source: stable/1.16/Clp/src/CbcOrClpParam.cpp @ 2228

Last change on this file since 2228 was 2228, checked in by forrest, 3 years ago

aesthetic change

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 174.4 KB
Line 
1/* $Id: CbcOrClpParam.cpp 2228 2016-08-17 08:32:35Z 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                              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#undef COIN_DBL_MAX
1512#define COIN_DBL_MAX 1.0e100
1513/*
1514  Subroutine to establish the cbc parameter array. See the description of
1515  class CbcOrClpParam for details. Pulled from C..Main() for clarity.
1516*/
1517void
1518establishParams (int &numberParameters, CbcOrClpParam *const parameters)
1519{
1520     numberParameters = 0;
1521     parameters[numberParameters++] =
1522          CbcOrClpParam("?", "For help", CBC_PARAM_GENERALQUERY, 7, 0);
1523     parameters[numberParameters++] =
1524          CbcOrClpParam("???", "For help", CBC_PARAM_FULLGENERALQUERY, 7, 0);
1525     parameters[numberParameters++] =
1526          CbcOrClpParam("-", "From stdin",
1527                        CLP_PARAM_ACTION_STDIN, 3, 0);
1528#ifdef ABC_INHERIT
1529      parameters[numberParameters++] =
1530          CbcOrClpParam("abc", "Whether to visit Aboca",
1531                        "off", CLP_PARAM_STR_ABCWANTED, 7, 0);
1532     parameters[numberParameters-1].append("one");
1533     parameters[numberParameters-1].append("two");
1534     parameters[numberParameters-1].append("three");
1535     parameters[numberParameters-1].append("four");
1536     parameters[numberParameters-1].append("five");
1537     parameters[numberParameters-1].append("six");
1538     parameters[numberParameters-1].append("seven");
1539     parameters[numberParameters-1].append("eight");
1540     parameters[numberParameters-1].append("on");
1541     parameters[numberParameters-1].append("decide");
1542     parameters[numberParameters-1].setFakeKeyWord(10);
1543     parameters[numberParameters-1].setLonghelp
1544     (
1545          "Decide whether to use A Basic Optimization Code (Accelerated?) \
1546and whether to try going parallel!"
1547     );
1548#endif
1549     parameters[numberParameters++] =
1550          CbcOrClpParam("allC!ommands", "Whether to print less used commands",
1551                        "no", CLP_PARAM_STR_ALLCOMMANDS);
1552     parameters[numberParameters-1].append("more");
1553     parameters[numberParameters-1].append("all");
1554     parameters[numberParameters-1].setLonghelp
1555     (
1556          "For the sake of your sanity, only the more useful and simple commands \
1557are printed out on ?."
1558     );
1559#ifdef COIN_HAS_CBC
1560     parameters[numberParameters++] =
1561          CbcOrClpParam("allow!ableGap", "Stop when gap between best possible and \
1562best less than this",
1563                        0.0, 1.0e20, CBC_PARAM_DBL_ALLOWABLEGAP);
1564     parameters[numberParameters-1].setDoubleValue(0.0);
1565     parameters[numberParameters-1].setLonghelp
1566     (
1567          "If the gap between best solution and best possible solution is less than this \
1568then the search will be terminated.  Also see ratioGap."
1569     );
1570#endif
1571#ifdef COIN_HAS_CLP
1572     parameters[numberParameters++] =
1573          CbcOrClpParam("allS!lack", "Set basis back to all slack and reset solution",
1574                        CLP_PARAM_ACTION_ALLSLACK, 3);
1575     parameters[numberParameters-1].setLonghelp
1576     (
1577          "Mainly useful for tuning purposes.  Normally the first dual or primal will be using an all slack \
1578basis anyway."
1579     );
1580#endif
1581#ifdef COIN_HAS_CBC
1582     parameters[numberParameters++] =
1583          CbcOrClpParam("artif!icialCost", "Costs >= this treated as artificials in feasibility pump",
1584                        0.0, COIN_DBL_MAX, CBC_PARAM_DBL_ARTIFICIALCOST, 1);
1585     parameters[numberParameters-1].setDoubleValue(0.0);
1586     parameters[numberParameters-1].setLonghelp
1587     (
1588          "0.0 off - otherwise variables with costs >= this are treated as artificials and fixed to lower bound in feasibility pump"
1589     );
1590#endif
1591#ifdef COIN_HAS_CLP
1592     parameters[numberParameters++] =
1593          CbcOrClpParam("auto!Scale", "Whether to scale objective, rhs and bounds of problem if they look odd",
1594                        "off", CLP_PARAM_STR_AUTOSCALE, 7, 0);
1595     parameters[numberParameters-1].append("on");
1596     parameters[numberParameters-1].setLonghelp
1597     (
1598          "If you think you may get odd objective values or large equality rows etc then\
1599 it may be worth setting this true.  It is still experimental and you may prefer\
1600 to use objective!Scale and rhs!Scale."
1601     );
1602     parameters[numberParameters++] =
1603          CbcOrClpParam("barr!ier", "Solve using primal dual predictor corrector algorithm",
1604                        CLP_PARAM_ACTION_BARRIER);
1605     parameters[numberParameters-1].setLonghelp
1606     (
1607          "This command solves the current model using the  primal dual predictor \
1608corrector algorithm.  You may want to link in an alternative \
1609ordering and factorization.  It will also solve models \
1610with quadratic objectives."
1611
1612     );
1613     parameters[numberParameters++] =
1614          CbcOrClpParam("basisI!n", "Import basis from bas file",
1615                        CLP_PARAM_ACTION_BASISIN, 3);
1616     parameters[numberParameters-1].setLonghelp
1617     (
1618          "This will read an MPS format basis file from the given file name.  It will use the default\
1619 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1620 is initialized to '', i.e. it must be set.  If you have libz then it can read compressed\
1621 files 'xxxxxxxx.gz' or xxxxxxxx.bz2."
1622     );
1623     parameters[numberParameters++] =
1624          CbcOrClpParam("basisO!ut", "Export basis as bas file",
1625                        CLP_PARAM_ACTION_BASISOUT);
1626     parameters[numberParameters-1].setLonghelp
1627     (
1628          "This will write an MPS format basis file to the given file name.  It will use the default\
1629 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1630 is initialized to 'default.bas'."
1631     );
1632     parameters[numberParameters++] =
1633          CbcOrClpParam("biasLU", "Whether factorization biased towards U",
1634                        "UU", CLP_PARAM_STR_BIASLU, 2, 0);
1635     parameters[numberParameters-1].append("UX");
1636     parameters[numberParameters-1].append("LX");
1637     parameters[numberParameters-1].append("LL");
1638     parameters[numberParameters-1].setCurrentOption("LX");
1639#endif
1640#ifdef COIN_HAS_CBC
1641     parameters[numberParameters++] =
1642          CbcOrClpParam("branch!AndCut", "Do Branch and Cut",
1643                        CBC_PARAM_ACTION_BAB);
1644     parameters[numberParameters-1].setLonghelp
1645     (
1646          "This does branch and cut.  There are many parameters which can affect the performance.  \
1647First just try with default settings and look carefully at the log file.  Did cuts help?  Did they take too long?  \
1648Look at output to see which cuts were effective and then do some tuning.  You will see that the \
1649options for cuts are off, on, root and ifmove, forceon.  Off is \
1650obvious, on means that this cut generator will be tried in the branch and cut tree (you can fine tune using \
1651'depth').  Root means just at the root node while 'ifmove' means that cuts will be used in the tree if they \
1652look as if they are doing some good and moving the objective value.  Forceon is same as on but forces code to use \
1653cut generator at every node.  For probing forceonbut just does fixing probing in tree - not strengthening etc.  \
1654If pre-processing reduced the size of the \
1655problem or strengthened many coefficients then it is probably wise to leave it on.  Switch off heuristics \
1656which did not provide solutions.  The other major area to look at is the search.  Hopefully good solutions \
1657were obtained fairly early in the search so the important point is to select the best variable to branch on.  \
1658See whether strong branching did a good job - or did it just take a lot of iterations.  Adjust the strongBranching \
1659and trustPseudoCosts parameters.  If cuts did a good job, then you may wish to \
1660have more rounds of cuts - see passC!uts and passT!ree."
1661     );
1662#endif
1663     parameters[numberParameters++] =
1664          CbcOrClpParam("bscale", "Whether to scale in barrier (and ordering speed)",
1665                        "off", CLP_PARAM_STR_BARRIERSCALE, 7, 0);
1666     parameters[numberParameters-1].append("on");
1667     parameters[numberParameters-1].append("off1");
1668     parameters[numberParameters-1].append("on1");
1669     parameters[numberParameters-1].append("off2");
1670     parameters[numberParameters-1].append("on2");
1671#if FLUSH_PRINT_BUFFER > 2
1672     parameters[numberParameters++] =
1673          CbcOrClpParam("buff!eredMode", "Whether to flush print buffer",
1674                        "on", CLP_PARAM_STR_BUFFER_MODE);
1675     parameters[numberParameters-1].append("off");
1676     parameters[numberParameters-1].setLonghelp
1677     (
1678          "Default is on, off switches on unbuffered output"
1679     );
1680     parameters[numberParameters-1].setIntValue(0);
1681#endif
1682     parameters[numberParameters++] =
1683          CbcOrClpParam("chol!esky", "Which cholesky algorithm",
1684                        "native", CLP_PARAM_STR_CHOLESKY, 7);
1685     parameters[numberParameters-1].append("dense");
1686     //#ifdef FOREIGN_BARRIER
1687#ifdef COIN_HAS_WSMP
1688     parameters[numberParameters-1].append("fudge!Long");
1689     parameters[numberParameters-1].append("wssmp");
1690#else
1691     parameters[numberParameters-1].append("fudge!Long_dummy");
1692     parameters[numberParameters-1].append("wssmp_dummy");
1693#endif
1694#if defined(COIN_HAS_AMD) || defined(COIN_HAS_CHOLMOD) || defined(COIN_HAS_GLPK)
1695     parameters[numberParameters-1].append("Uni!versityOfFlorida");
1696#else
1697     parameters[numberParameters-1].append("Uni!versityOfFlorida_dummy");
1698#endif
1699#ifdef TAUCS_BARRIER
1700     parameters[numberParameters-1].append("Taucs");
1701#else
1702     parameters[numberParameters-1].append("Taucs_dummy");
1703#endif
1704#ifdef COIN_HAS_MUMPS
1705     parameters[numberParameters-1].append("Mumps");
1706#else
1707     parameters[numberParameters-1].append("Mumps_dummy");
1708#endif
1709     parameters[numberParameters-1].setLonghelp
1710     (
1711          "For a barrier code to be effective it needs a good Cholesky ordering and factorization.  \
1712The native ordering and factorization is not state of the art, although acceptable.  \
1713You may want to link in one from another source.  See Makefile.locations for some \
1714possibilities."
1715     );
1716     //#endif
1717#ifdef COIN_HAS_CBC
1718     parameters[numberParameters++] =
1719          CbcOrClpParam("clique!Cuts", "Whether to use Clique cuts",
1720                        "off", CBC_PARAM_STR_CLIQUECUTS);
1721     parameters[numberParameters-1].append("on");
1722     parameters[numberParameters-1].append("root");
1723     parameters[numberParameters-1].append("ifmove");
1724     parameters[numberParameters-1].append("forceOn");
1725     parameters[numberParameters-1].append("onglobal");
1726     parameters[numberParameters-1].setLonghelp
1727     (
1728          "This switches on clique cuts (either at root or in entire tree) \
1729See branchAndCut for information on options."
1730     );
1731     parameters[numberParameters++] =
1732          CbcOrClpParam("combine!Solutions", "Whether to use combine solution heuristic",
1733                        "off", CBC_PARAM_STR_COMBINE);
1734     parameters[numberParameters-1].append("on");
1735     parameters[numberParameters-1].append("both");
1736     parameters[numberParameters-1].append("before");
1737     parameters[numberParameters-1].append("onquick");
1738     parameters[numberParameters-1].append("bothquick");
1739     parameters[numberParameters-1].append("beforequick");
1740     parameters[numberParameters-1].setLonghelp
1741     (
1742          "This switches on a heuristic which does branch and cut on the problem given by just \
1743using variables which have appeared in one or more solutions. \
1744It obviously only tries after two or more solutions. \
1745See Rounding for meaning of on,both,before"
1746     );
1747     parameters[numberParameters++] =
1748          CbcOrClpParam("combine2!Solutions", "Whether to use crossover solution heuristic",
1749                        "off", CBC_PARAM_STR_CROSSOVER2);
1750     parameters[numberParameters-1].append("on");
1751     parameters[numberParameters-1].append("both");
1752     parameters[numberParameters-1].append("before");
1753     parameters[numberParameters-1].setLonghelp
1754     (
1755          "This switches on a heuristic which does branch and cut on the problem given by \
1756fixing variables which have same value in two or more solutions. \
1757It obviously only tries after two or more solutions. \
1758See Rounding for meaning of on,both,before"
1759     );
1760     parameters[numberParameters++] =
1761          CbcOrClpParam("constraint!fromCutoff", "Whether to use cutoff as constraint",
1762                        "off", CBC_PARAM_STR_CUTOFF_CONSTRAINT);
1763     parameters[numberParameters-1].append("on");
1764     parameters[numberParameters-1].append("variable");
1765     parameters[numberParameters-1].append("forcevariable");
1766     parameters[numberParameters-1].append("conflict");
1767     parameters[numberParameters-1].setLonghelp
1768     (
1769          "This adds the objective as a constraint with best solution as RHS"
1770     );
1771     parameters[numberParameters++] =
1772          CbcOrClpParam("cost!Strategy", "How to use costs as priorities",
1773                        "off", CBC_PARAM_STR_COSTSTRATEGY);
1774     parameters[numberParameters-1].append("pri!orities");
1775     parameters[numberParameters-1].append("column!Order?");
1776     parameters[numberParameters-1].append("01f!irst?");
1777     parameters[numberParameters-1].append("01l!ast?");
1778     parameters[numberParameters-1].append("length!?");
1779     parameters[numberParameters-1].append("singletons");
1780     parameters[numberParameters-1].append("nonzero");
1781     parameters[numberParameters-1].append("general!Force?");
1782     parameters[numberParameters-1].setLonghelp
1783     (
1784          "This orders the variables in order of their absolute costs - with largest cost ones being branched on \
1785first.  This primitive strategy can be surprsingly effective.  The column order\
1786 option is obviously not on costs but easy to code here."
1787     );
1788     parameters[numberParameters++] =
1789          CbcOrClpParam("cplex!Use", "Whether to use Cplex!",
1790                        "off", CBC_PARAM_STR_CPX);
1791     parameters[numberParameters-1].append("on");
1792     parameters[numberParameters-1].setLonghelp
1793     (
1794          " If the user has Cplex, but wants to use some of Cbc's heuristics \
1795then you can!  If this is on, then Cbc will get to the root node and then \
1796hand over to Cplex.  If heuristics find a solution this can be significantly \
1797quicker.  You will probably want to switch off Cbc's cuts as Cplex thinks \
1798they are genuine constraints.  It is also probable that you want to switch \
1799off preprocessing, although for difficult problems it is worth trying \
1800both."
1801     );
1802#endif
1803     parameters[numberParameters++] =
1804          CbcOrClpParam("cpp!Generate", "Generates C++ code",
1805                        -1, 50000, CLP_PARAM_INT_CPP, 1);
1806     parameters[numberParameters-1].setLonghelp
1807     (
1808          "Once you like what the stand-alone solver does then this allows \
1809you to generate user_driver.cpp which approximates the code.  \
18100 gives simplest driver, 1 generates saves and restores, 2 \
1811generates saves and restores even for variables at default value. \
18124 bit in cbc generates size dependent code rather than computed values.  \
1813This is now deprecated as you can call stand-alone solver - see \
1814Cbc/examples/driver4.cpp."
1815     );
1816#ifdef COIN_HAS_CLP
1817     parameters[numberParameters++] =
1818          CbcOrClpParam("crash", "Whether to create basis for problem",
1819                        "off", CLP_PARAM_STR_CRASH);
1820     parameters[numberParameters-1].append("on");
1821     parameters[numberParameters-1].append("so!low_halim");
1822     parameters[numberParameters-1].append("lots");
1823#ifdef CLP_INHERIT_MODE
1824     parameters[numberParameters-1].append("dual");
1825     parameters[numberParameters-1].append("dw");
1826     parameters[numberParameters-1].append("idiot");
1827#else
1828     parameters[numberParameters-1].append("idiot1");
1829     parameters[numberParameters-1].append("idiot2");
1830     parameters[numberParameters-1].append("idiot3");
1831     parameters[numberParameters-1].append("idiot4");
1832     parameters[numberParameters-1].append("idiot5");
1833     parameters[numberParameters-1].append("idiot6");
1834     parameters[numberParameters-1].append("idiot7");
1835#endif
1836     parameters[numberParameters-1].setLonghelp
1837     (
1838          "If crash is set on and there is an all slack basis then Clp will flip or put structural\
1839 variables into basis with the aim of getting dual feasible.  On the whole dual seems to be\
1840 better without it and there are alternative types of 'crash' for primal e.g. 'idiot' or 'sprint'. \
1841I have also added a variant due to Solow and Halim which is as on but just flip.");
1842     parameters[numberParameters++] =
1843          CbcOrClpParam("cross!over", "Whether to get a basic solution after barrier",
1844                        "on", CLP_PARAM_STR_CROSSOVER);
1845     parameters[numberParameters-1].append("off");
1846     parameters[numberParameters-1].append("maybe");
1847     parameters[numberParameters-1].append("presolve");
1848     parameters[numberParameters-1].setLonghelp
1849     (
1850          "Interior point algorithms do not obtain a basic solution (and \
1851the feasibility criterion is a bit suspect (JJF)).  This option will crossover \
1852to a basic solution suitable for ranging or branch and cut.  With the current state \
1853of quadratic it may be a good idea to switch off crossover for quadratic (and maybe \
1854presolve as well) - the option maybe does this."
1855     );
1856#endif
1857#ifdef COIN_HAS_CBC
1858     parameters[numberParameters++] =
1859          CbcOrClpParam("csv!Statistics", "Create one line of statistics",
1860                        CLP_PARAM_ACTION_CSVSTATISTICS, 2, 1);
1861     parameters[numberParameters-1].setLonghelp
1862     (
1863          "This appends statistics to given file name.  It will use the default\
1864 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1865 is initialized to '', i.e. it must be set.  Adds header if file empty or does not exist."
1866     );
1867     parameters[numberParameters++] =
1868          CbcOrClpParam("cutD!epth", "Depth in tree at which to do cuts",
1869                        -1, 999999, CBC_PARAM_INT_CUTDEPTH);
1870     parameters[numberParameters-1].setLonghelp
1871     (
1872          "Cut generators may be - off, on only at root, on if they look possible \
1873and on.  If they are done every node then that is that, but it may be worth doing them \
1874every so often.  The original method was every so many nodes but it is more logical \
1875to do it whenever depth in tree is a multiple of K.  This option does that and defaults \
1876to -1 (off -> code decides)."
1877     );
1878     parameters[numberParameters-1].setIntValue(-1);
1879     parameters[numberParameters++] =
1880          CbcOrClpParam("cutL!ength", "Length of a cut",
1881                        -1, COIN_INT_MAX, CBC_PARAM_INT_CUTLENGTH);
1882     parameters[numberParameters-1].setLonghelp
1883     (
1884          "At present this only applies to Gomory cuts. -1 (default) leaves as is. \
1885Any value >0 says that all cuts <= this length can be generated both at \
1886root node and in tree. 0 says to use some dynamic lengths.  If value >=10,000,000 \
1887then the length in tree is value%10000000 - so 10000100 means unlimited length \
1888at root and 100 in tree."
1889     );
1890     parameters[numberParameters-1].setIntValue(-1);
1891     parameters[numberParameters++] =
1892          CbcOrClpParam("cuto!ff", "All solutions must be better than this",
1893                        -1.0e60, 1.0e60, CBC_PARAM_DBL_CUTOFF);
1894     parameters[numberParameters-1].setDoubleValue(1.0e50);
1895     parameters[numberParameters-1].setLonghelp
1896     (
1897          "All solutions must be better than this value (in a minimization sense).  \
1898This is also set by code whenever it obtains a solution and is set to value of \
1899objective for solution minus cutoff increment."
1900     );
1901     parameters[numberParameters++] =
1902          CbcOrClpParam("cuts!OnOff", "Switches all cuts on or off",
1903                        "off", CBC_PARAM_STR_CUTSSTRATEGY);
1904     parameters[numberParameters-1].append("on");
1905     parameters[numberParameters-1].append("root");
1906     parameters[numberParameters-1].append("ifmove");
1907     parameters[numberParameters-1].append("forceOn");
1908     parameters[numberParameters-1].setLonghelp
1909     (
1910          "This can be used to switch on or off all cuts (apart from Reduce and Split).  Then you can do \
1911individual ones off or on \
1912See branchAndCut for information on options."
1913     );
1914     parameters[numberParameters++] =
1915          CbcOrClpParam("debug!In", "read valid solution from file",
1916                        CLP_PARAM_ACTION_DEBUG, 7, 1);
1917     parameters[numberParameters-1].setLonghelp
1918     (
1919          "This will read a solution file from the given file name.  It will use the default\
1920 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1921 is initialized to '', i.e. it must be set.\n\n\
1922If set to create it will create a file called debug.file  after search.\n\n\
1923The idea is that if you suspect a bad cut generator \
1924you can do a good run with debug set to 'create' and then switch on the cuts you suspect and \
1925re-run with debug set to 'debug.file'  The create case has same effect as saveSolution."
1926     );
1927#endif
1928#ifdef COIN_HAS_CLP
1929     parameters[numberParameters++] =
1930          CbcOrClpParam("decomp!ose", "Whether to try decomposition",
1931                        -COIN_INT_MAX, COIN_INT_MAX, CLP_PARAM_INT_DECOMPOSE_BLOCKS, 1);
1932     parameters[numberParameters-1].setLonghelp
1933     (
1934          "0 - off, 1 choose blocks >1 use as blocks \
1935Dantzig Wolfe if primal, Benders if dual \
1936- uses sprint pass for number of passes"
1937     );
1938     parameters[numberParameters-1].setIntValue(0);
1939#if CLP_MULTIPLE_FACTORIZATIONS >0
1940     parameters[numberParameters++] =
1941          CbcOrClpParam("dense!Threshold", "Whether to use dense factorization",
1942                        -1, 10000, CBC_PARAM_INT_DENSE, 1);
1943     parameters[numberParameters-1].setLonghelp
1944     (
1945          "If processed problem <= this use dense factorization"
1946     );
1947     parameters[numberParameters-1].setIntValue(-1);
1948#endif
1949#endif
1950#ifdef COIN_HAS_CBC
1951     parameters[numberParameters++] =
1952          CbcOrClpParam("depth!MiniBab", "Depth at which to try mini BAB",
1953                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_DEPTHMINIBAB);
1954     parameters[numberParameters-1].setIntValue(-1);
1955     parameters[numberParameters-1].setLonghelp
1956     (
1957          "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 \
1958means 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."
1959     );
1960     parameters[numberParameters++] =
1961          CbcOrClpParam("dextra3", "Extra double parameter 3",
1962                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA3, 0);
1963     parameters[numberParameters-1].setDoubleValue(0.0);
1964     parameters[numberParameters++] =
1965          CbcOrClpParam("dextra4", "Extra double parameter 4",
1966                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA4, 0);
1967     parameters[numberParameters-1].setDoubleValue(0.0);
1968     parameters[numberParameters++] =
1969          CbcOrClpParam("dextra5", "Extra double parameter 5",
1970                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA5, 0);
1971     parameters[numberParameters-1].setDoubleValue(0.0);
1972     parameters[numberParameters++] =
1973          CbcOrClpParam("Dins", "Whether to try Distance Induced Neighborhood Search",
1974                        "off", CBC_PARAM_STR_DINS);
1975     parameters[numberParameters-1].append("on");
1976     parameters[numberParameters-1].append("both");
1977     parameters[numberParameters-1].append("before");
1978     parameters[numberParameters-1].append("often");
1979     parameters[numberParameters-1].setLonghelp
1980     (
1981          "This switches on Distance induced neighborhood Search. \
1982See Rounding for meaning of on,both,before"
1983     );
1984#endif
1985     parameters[numberParameters++] =
1986          CbcOrClpParam("direction", "Minimize or Maximize",
1987                        "min!imize", CLP_PARAM_STR_DIRECTION);
1988     parameters[numberParameters-1].append("max!imize");
1989     parameters[numberParameters-1].append("zero");
1990     parameters[numberParameters-1].setLonghelp
1991     (
1992          "The default is minimize - use 'direction maximize' for maximization.\n\
1993You can also use the parameters 'maximize' or 'minimize'."
1994     );
1995     parameters[numberParameters++] =
1996          CbcOrClpParam("directory", "Set Default directory for import etc.",
1997                        CLP_PARAM_ACTION_DIRECTORY);
1998     parameters[numberParameters-1].setLonghelp
1999     (
2000          "This sets the directory which import, export, saveModel, restoreModel etc will use.\
2001  It is initialized to './'"
2002     );
2003     parameters[numberParameters++] =
2004          CbcOrClpParam("dirSample", "Set directory where the COIN-OR sample problems are.",
2005                        CLP_PARAM_ACTION_DIRSAMPLE, 7, 1);
2006     parameters[numberParameters-1].setLonghelp
2007     (
2008          "This sets the directory where the COIN-OR sample problems reside. It is\
2009 used only when -unitTest is passed to clp. clp will pick up the test problems\
2010 from this directory.\
2011 It is initialized to '../../Data/Sample'"
2012     );
2013     parameters[numberParameters++] =
2014          CbcOrClpParam("dirNetlib", "Set directory where the netlib problems are.",
2015                        CLP_PARAM_ACTION_DIRNETLIB, 7, 1);
2016     parameters[numberParameters-1].setLonghelp
2017     (
2018          "This sets the directory where the netlib problems reside. One can get\
2019 the netlib problems from COIN-OR or from the main netlib site. This\
2020 parameter is used only when -netlib is passed to clp. clp will pick up the\
2021 netlib problems from this directory. If clp is built without zlib support\
2022 then the problems must be uncompressed.\
2023 It is initialized to '../../Data/Netlib'"
2024     );
2025     parameters[numberParameters++] =
2026          CbcOrClpParam("dirMiplib", "Set directory where the miplib 2003 problems are.",
2027                        CBC_PARAM_ACTION_DIRMIPLIB, 7, 1);
2028     parameters[numberParameters-1].setLonghelp
2029     (
2030          "This sets the directory where the miplib 2003 problems reside. One can\
2031 get the miplib problems from COIN-OR or from the main miplib site. This\
2032 parameter is used only when -miplib is passed to cbc. cbc will pick up the\
2033 miplib problems from this directory. If cbc is built without zlib support\
2034 then the problems must be uncompressed.\
2035 It is initialized to '../../Data/miplib3'"
2036     );
2037#ifdef COIN_HAS_CBC
2038     parameters[numberParameters++] =
2039          CbcOrClpParam("diveO!pt", "Diving options",
2040                        -1, 200000, CBC_PARAM_INT_DIVEOPT, 1);
2041     parameters[numberParameters-1].setLonghelp
2042     (
2043          "If >2 && <20 then modify diving options - \
2044         \n\t3 only at root and if no solution,  \
2045         \n\t4 only at root and if this heuristic has not got solution, \
2046         \n\t5 decay only if no solution, \
2047         \n\t6 if depth <3 or decay, \
2048         \n\t7 run up to 2 times if solution found 4 otherwise, \
2049         \n\t>10 All only at root (DivingC normal as value-10), \
2050         \n\t>20 All with value-20)."
2051     );
2052     parameters[numberParameters-1].setIntValue(-1);
2053     parameters[numberParameters++] =
2054          CbcOrClpParam("diveS!olves", "Diving solve option",
2055                        -1, 200000, CBC_PARAM_INT_DIVEOPTSOLVES, 1);
2056     parameters[numberParameters-1].setLonghelp
2057     (
2058          "If >0 then do up to this many solves.  Last digit is ignored \
2059and used for extra options - \
2060         \n\t1-3 allow fixing of satisfied integers (but not at bound) \
2061         \n\t1 switch off above for that dive if goes infeasible \
2062         \n\t2 switch off above permanently if goes infeasible"
2063     );
2064     parameters[numberParameters-1].setIntValue(100);
2065     parameters[numberParameters++] =
2066          CbcOrClpParam("DivingS!ome", "Whether to try Diving heuristics",
2067                        "off", CBC_PARAM_STR_DIVINGS);
2068     parameters[numberParameters-1].append("on");
2069     parameters[numberParameters-1].append("both");
2070     parameters[numberParameters-1].append("before");
2071     parameters[numberParameters-1].setLonghelp
2072     (
2073          "This switches on a random diving heuristic at various times. \
2074C - Coefficient, F - Fractional, G - Guided, L - LineSearch, P - PseudoCost, V - VectorLength. \
2075You may prefer to use individual on/off \
2076See Rounding for meaning of on,both,before"
2077     );
2078     parameters[numberParameters++] =
2079          CbcOrClpParam("DivingC!oefficient", "Whether to try DiveCoefficient",
2080                        "off", CBC_PARAM_STR_DIVINGC);
2081     parameters[numberParameters-1].append("on");
2082     parameters[numberParameters-1].append("both");
2083     parameters[numberParameters-1].append("before");
2084     parameters[numberParameters++] =
2085          CbcOrClpParam("DivingF!ractional", "Whether to try DiveFractional",
2086                        "off", CBC_PARAM_STR_DIVINGF);
2087     parameters[numberParameters-1].append("on");
2088     parameters[numberParameters-1].append("both");
2089     parameters[numberParameters-1].append("before");
2090     parameters[numberParameters++] =
2091          CbcOrClpParam("DivingG!uided", "Whether to try DiveGuided",
2092                        "off", CBC_PARAM_STR_DIVINGG);
2093     parameters[numberParameters-1].append("on");
2094     parameters[numberParameters-1].append("both");
2095     parameters[numberParameters-1].append("before");
2096     parameters[numberParameters++] =
2097          CbcOrClpParam("DivingL!ineSearch", "Whether to try DiveLineSearch",
2098                        "off", CBC_PARAM_STR_DIVINGL);
2099     parameters[numberParameters-1].append("on");
2100     parameters[numberParameters-1].append("both");
2101     parameters[numberParameters-1].append("before");
2102     parameters[numberParameters++] =
2103          CbcOrClpParam("DivingP!seudoCost", "Whether to try DivePseudoCost",
2104                        "off", CBC_PARAM_STR_DIVINGP);
2105     parameters[numberParameters-1].append("on");
2106     parameters[numberParameters-1].append("both");
2107     parameters[numberParameters-1].append("before");
2108     parameters[numberParameters++] =
2109          CbcOrClpParam("DivingV!ectorLength", "Whether to try DiveVectorLength",
2110                        "off", CBC_PARAM_STR_DIVINGV);
2111     parameters[numberParameters-1].append("on");
2112     parameters[numberParameters-1].append("both");
2113     parameters[numberParameters-1].append("before");
2114     parameters[numberParameters++] =
2115          CbcOrClpParam("doH!euristic", "Do heuristics before any preprocessing",
2116                        CBC_PARAM_ACTION_DOHEURISTIC, 3);
2117     parameters[numberParameters-1].setLonghelp
2118     (
2119          "Normally heuristics are done in branch and bound.  It may be useful to do them outside. \
2120Only those heuristics with 'both' or 'before' set will run.  \
2121Doing this may also set cutoff, which can help with preprocessing."
2122     );
2123#endif
2124#ifdef COIN_HAS_CLP
2125     parameters[numberParameters++] =
2126          CbcOrClpParam("dualB!ound", "Initially algorithm acts as if no \
2127gap between bounds exceeds this value",
2128                        1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALBOUND);
2129     parameters[numberParameters-1].setLonghelp
2130     (
2131          "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
2132 algorithm where you first get feasible then optimal.  If a problem has both upper and\
2133 lower bounds then it is trivial to get dual feasible by setting non basic variables\
2134 to correct bound.  If the gap between the upper and lower bounds of a variable is more\
2135 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
2136 dual feasible.  This has the same effect as a composite objective function in the\
2137 primal algorithm.  Too high a value may mean more iterations, while too low a bound means\
2138 the code may go all the way and then have to increase the bounds.  OSL had a heuristic to\
2139 adjust bounds, maybe we need that here."
2140     );
2141     parameters[numberParameters++] =
2142          CbcOrClpParam("dualize", "Solves dual reformulation",
2143                        0, 4, CLP_PARAM_INT_DUALIZE, 1);
2144     parameters[numberParameters-1].setLonghelp
2145     (
2146          "Don't even think about it."
2147     );
2148     parameters[numberParameters++] =
2149          CbcOrClpParam("dualP!ivot", "Dual pivot choice algorithm",
2150                        "auto!matic", CLP_PARAM_STR_DUALPIVOT, 7, 1);
2151     parameters[numberParameters-1].append("dant!zig");
2152     parameters[numberParameters-1].append("partial");
2153     parameters[numberParameters-1].append("steep!est");
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."
2162     );
2163     parameters[numberParameters++] =
2164          CbcOrClpParam("dualS!implex", "Do dual simplex algorithm",
2165                        CLP_PARAM_ACTION_DUALSIMPLEX);
2166     parameters[numberParameters-1].setLonghelp
2167     (
2168          "This command solves the continuous relaxation of the current model using the dual steepest edge algorithm.\
2169The time and iterations may be affected by settings such as presolve, scaling, crash\
2170 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
2171     );
2172#endif
2173     parameters[numberParameters++] =
2174          CbcOrClpParam("dualT!olerance", "For an optimal solution \
2175no dual infeasibility may exceed this value",
2176                        1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALTOLERANCE);
2177     parameters[numberParameters-1].setLonghelp
2178     (
2179          "Normally the default tolerance is fine, but you may want to increase it a\
2180 bit if a dual run seems to be having a hard time.  One method which can be faster is \
2181to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \
2182correct tolerance (remembering to switch off presolve for this final short clean up phase)."
2183     );
2184#ifdef COIN_HAS_CBC
2185     parameters[numberParameters++] =
2186          CbcOrClpParam("dw!Heuristic", "Whether to try DW heuristic",
2187                        "off", CBC_PARAM_STR_DW);
2188     parameters[numberParameters-1].append("on");
2189     parameters[numberParameters-1].append("both");
2190     parameters[numberParameters-1].append("before");
2191     parameters[numberParameters-1].setLonghelp
2192     (
2193      "See Rounding for meaning of on,both,before"
2194     );
2195#endif
2196#ifdef COIN_HAS_CLP
2197     parameters[numberParameters++] =
2198          CbcOrClpParam("either!Simplex", "Do dual or primal simplex algorithm",
2199                        CLP_PARAM_ACTION_EITHERSIMPLEX);
2200     parameters[numberParameters-1].setLonghelp
2201     (
2202          "This command solves the continuous relaxation of the current model using the dual or primal algorithm,\
2203 based on a dubious analysis of model."
2204     );
2205#endif
2206     parameters[numberParameters++] =
2207          CbcOrClpParam("end", "Stops clp execution",
2208                        CLP_PARAM_ACTION_EXIT);
2209     parameters[numberParameters-1].setLonghelp
2210     (
2211          "This stops execution ; end, exit, quit and stop are synonyms"
2212     );
2213     parameters[numberParameters++] =
2214          CbcOrClpParam("environ!ment", "Read commands from environment",
2215                        CLP_PARAM_ACTION_ENVIRONMENT, 7, 0);
2216     parameters[numberParameters-1].setLonghelp
2217     (
2218          "This starts reading from environment variable CBC_CLP_ENVIRONMENT."
2219     );
2220     parameters[numberParameters++] =
2221          CbcOrClpParam("error!sAllowed", "Whether to allow import errors",
2222                        "off", CLP_PARAM_STR_ERRORSALLOWED, 3);
2223     parameters[numberParameters-1].append("on");
2224     parameters[numberParameters-1].setLonghelp
2225     (
2226          "The default is not to use any model which had errors when reading the mps file.\
2227  Setting this to 'on' will allow all errors from which the code can recover\
2228 simply by ignoring the error.  There are some errors from which the code can not recover \
2229e.g. no ENDATA.  This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps."
2230     );
2231     parameters[numberParameters++] =
2232          CbcOrClpParam("exit", "Stops clp execution",
2233                        CLP_PARAM_ACTION_EXIT);
2234     parameters[numberParameters-1].setLonghelp
2235     (
2236          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2237     );
2238#ifdef COIN_HAS_CBC
2239     parameters[numberParameters++] =
2240          CbcOrClpParam("exper!iment", "Whether to use testing features",
2241                        -1, 200, CBC_PARAM_INT_EXPERIMENT, 0);
2242     parameters[numberParameters-1].setLonghelp
2243     (
2244          "Defines how adventurous you want to be in using new ideas. \
22450 then no new ideas, 1 fairly sensible, 2 a bit dubious, 3 you are on your own!"
2246     );
2247     parameters[numberParameters-1].setIntValue(0);
2248     parameters[numberParameters++] =
2249          CbcOrClpParam("expensive!Strong", "Whether to do even more strong branching",
2250                        0, COIN_INT_MAX, CBC_PARAM_INT_STRONG_STRATEGY, 0);
2251     parameters[numberParameters-1].setLonghelp
2252     (
2253      "Strategy for extra strong branching \n\
2254\n\t0 - normal\n\
2255\n\twhen to do all fractional\n\
2256\n\t1 - root node\n\
2257\n\t2 - depth less than modifier\n\
2258\n\t4 - if objective == best possible\n\
2259\n\t6 - as 2+4\n\
2260\n\twhen to do all including satisfied\n\
2261\n\t10 - root node etc.\n\
2262\n\tIf >=100 then do when depth <= strategy/100 (otherwise 5)"
2263     );
2264     parameters[numberParameters-1].setIntValue(0);
2265#endif
2266     parameters[numberParameters++] =
2267          CbcOrClpParam("export", "Export model as mps file",
2268                        CLP_PARAM_ACTION_EXPORT);
2269     parameters[numberParameters-1].setLonghelp
2270     (
2271          "This will write an MPS format file to the given file name.  It will use the default\
2272 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2273 is initialized to 'default.mps'.  \
2274It 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."
2275     );
2276#ifdef COIN_HAS_CBC
2277     parameters[numberParameters++] =
2278          CbcOrClpParam("extra1", "Extra integer parameter 1",
2279                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA1, 0);
2280     parameters[numberParameters-1].setIntValue(-1);
2281     parameters[numberParameters++] =
2282          CbcOrClpParam("extra2", "Extra integer parameter 2",
2283                        -100, COIN_INT_MAX, CBC_PARAM_INT_EXTRA2, 0);
2284     parameters[numberParameters-1].setIntValue(-1);
2285     parameters[numberParameters++] =
2286          CbcOrClpParam("extra3", "Extra integer parameter 3",
2287                        -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA3, 0);
2288     parameters[numberParameters-1].setIntValue(-1);
2289     parameters[numberParameters++] =
2290          CbcOrClpParam("extra4", "Extra integer parameter 4",
2291                        -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA4, 0);
2292     parameters[numberParameters-1].setIntValue(-1);
2293     parameters[numberParameters-1].setLonghelp
2294     (
2295          "This switches on yet more special options!! \
2296The bottom digit is a strategy when to used shadow price stuff e.g. 3 \
2297means use until a solution is found.  The next two digits say what sort \
2298of dual information to use.  After that it goes back to powers of 2 so -\n\
2299\n\t1000 - switches on experimental hotstart\n\
2300\n\t2,4,6000 - switches on experimental methods of stopping cuts\n\
2301\n\t8000 - increase minimum drop gradually\n\
2302\n\t16000 - switches on alternate gomory criterion"
2303     );
2304     parameters[numberParameters++] =
2305       CbcOrClpParam("extraV!ariables", "Allow creation of extra integer variables",
2306                     -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA_VARIABLES, 0);
2307     parameters[numberParameters-1].setIntValue(0);
2308     parameters[numberParameters-1].setLonghelp
2309     (
2310          "This switches on creation of extra integer variables \
2311to gather all variables with same cost."
2312     );
2313#endif
2314#ifdef COIN_HAS_CLP
2315     parameters[numberParameters++] =
2316          CbcOrClpParam("fact!orization", "Which factorization to use",
2317                        "normal", CLP_PARAM_STR_FACTORIZATION);
2318     parameters[numberParameters-1].append("dense");
2319     parameters[numberParameters-1].append("simple");
2320     parameters[numberParameters-1].append("osl");
2321     parameters[numberParameters-1].setLonghelp
2322     (
2323#ifndef ABC_INHERIT
2324          "The default is to use the normal CoinFactorization, but \
2325other choices are a dense one, osl's or one designed for small problems."
2326#else
2327          "Normally the default is to use the normal CoinFactorization, but \
2328other choices are a dense one, osl's or one designed for small problems. \
2329However if at Aboca then the default is CoinAbcFactorization and other choices are \
2330a dense one, one designed for small problems or if enabled a long factorization."
2331#endif
2332     );
2333     parameters[numberParameters++] =
2334          CbcOrClpParam("fakeB!ound", "All bounds <= this value - DEBUG",
2335                        1.0, 1.0e15, CLP_PARAM_ACTION_FAKEBOUND, 0);
2336#ifdef COIN_HAS_CBC
2337     parameters[numberParameters++] =
2338          CbcOrClpParam("feas!ibilityPump", "Whether to try Feasibility Pump",
2339                        "off", CBC_PARAM_STR_FPUMP);
2340     parameters[numberParameters-1].append("on");
2341     parameters[numberParameters-1].append("both");
2342     parameters[numberParameters-1].append("before");
2343     parameters[numberParameters-1].setLonghelp
2344     (
2345          "This switches on feasibility pump heuristic at root. This is due to Fischetti, Lodi and Glover \
2346and uses a sequence of Lps to try and get an integer feasible solution. \
2347Some fine tuning is available by passFeasibilityPump and also pumpTune. \
2348See Rounding for meaning of on,both,before"
2349     );
2350     parameters[numberParameters++] =
2351          CbcOrClpParam("fix!OnDj", "Try heuristic based on fixing variables with \
2352reduced costs greater than this",
2353                        -1.0e20, 1.0e20, CBC_PARAM_DBL_DJFIX, 1);
2354     parameters[numberParameters-1].setLonghelp
2355     (
2356          "If this is set integer variables with reduced costs greater than this will be fixed \
2357before branch and bound - use with extreme caution!"
2358     );
2359     parameters[numberParameters++] =
2360          CbcOrClpParam("flow!CoverCuts", "Whether to use Flow Cover cuts",
2361                        "off", CBC_PARAM_STR_FLOWCUTS);
2362     parameters[numberParameters-1].append("on");
2363     parameters[numberParameters-1].append("root");
2364     parameters[numberParameters-1].append("ifmove");
2365     parameters[numberParameters-1].append("forceOn");
2366     parameters[numberParameters-1].append("onglobal");
2367     parameters[numberParameters-1].setFakeKeyWord(3);
2368     parameters[numberParameters-1].setLonghelp
2369     (
2370          "This switches on flow cover cuts (either at root or in entire tree) \
2371See branchAndCut for information on options. \
2372Can also enter testing values by plusnn (==ifmove)"
2373     );
2374     parameters[numberParameters++] =
2375          CbcOrClpParam("force!Solution", "Whether to use given solution as crash for BAB",
2376                        -1, 20000000, CLP_PARAM_INT_USESOLUTION);
2377     parameters[numberParameters-1].setIntValue(-1);
2378     parameters[numberParameters-1].setLonghelp
2379     (
2380          "-1 off.  If 1 then tries to branch to solution given by AMPL or priorities file. \
2381If 0 then just tries to set as best solution \
2382If >1 then also does that many nodes on fixed problem."
2383     );
2384     parameters[numberParameters++] =
2385          CbcOrClpParam("fraction!forBAB", "Fraction in feasibility pump",
2386                        1.0e-5, 1.1, CBC_PARAM_DBL_SMALLBAB, 1);
2387     parameters[numberParameters-1].setDoubleValue(0.5);
2388     parameters[numberParameters-1].setLonghelp
2389     (
2390          "After a pass in feasibility pump, variables which have not moved \
2391about are fixed and if the preprocessed model is small enough a few nodes \
2392of branch and bound are done on reduced problem.  Small problem has to be less than this fraction of original."
2393     );
2394#endif
2395     parameters[numberParameters++] =
2396          CbcOrClpParam("gamma!(Delta)", "Whether to regularize barrier",
2397                        "off", CLP_PARAM_STR_GAMMA, 7, 1);
2398     parameters[numberParameters-1].append("on");
2399     parameters[numberParameters-1].append("gamma");
2400     parameters[numberParameters-1].append("delta");
2401     parameters[numberParameters-1].append("onstrong");
2402     parameters[numberParameters-1].append("gammastrong");
2403     parameters[numberParameters-1].append("deltastrong");
2404#endif
2405#ifdef COIN_HAS_CBC
2406      parameters[numberParameters++] =
2407          CbcOrClpParam("GMI!Cuts", "Whether to use alternative Gomory cuts",
2408                        "off", CBC_PARAM_STR_GMICUTS);
2409     parameters[numberParameters-1].append("on");
2410     parameters[numberParameters-1].append("root");
2411     parameters[numberParameters-1].append("ifmove");
2412     parameters[numberParameters-1].append("forceOn");
2413     parameters[numberParameters-1].append("endonly");
2414     parameters[numberParameters-1].append("long");
2415     parameters[numberParameters-1].append("longroot");
2416     parameters[numberParameters-1].append("longifmove");
2417     parameters[numberParameters-1].append("forceLongOn");
2418     parameters[numberParameters-1].append("longendonly");
2419     parameters[numberParameters-1].setLonghelp
2420     (
2421          "This switches on an alternative Gomory cut generator (either at root or in entire tree) \
2422This version is by Giacomo Nannicini and may be more robust \
2423See branchAndCut for information on options."
2424     );
2425     parameters[numberParameters++] =
2426          CbcOrClpParam("gomory!Cuts", "Whether to use Gomory cuts",
2427                        "off", CBC_PARAM_STR_GOMORYCUTS);
2428     parameters[numberParameters-1].append("on");
2429     parameters[numberParameters-1].append("root");
2430     parameters[numberParameters-1].append("ifmove");
2431     parameters[numberParameters-1].append("forceOn");
2432     parameters[numberParameters-1].append("onglobal");
2433     parameters[numberParameters-1].append("forceandglobal");
2434     parameters[numberParameters-1].append("forceLongOn");
2435     parameters[numberParameters-1].append("long");
2436     parameters[numberParameters-1].setLonghelp
2437     (
2438          "The original cuts - beware of imitations!  Having gone out of favor, they are now more \
2439fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
2440give cuts (although in this executable they are limited as to number of variables in cut).  \
2441However the cuts may be dense so it is worth experimenting (Long allows any length). \
2442See branchAndCut for information on options."
2443     );
2444     parameters[numberParameters++] =
2445          CbcOrClpParam("greedy!Heuristic", "Whether to use a greedy heuristic",
2446                        "off", CBC_PARAM_STR_GREEDY);
2447     parameters[numberParameters-1].append("on");
2448     parameters[numberParameters-1].append("both");
2449     parameters[numberParameters-1].append("before");
2450     //parameters[numberParameters-1].append("root");
2451     parameters[numberParameters-1].setLonghelp
2452     (
2453          "Switches on a greedy heuristic which will try and obtain a solution.  It may just fix a \
2454percentage of variables and then try a small branch and cut run. \
2455See Rounding for meaning of on,both,before"
2456     );
2457#endif
2458     parameters[numberParameters++] =
2459          CbcOrClpParam("gsolu!tion", "Puts glpk solution to file",
2460                        CLP_PARAM_ACTION_GMPL_SOLUTION);
2461     parameters[numberParameters-1].setLonghelp
2462     (
2463          "Will write a glpk solution file to the given file name.  It will use the default\
2464 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2465 is initialized to 'stdout' (this defaults to ordinary solution if stdout). \
2466If problem created from gmpl model - will do any reports."
2467     );
2468#ifdef COIN_HAS_CBC
2469     parameters[numberParameters++] =
2470          CbcOrClpParam("heur!isticsOnOff", "Switches most heuristics on or off",
2471                        "off", CBC_PARAM_STR_HEURISTICSTRATEGY);
2472     parameters[numberParameters-1].append("on");
2473     parameters[numberParameters-1].setLonghelp
2474     (
2475          "This can be used to switch on or off all heuristics.  Then you can do \
2476individual ones off or on.  CbcTreeLocal is not included as it dramatically \
2477alters search."
2478     );
2479#endif
2480     parameters[numberParameters++] =
2481          CbcOrClpParam("help", "Print out version, non-standard options and some help",
2482                        CLP_PARAM_ACTION_HELP, 3);
2483     parameters[numberParameters-1].setLonghelp
2484     (
2485          "This prints out some help to get user started.  If you have printed this then \
2486you should be past that stage:-)"
2487     );
2488#ifdef COIN_HAS_CBC
2489     parameters[numberParameters++] =
2490          CbcOrClpParam("hOp!tions", "Heuristic options",
2491                        -9999999, 9999999, CBC_PARAM_INT_HOPTIONS, 1);
2492     parameters[numberParameters-1].setLonghelp
2493     (
2494          "1 says stop heuristic immediately allowable gap reached. \
2495Others are for feasibility pump - \
24962 says do exact number of passes given, \
24974 only applies if initial cutoff given and says relax after 50 passes, \
2498while 8 will adapt cutoff rhs after first solution if it looks as if code is stalling."
2499     );
2500     parameters[numberParameters-1].setIntValue(0);
2501     parameters[numberParameters++] =
2502          CbcOrClpParam("hot!StartMaxIts", "Maximum iterations on hot start",
2503                        0, COIN_INT_MAX, CBC_PARAM_INT_MAXHOTITS);
2504#endif
2505#ifdef COIN_HAS_CLP
2506     parameters[numberParameters++] =
2507          CbcOrClpParam("idiot!Crash", "Whether to try idiot crash",
2508                        -1, 99999999, CLP_PARAM_INT_IDIOT);
2509     parameters[numberParameters-1].setLonghelp
2510     (
2511          "This is a type of 'crash' which works well on some homogeneous problems.\
2512 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
2513 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
2514 0 to switch off or n > 0 to do n passes."
2515     );
2516#endif
2517     parameters[numberParameters++] =
2518          CbcOrClpParam("import", "Import model from mps file",
2519                        CLP_PARAM_ACTION_IMPORT, 3);
2520     parameters[numberParameters-1].setLonghelp
2521     (
2522          "This will read an MPS format file from the given file name.  It will use the default\
2523 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2524 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
2525 files 'xxxxxxxx.gz' or 'xxxxxxxx.bz2'.  \
2526If 'keepnames' is off, then names are dropped -> Rnnnnnnn and Cnnnnnnn."
2527     );
2528#ifdef COIN_HAS_CBC
2529     parameters[numberParameters++] =
2530          CbcOrClpParam("inc!rement", "A valid solution must be at least this \
2531much better than last integer solution",
2532                        -1.0e20, 1.0e20, CBC_PARAM_DBL_INCREMENT);
2533     parameters[numberParameters-1].setLonghelp
2534     (
2535          "Whenever a solution is found the bound on solutions is set to solution (in a minimization\
2536sense) plus this.  If it is not set then the code will try and work one out e.g. if \
2537all objective coefficients are multiples of 0.01 and only integer variables have entries in \
2538objective then this can be set to 0.01.  Be careful if you set this negative!"
2539     );
2540     parameters[numberParameters++] =
2541          CbcOrClpParam("inf!easibilityWeight", "Each integer infeasibility is expected \
2542to cost this much",
2543                        0.0, 1.0e20, CBC_PARAM_DBL_INFEASIBILITYWEIGHT, 1);
2544     parameters[numberParameters-1].setLonghelp
2545     (
2546          "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is \
2547expected to cost this much."
2548     );
2549     parameters[numberParameters++] =
2550          CbcOrClpParam("initialS!olve", "Solve to continuous",
2551                        CLP_PARAM_ACTION_SOLVECONTINUOUS);
2552     parameters[numberParameters-1].setLonghelp
2553     (
2554          "This just solves the problem to continuous - without adding any cuts"
2555     );
2556     parameters[numberParameters++] =
2557          CbcOrClpParam("integerT!olerance", "For an optimal solution \
2558no integer variable may be this away from an integer value",
2559                        1.0e-20, 0.5, CBC_PARAM_DBL_INTEGERTOLERANCE);
2560     parameters[numberParameters-1].setLonghelp
2561     (
2562          "Beware of setting this smaller than the primal tolerance."
2563     );
2564#endif
2565#ifdef COIN_HAS_CLP
2566     parameters[numberParameters++] =
2567          CbcOrClpParam("keepN!ames", "Whether to keep names from import",
2568                        "on", CLP_PARAM_STR_KEEPNAMES);
2569     parameters[numberParameters-1].append("off");
2570     parameters[numberParameters-1].setLonghelp
2571     (
2572          "It saves space to get rid of names so if you need to you can set this to off.  \
2573This needs to be set before the import of model - so -keepnames off -import xxxxx.mps."
2574     );
2575     parameters[numberParameters++] =
2576          CbcOrClpParam("KKT", "Whether to use KKT factorization",
2577                        "off", CLP_PARAM_STR_KKT, 7, 1);
2578     parameters[numberParameters-1].append("on");
2579#endif
2580#ifdef COIN_HAS_CBC
2581     parameters[numberParameters++] =
2582          CbcOrClpParam("knapsack!Cuts", "Whether to use Knapsack cuts",
2583                        "off", CBC_PARAM_STR_KNAPSACKCUTS);
2584     parameters[numberParameters-1].append("on");
2585     parameters[numberParameters-1].append("root");
2586     parameters[numberParameters-1].append("ifmove");
2587     parameters[numberParameters-1].append("forceOn");
2588     parameters[numberParameters-1].append("onglobal");
2589     parameters[numberParameters-1].append("forceandglobal");
2590     parameters[numberParameters-1].setLonghelp
2591     (
2592          "This switches on knapsack cuts (either at root or in entire tree) \
2593See branchAndCut for information on options."
2594     );
2595     parameters[numberParameters++] =
2596          CbcOrClpParam("lagomory!Cuts", "Whether to use Lagrangean Gomory cuts",
2597                        "off", CBC_PARAM_STR_LAGOMORYCUTS);
2598     parameters[numberParameters-1].append("endonlyroot");
2599     parameters[numberParameters-1].append("endcleanroot");
2600     parameters[numberParameters-1].append("root");
2601     parameters[numberParameters-1].append("endonly");
2602     parameters[numberParameters-1].append("endclean");
2603     parameters[numberParameters-1].append("endboth");
2604     parameters[numberParameters-1].append("onlyaswell");
2605     parameters[numberParameters-1].append("cleanaswell");
2606     parameters[numberParameters-1].append("bothaswell");
2607     parameters[numberParameters-1].append("onlyinstead");
2608     parameters[numberParameters-1].append("cleaninstead");
2609     parameters[numberParameters-1].append("bothinstead");
2610     parameters[numberParameters-1].append("onlyaswellroot");
2611     parameters[numberParameters-1].append("cleanaswellroot");
2612     parameters[numberParameters-1].append("bothaswellroot");
2613     parameters[numberParameters-1].setLonghelp
2614     (
2615          "This is a gross simplification of 'A Relax-and-Cut Framework for Gomory's Mixed-Integer Cuts' \
2616by Matteo Fischetti & Domenico Salvagnin.  This simplification \
2617just uses original constraints while modifying objective using other cuts. \
2618So you don't use messy constraints generated by Gomory etc. \
2619A variant is to allow non messy cuts e.g. clique cuts. \
2620So 'only' does this while clean also allows integral valued cuts.  \
2621'End' is recommended which waits until other cuts have finished and then \
2622does a few passes. \
2623The length options for gomory cuts are used."
2624     );
2625     parameters[numberParameters++] =
2626          CbcOrClpParam("latwomir!Cuts", "Whether to use Lagrangean TwoMir cuts",
2627                        "off", CBC_PARAM_STR_LATWOMIRCUTS);
2628     parameters[numberParameters-1].append("endonlyroot");
2629     parameters[numberParameters-1].append("endcleanroot");
2630     parameters[numberParameters-1].append("endbothroot");
2631     parameters[numberParameters-1].append("endonly");
2632     parameters[numberParameters-1].append("endclean");
2633     parameters[numberParameters-1].append("endboth");
2634     parameters[numberParameters-1].append("onlyaswell");
2635     parameters[numberParameters-1].append("cleanaswell");
2636     parameters[numberParameters-1].append("bothaswell");
2637     parameters[numberParameters-1].append("onlyinstead");
2638     parameters[numberParameters-1].append("cleaninstead");
2639     parameters[numberParameters-1].append("bothinstead");
2640     parameters[numberParameters-1].setLonghelp
2641     (
2642          "This is a lagrangean relaxation for TwoMir cuts.  See \
2643lagomoryCuts for description of options."
2644     );
2645     parameters[numberParameters++] =
2646          CbcOrClpParam("lift!AndProjectCuts", "Whether to use Lift and Project cuts",
2647                        "off", CBC_PARAM_STR_LANDPCUTS);
2648     parameters[numberParameters-1].append("on");
2649     parameters[numberParameters-1].append("root");
2650     parameters[numberParameters-1].append("ifmove");
2651     parameters[numberParameters-1].append("forceOn");
2652     parameters[numberParameters-1].setLonghelp
2653     (
2654          "Lift and project cuts. \
2655May be slow \
2656See branchAndCut for information on options."
2657     );
2658     parameters[numberParameters++] =
2659          CbcOrClpParam("local!TreeSearch", "Whether to use local treesearch",
2660                        "off", CBC_PARAM_STR_LOCALTREE);
2661     parameters[numberParameters-1].append("on");
2662     parameters[numberParameters-1].setLonghelp
2663     (
2664          "This switches on a local search algorithm when a solution is found.  This is from \
2665Fischetti and Lodi and is not really a heuristic although it can be used as one. \
2666When used from Coin solve it has limited functionality.  It is not switched on when \
2667heuristics are switched on."
2668     );
2669#endif
2670#ifndef COIN_HAS_CBC
2671     parameters[numberParameters++] =
2672          CbcOrClpParam("log!Level", "Level of detail in Solver output",
2673                        -1, 999999, CLP_PARAM_INT_SOLVERLOGLEVEL);
2674#else
2675     parameters[numberParameters++] =
2676          CbcOrClpParam("log!Level", "Level of detail in Coin branch and Cut output",
2677                        -63, 63, CLP_PARAM_INT_LOGLEVEL);
2678     parameters[numberParameters-1].setIntValue(1);
2679#endif
2680     parameters[numberParameters-1].setLonghelp
2681     (
2682          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
2683 value for most uses, while 2 and 3 give more information."
2684     );
2685     parameters[numberParameters++] =
2686          CbcOrClpParam("max!imize", "Set optimization direction to maximize",
2687                        CLP_PARAM_ACTION_MAXIMIZE, 7);
2688     parameters[numberParameters-1].setLonghelp
2689     (
2690          "The default is minimize - use 'maximize' for maximization.\n\
2691You can also use the parameters 'direction maximize'."
2692     );
2693#ifdef COIN_HAS_CLP
2694     parameters[numberParameters++] =
2695          CbcOrClpParam("maxF!actor", "Maximum number of iterations between \
2696refactorizations",
2697                        1, 999999, CLP_PARAM_INT_MAXFACTOR);
2698     parameters[numberParameters-1].setLonghelp
2699     (
2700          "If this is at its initial value of 200 then in this executable clp will guess at a\
2701 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
2702 earlier for accuracy."
2703     );
2704     parameters[numberParameters++] =
2705          CbcOrClpParam("maxIt!erations", "Maximum number of iterations before \
2706stopping",
2707                        0, 2147483647, CLP_PARAM_INT_MAXITERATION);
2708     parameters[numberParameters-1].setLonghelp
2709     (
2710          "This can be used for testing purposes.  The corresponding library call\n\
2711      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
2712 seconds or by an interrupt this will be treated as stopping on maximum iterations.  This is ignored in branchAndCut - use maxN!odes."
2713     );
2714#endif
2715#ifdef COIN_HAS_CBC
2716     parameters[numberParameters++] =
2717          CbcOrClpParam("maxN!odes", "Maximum number of nodes to do",
2718                        -1, 2147483647, CBC_PARAM_INT_MAXNODES);
2719     parameters[numberParameters-1].setLonghelp
2720     (
2721          "This is a repeatable way to limit search.  Normally using time is easier \
2722but then the results may not be repeatable."
2723     );
2724     parameters[numberParameters++] =
2725          CbcOrClpParam("maxSaved!Solutions", "Maximum number of solutions to save",
2726                        0, 2147483647, CBC_PARAM_INT_MAXSAVEDSOLS);
2727     parameters[numberParameters-1].setLonghelp
2728     (
2729          "Number of solutions to save."
2730     );
2731     parameters[numberParameters++] =
2732          CbcOrClpParam("maxSo!lutions", "Maximum number of solutions to get",
2733                        1, 2147483647, CBC_PARAM_INT_MAXSOLS);
2734     parameters[numberParameters-1].setLonghelp
2735     (
2736          "You may want to stop after (say) two solutions or an hour.  \
2737This is checked every node in tree, so it is possible to get more solutions from heuristics."
2738     );
2739#endif
2740     parameters[numberParameters++] =
2741          CbcOrClpParam("min!imize", "Set optimization direction to minimize",
2742                        CLP_PARAM_ACTION_MINIMIZE, 7);
2743     parameters[numberParameters-1].setLonghelp
2744     (
2745          "The default is minimize - use 'maximize' for maximization.\n\
2746This should only be necessary if you have previously set maximization \
2747You can also use the parameters 'direction minimize'."
2748     );
2749#ifdef COIN_HAS_CBC
2750     parameters[numberParameters++] =
2751          CbcOrClpParam("mipO!ptions", "Dubious options for mip",
2752                        0, COIN_INT_MAX, CBC_PARAM_INT_MIPOPTIONS, 0);
2753     parameters[numberParameters++] =
2754          CbcOrClpParam("more!MipOptions", "More dubious options for mip",
2755                        -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMIPOPTIONS, 0);
2756     parameters[numberParameters++] =
2757          CbcOrClpParam("more2!MipOptions", "More more dubious options for mip",
2758                        -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMOREMIPOPTIONS, 0);
2759     parameters[numberParameters-1].setIntValue(0);
2760     parameters[numberParameters++] =
2761          CbcOrClpParam("mixed!IntegerRoundingCuts", "Whether to use Mixed Integer Rounding cuts",
2762                        "off", CBC_PARAM_STR_MIXEDCUTS);
2763     parameters[numberParameters-1].append("on");
2764     parameters[numberParameters-1].append("root");
2765     parameters[numberParameters-1].append("ifmove");
2766     parameters[numberParameters-1].append("forceOn");
2767     parameters[numberParameters-1].append("onglobal");
2768     parameters[numberParameters-1].setLonghelp
2769     (
2770          "This switches on mixed integer rounding cuts (either at root or in entire tree) \
2771See branchAndCut for information on options."
2772     );
2773#endif
2774     parameters[numberParameters++] =
2775          CbcOrClpParam("mess!ages", "Controls if Clpnnnn is printed",
2776                        "off", CLP_PARAM_STR_MESSAGES);
2777     parameters[numberParameters-1].append("on");
2778     parameters[numberParameters-1].setLonghelp
2779     ("The default behavior is to put out messages such as:\n\
2780   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
2781but this program turns this off to make it look more friendly.  It can be useful\
2782 to turn them back on if you want to be able to 'grep' for particular messages or if\
2783 you intend to override the behavior of a particular message.  This only affects Clp not Cbc."
2784     );
2785     parameters[numberParameters++] =
2786          CbcOrClpParam("miplib", "Do some of miplib test set",
2787                        CBC_PARAM_ACTION_MIPLIB, 3, 1);
2788#ifdef COIN_HAS_CBC
2789      parameters[numberParameters++] =
2790          CbcOrClpParam("mips!tart", "reads an initial feasible solution from file",
2791                        CBC_PARAM_ACTION_MIPSTART);
2792     parameters[numberParameters-1].setLonghelp
2793     ("\
2794The MIPStart allows one to enter an initial integer feasible solution \
2795to CBC. Values of the main decision variables which are active (have \
2796non-zero values) in this solution are specified in a text  file. The \
2797text file format used is the same of the solutions saved by CBC, but \
2798not all fields are required to be filled. First line may contain the \
2799solution status and will be ignored, remaining lines contain column \
2800indexes, names and values as in this example:\n\
2801\n\
2802Stopped on iterations - objective value 57597.00000000\n\
2803      0  x(1,1,2,2)               1 \n\
2804      1  x(3,1,3,2)               1 \n\
2805      5  v(5,1)                   2 \n\
2806      33 x(8,1,5,2)               1 \n\
2807      ...\n\
2808\n\
2809Column indexes are also ignored since pre-processing can change them. \
2810There is no need to include values for continuous or integer auxiliary \
2811variables, since they can be computed based on main decision variables. \
2812Starting CBC with an integer feasible solution can dramatically improve \
2813its performance: several MIP heuristics (e.g. RINS) rely on having at \
2814least one feasible solution available and can start immediately if the \
2815user provides one. Feasibility Pump (FP) is a heuristic which tries to \
2816overcome the problem of taking too long to find feasible solution (or \
2817not finding at all), but it not always succeeds. If you provide one \
2818starting solution you will probably save some time by disabling FP. \
2819\n\n\
2820Knowledge specific to your problem can be considered to write an \
2821external module to quickly produce an initial feasible solution - some \
2822alternatives are the implementation of simple greedy heuristics or the \
2823solution (by CBC for example) of a simpler model created just to find \
2824a feasible solution. \
2825\n\n\
2826Question and suggestions regarding MIPStart can be directed to\n\
2827haroldo.santos@gmail.com.\
2828");
2829#endif
2830     parameters[numberParameters++] =
2831          CbcOrClpParam("moreS!pecialOptions", "Yet more dubious options for Simplex - see ClpSimplex.hpp",
2832                        0, COIN_INT_MAX, CLP_PARAM_INT_MORESPECIALOPTIONS, 0);
2833#ifdef COIN_HAS_CBC
2834     parameters[numberParameters++] =
2835          CbcOrClpParam("moreT!une", "Yet more dubious ideas for feasibility pump",
2836                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE2, 0);
2837     parameters[numberParameters-1].setLonghelp
2838     (
2839          "Yet more ideas for Feasibility Pump \n\
2840\t/100000 == 1 use box constraints and original obj in cleanup\n\
2841\t/1000 == 1 Pump will run twice if no solution found\n\
2842\t/1000 == 2 Pump will only run after root cuts if no solution found\n\
2843\t/1000 >10 as above but even if solution found\n\
2844\t/100 == 1,3.. exact 1.0 for objective values\n\
2845\t/100 == 2,3.. allow more iterations per pass\n\
2846\t n fix if value of variable same for last n iterations."
2847     );
2848     parameters[numberParameters-1].setIntValue(0);
2849     parameters[numberParameters++] =
2850          CbcOrClpParam("multiple!RootPasses", "Do multiple root passes to collect cuts and solutions",
2851                        0, 100000000, CBC_PARAM_INT_MULTIPLEROOTS, 0);
2852     parameters[numberParameters-1].setIntValue(0);
2853     parameters[numberParameters-1].setLonghelp
2854     (
2855          "Do (in parallel if threads enabled) the root phase this number of times \
2856 and collect all solutions and cuts generated.  The actual format is aabbcc \
2857where aa is number of extra passes, if bb is non zero \
2858then it is number of threads to use (otherwise uses threads setting) and \
2859cc is number of times to do root phase.  Yet another one from the Italian idea factory \
2860(This time - Andrea Lodi , Matteo Fischetti , Michele Monaci , Domenico Salvagnin , \
2861and Andrea Tramontani). \
2862The solvers do not interact with each other.  However if extra passes are specified \
2863then cuts are collected and used in later passes - so there is interaction there." 
2864     );
2865     parameters[numberParameters++] =
2866          CbcOrClpParam("naive!Heuristics", "Whether to try some stupid heuristic",
2867                        "off", CBC_PARAM_STR_NAIVE, 7, 1);
2868     parameters[numberParameters-1].append("on");
2869     parameters[numberParameters-1].append("both");
2870     parameters[numberParameters-1].append("before");
2871     parameters[numberParameters-1].setLonghelp
2872     (
2873          "Really silly stuff e.g. fix all integers with costs to zero!. \
2874Doh option does heuristic before preprocessing"     );
2875#endif
2876#ifdef COIN_HAS_CLP
2877     parameters[numberParameters++] =
2878          CbcOrClpParam("netlib", "Solve entire netlib test set",
2879                        CLP_PARAM_ACTION_NETLIB_EITHER, 3, 1);
2880     parameters[numberParameters-1].setLonghelp
2881     (
2882          "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
2883The user can set options before e.g. clp -presolve off -netlib"
2884     );
2885     parameters[numberParameters++] =
2886          CbcOrClpParam("netlibB!arrier", "Solve entire netlib test set with barrier",
2887                        CLP_PARAM_ACTION_NETLIB_BARRIER, 3, 1);
2888     parameters[numberParameters-1].setLonghelp
2889     (
2890          "This exercises the unit test for clp and then solves the netlib test set using barrier.\
2891The user can set options before e.g. clp -kkt on -netlib"
2892     );
2893     parameters[numberParameters++] =
2894          CbcOrClpParam("netlibD!ual", "Solve entire netlib test set (dual)",
2895                        CLP_PARAM_ACTION_NETLIB_DUAL, 3, 1);
2896     parameters[numberParameters-1].setLonghelp
2897     (
2898          "This exercises the unit test for clp and then solves the netlib test set using dual.\
2899The user can set options before e.g. clp -presolve off -netlib"
2900     );
2901     parameters[numberParameters++] =
2902          CbcOrClpParam("netlibP!rimal", "Solve entire netlib test set (primal)",
2903                        CLP_PARAM_ACTION_NETLIB_PRIMAL, 3, 1);
2904     parameters[numberParameters-1].setLonghelp
2905     (
2906          "This exercises the unit test for clp and then solves the netlib test set using primal.\
2907The user can set options before e.g. clp -presolve off -netlibp"
2908     );
2909     parameters[numberParameters++] =
2910          CbcOrClpParam("netlibT!une", "Solve entire netlib test set with 'best' algorithm",
2911                        CLP_PARAM_ACTION_NETLIB_TUNE, 3, 1);
2912     parameters[numberParameters-1].setLonghelp
2913     (
2914          "This exercises the unit test for clp and then solves the netlib test set using whatever \
2915works best.  I know this is cheating but it also stresses the code better by doing a \
2916mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
2917with University of Florida ordering."
2918     );
2919     parameters[numberParameters++] =
2920          CbcOrClpParam("network", "Tries to make network matrix",
2921                        CLP_PARAM_ACTION_NETWORK, 7, 0);
2922     parameters[numberParameters-1].setLonghelp
2923     (
2924          "Clp will go faster if the matrix can be converted to a network.  The matrix\
2925 operations may be a bit faster with more efficient storage, but the main advantage\
2926 comes from using a network factorization.  It will probably not be as fast as a \
2927specialized network code."
2928     );
2929#ifdef COIN_HAS_CBC
2930     parameters[numberParameters++] =
2931          CbcOrClpParam("nextB!estSolution", "Prints next best saved solution to file",
2932                        CLP_PARAM_ACTION_NEXTBESTSOLUTION);
2933     parameters[numberParameters-1].setLonghelp
2934     (
2935          "To write best solution, just use solution.  This prints next best (if exists) \
2936 and then deletes it. \
2937 This will write a primitive solution file to the given file name.  It will use the default\
2938 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2939 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
2940     );
2941     parameters[numberParameters++] =
2942          CbcOrClpParam("node!Strategy", "What strategy to use to select nodes",
2943                        "hybrid", CBC_PARAM_STR_NODESTRATEGY);
2944     parameters[numberParameters-1].append("fewest");
2945     parameters[numberParameters-1].append("depth");
2946     parameters[numberParameters-1].append("upfewest");
2947     parameters[numberParameters-1].append("downfewest");
2948     parameters[numberParameters-1].append("updepth");
2949     parameters[numberParameters-1].append("downdepth");
2950     parameters[numberParameters-1].setLonghelp
2951     (
2952          "Normally before a solution the code will choose node with fewest infeasibilities. \
2953You can choose depth as the criterion.  You can also say if up or down branch must \
2954be done first (the up down choice will carry on after solution). \
2955Default has now been changed to hybrid which is breadth first on small depth nodes then fewest."
2956     );
2957     parameters[numberParameters++] =
2958          CbcOrClpParam("numberA!nalyze", "Number of analysis iterations",
2959                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_NUMBERANALYZE, 0);
2960     parameters[numberParameters-1].setLonghelp
2961     (
2962          "This says how many iterations to spend at root node analyzing problem. \
2963This is a first try and will hopefully become more sophisticated."
2964     );
2965#endif
2966     parameters[numberParameters++] =
2967          CbcOrClpParam("objective!Scale", "Scale factor to apply to objective",
2968                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE, 1);
2969     parameters[numberParameters-1].setLonghelp
2970     (
2971          "If the objective function has some very large values, you may wish to scale them\
2972 internally by this amount.  It can also be set by autoscale.  It is applied after scaling.  You are unlikely to need this."
2973     );
2974     parameters[numberParameters-1].setDoubleValue(1.0);
2975#endif
2976#ifdef COIN_HAS_CBC
2977#ifdef COIN_HAS_NTY
2978     parameters[numberParameters++] =
2979          CbcOrClpParam("Orbit!alBranching", "Whether to try orbital branching",
2980                        "off", CBC_PARAM_STR_ORBITAL);
2981     parameters[numberParameters-1].append("on");
2982     parameters[numberParameters-1].append("strong");
2983     parameters[numberParameters-1].append("force");
2984     parameters[numberParameters-1].setLonghelp
2985     (
2986          "This switches on Orbital branching. \
2987On just adds orbital, strong tries extra fixing in strong branching");
2988#endif
2989     parameters[numberParameters++] =
2990          CbcOrClpParam("outDup!licates", "takes duplicate rows etc out of integer model",
2991                        CLP_PARAM_ACTION_OUTDUPROWS, 7, 0);
2992#endif
2993     parameters[numberParameters++] =
2994          CbcOrClpParam("output!Format", "Which output format to use",
2995                        1, 6, CLP_PARAM_INT_OUTPUTFORMAT);
2996     parameters[numberParameters-1].setLonghelp
2997     (
2998          "Normally export will be done using normal representation for numbers and two values\
2999 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
3000 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
3001 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
3002 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
3003values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
3004     );
3005#ifdef COIN_HAS_CLP
3006     parameters[numberParameters++] =
3007          CbcOrClpParam("para!metrics", "Import data from file and do parametrics",
3008                        CLP_PARAM_ACTION_PARAMETRICS, 3);
3009     parameters[numberParameters-1].setLonghelp
3010     (
3011          "This will read a file with parametric data from the given file name \
3012and then do parametrics.  It will use the default\
3013 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3014 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
3015File is in modified csv format - a line ROWS will be followed by rows data \
3016while a line COLUMNS will be followed by column data.  The last line \
3017should be ENDATA. The ROWS line must exist and is in the format \
3018ROWS, inital theta, final theta, interval theta, n where n is 0 to get \
3019CLPI0062 message at interval or at each change of theta \
3020and 1 to get CLPI0063 message at each iteration.  If interval theta is 0.0 \
3021or >= final theta then no interval reporting.  n may be missed out when it is \
3022taken as 0.  If there is Row data then \
3023there is a headings line with allowed headings - name, number, \
3024lower(rhs change), upper(rhs change), rhs(change).  Either the lower and upper \
3025fields should be given or the rhs field. \
3026The optional COLUMNS line is followed by a headings line with allowed \
3027headings - name, number, objective(change), lower(change), upper(change). \
3028 Exactly one of name and number must be given for either section and \
3029missing ones have value 0.0."
3030     );
3031#endif
3032#ifdef COIN_HAS_CBC
3033     parameters[numberParameters++] =
3034          CbcOrClpParam("passC!uts", "Number of cut passes at root node",
3035                        -9999999, 9999999, CBC_PARAM_INT_CUTPASS);
3036     parameters[numberParameters-1].setLonghelp
3037     (
3038          "The default is 100 passes if less than 500 columns, 100 passes (but \
3039stop if drop small if less than 5000 columns, 20 otherwise"
3040     );
3041     parameters[numberParameters++] =
3042          CbcOrClpParam("passF!easibilityPump", "How many passes in feasibility pump",
3043                        0, 10000, CBC_PARAM_INT_FPUMPITS);
3044     parameters[numberParameters-1].setLonghelp
3045     (
3046          "This fine tunes Feasibility Pump by doing more or fewer passes."
3047     );
3048     parameters[numberParameters-1].setIntValue(20);
3049#endif
3050#ifdef COIN_HAS_CLP
3051     parameters[numberParameters++] =
3052          CbcOrClpParam("passP!resolve", "How many passes in presolve",
3053                        -200, 100, CLP_PARAM_INT_PRESOLVEPASS, 1);
3054     parameters[numberParameters-1].setLonghelp
3055     (
3056          "Normally Presolve does 10 passes but you may want to do less to make it\
3057 more lightweight or do more if improvements are still being made.  As Presolve will return\
3058 if nothing is being taken out, you should not normally need to use this fine tuning."
3059     );
3060#endif
3061#ifdef COIN_HAS_CBC
3062     parameters[numberParameters++] =
3063          CbcOrClpParam("passT!reeCuts", "Number of cut passes in tree",
3064                        -9999999, 9999999, CBC_PARAM_INT_CUTPASSINTREE);
3065     parameters[numberParameters-1].setLonghelp
3066     (
3067          "The default is one pass"
3068     );
3069#endif
3070#ifdef COIN_HAS_CLP
3071     parameters[numberParameters++] =
3072          CbcOrClpParam("pertV!alue", "Method of perturbation",
3073                        -5000, 102, CLP_PARAM_INT_PERTVALUE, 1);
3074     parameters[numberParameters++] =
3075          CbcOrClpParam("perturb!ation", "Whether to perturb problem",
3076                        "on", CLP_PARAM_STR_PERTURBATION);
3077     parameters[numberParameters-1].append("off");
3078     parameters[numberParameters-1].setLonghelp
3079     (
3080          "Perturbation helps to stop cycling, but Clp uses other measures for this.\
3081  However large problems and especially ones with unit elements and unit rhs or costs\
3082 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
3083  The Clp library has this off by default.  This program has it on by default."
3084     );
3085     parameters[numberParameters++] =
3086          CbcOrClpParam("PFI", "Whether to use Product Form of Inverse in simplex",
3087                        "off", CLP_PARAM_STR_PFI, 7, 0);
3088     parameters[numberParameters-1].append("on");
3089     parameters[numberParameters-1].setLonghelp
3090     (
3091          "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
3092     );
3093#endif
3094#ifdef COIN_HAS_CBC
3095     parameters[numberParameters++] =
3096          CbcOrClpParam("pivotAndC!omplement", "Whether to try Pivot and Complement heuristic",
3097                        "off", CBC_PARAM_STR_PIVOTANDCOMPLEMENT);
3098     parameters[numberParameters-1].append("on");
3099     parameters[numberParameters-1].append("both");
3100     parameters[numberParameters-1].append("before");
3101     parameters[numberParameters-1].setLonghelp
3102     (
3103          "stuff needed. \
3104Doh option does heuristic before preprocessing"     );
3105     parameters[numberParameters++] =
3106          CbcOrClpParam("pivotAndF!ix", "Whether to try Pivot and Fix heuristic",
3107                        "off", CBC_PARAM_STR_PIVOTANDFIX);
3108     parameters[numberParameters-1].append("on");
3109     parameters[numberParameters-1].append("both");
3110     parameters[numberParameters-1].append("before");
3111     parameters[numberParameters-1].setLonghelp
3112     (
3113          "stuff needed. \
3114Doh option does heuristic before preprocessing"     );
3115#endif
3116#ifdef COIN_HAS_CLP
3117     parameters[numberParameters++] =
3118          CbcOrClpParam("plus!Minus", "Tries to make +- 1 matrix",
3119                        CLP_PARAM_ACTION_PLUSMINUS, 7, 0);
3120     parameters[numberParameters-1].setLonghelp
3121     (
3122          "Clp will go slightly faster if the matrix can be converted so that the elements are\
3123 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
3124 see if it can convert the problem so you should not need to use this."
3125     );
3126     parameters[numberParameters++] =
3127          CbcOrClpParam("pO!ptions", "Dubious print options",
3128                        0, COIN_INT_MAX, CLP_PARAM_INT_PRINTOPTIONS, 1);
3129     parameters[numberParameters-1].setIntValue(0);
3130     parameters[numberParameters-1].setLonghelp
3131     (
3132          "If this is > 0 then presolve will give more information and branch and cut will give statistics"
3133     );
3134     parameters[numberParameters++] =
3135          CbcOrClpParam("preO!pt", "Presolve options",
3136                        0, COIN_INT_MAX, CLP_PARAM_INT_PRESOLVEOPTIONS, 0);
3137#endif
3138     parameters[numberParameters++] =
3139          CbcOrClpParam("presolve", "Whether to presolve problem",
3140                        "on", CLP_PARAM_STR_PRESOLVE);
3141     parameters[numberParameters-1].append("off");
3142     parameters[numberParameters-1].append("more");
3143     parameters[numberParameters-1].append("file");
3144     parameters[numberParameters-1].setLonghelp
3145     (
3146          "Presolve analyzes the model to find such things as redundant equations, equations\
3147 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
3148 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
3149on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
3150to write the original to file using 'file'."
3151     );
3152#ifdef COIN_HAS_CBC
3153     parameters[numberParameters++] =
3154          CbcOrClpParam("preprocess", "Whether to use integer preprocessing",
3155                        "off", CBC_PARAM_STR_PREPROCESS);
3156     parameters[numberParameters-1].append("on");
3157     parameters[numberParameters-1].append("save");
3158     parameters[numberParameters-1].append("equal");
3159     parameters[numberParameters-1].append("sos");
3160     parameters[numberParameters-1].append("trysos");
3161     parameters[numberParameters-1].append("equalall");
3162     parameters[numberParameters-1].append("strategy");
3163     parameters[numberParameters-1].append("aggregate");
3164     parameters[numberParameters-1].append("forcesos");
3165     parameters[numberParameters-1].setLonghelp
3166     (
3167          "This tries to reduce size of model in a similar way to presolve and \
3168it also tries to strengthen the model - this can be very useful and is worth trying. \
3169 Save option saves on file presolved.mps.  equal will turn <= cliques into \
3170==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
3171and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
3172valid inequalities into equalities with integer slacks.  strategy is as \
3173on but uses CbcStrategy."
3174     );
3175#endif
3176#ifdef COIN_HAS_CLP
3177     parameters[numberParameters++] =
3178          CbcOrClpParam("preT!olerance", "Tolerance to use in presolve",
3179                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRESOLVETOLERANCE);
3180     parameters[numberParameters-1].setLonghelp
3181     (
3182          "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
3183infeasible and you have awkward numbers and you are sure the problem is really feasible."
3184     );
3185     parameters[numberParameters++] =
3186          CbcOrClpParam("primalP!ivot", "Primal pivot choice algorithm",
3187                        "auto!matic", CLP_PARAM_STR_PRIMALPIVOT, 7, 1);
3188     parameters[numberParameters-1].append("exa!ct");
3189     parameters[numberParameters-1].append("dant!zig");
3190     parameters[numberParameters-1].append("part!ial");
3191     parameters[numberParameters-1].append("steep!est");
3192     parameters[numberParameters-1].append("change");
3193     parameters[numberParameters-1].append("sprint");
3194     parameters[numberParameters-1].setLonghelp
3195     (
3196          "Clp can use any pivot selection algorithm which the user codes as long as it\
3197 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
3198 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
3199 are two variants which keep all weights updated but only scan a subset each iteration.\
3200 Partial switches this on while change initially does dantzig until the factorization\
3201 becomes denser.  This is still a work in progress."
3202     );
3203     parameters[numberParameters++] =
3204          CbcOrClpParam("primalS!implex", "Do primal simplex algorithm",
3205                        CLP_PARAM_ACTION_PRIMALSIMPLEX);
3206     parameters[numberParameters-1].setLonghelp
3207     (
3208          "This command solves the continuous relaxation of the current model using the primal algorithm.\
3209  The default is to use exact devex.\
3210 The time and iterations may be affected by settings such as presolve, scaling, crash\
3211 and also by column selection  method, infeasibility weight and dual and primal tolerances."
3212     );
3213#endif
3214     parameters[numberParameters++] =
3215          CbcOrClpParam("primalT!olerance", "For an optimal solution \
3216no primal infeasibility may exceed this value",
3217                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRIMALTOLERANCE);
3218     parameters[numberParameters-1].setLonghelp
3219     (
3220          "Normally the default tolerance is fine, but you may want to increase it a\
3221 bit if a primal run seems to be having a hard time"
3222     );
3223#ifdef COIN_HAS_CLP
3224     parameters[numberParameters++] =
3225          CbcOrClpParam("primalW!eight", "Initially algorithm acts as if it \
3226costs this much to be infeasible",
3227                        1.0e-20, 1.0e20, CLP_PARAM_DBL_PRIMALWEIGHT);
3228     parameters[numberParameters-1].setLonghelp
3229     (
3230          "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
3231 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
3232 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
3233  Too high a value may mean more iterations, while too low a bound means\
3234 the code may go all the way and then have to increase the weight in order to get feasible.\
3235  OSL had a heuristic to\
3236 adjust bounds, maybe we need that here."
3237     );
3238#endif
3239     parameters[numberParameters++] =
3240          CbcOrClpParam("printi!ngOptions", "Print options",
3241                        "normal", CLP_PARAM_STR_INTPRINT, 3);
3242     parameters[numberParameters-1].append("integer");
3243     parameters[numberParameters-1].append("special");
3244     parameters[numberParameters-1].append("rows");
3245     parameters[numberParameters-1].append("all");
3246     parameters[numberParameters-1].append("csv");
3247     parameters[numberParameters-1].append("bound!ranging");
3248     parameters[numberParameters-1].append("rhs!ranging");
3249     parameters[numberParameters-1].append("objective!ranging");
3250     parameters[numberParameters-1].append("stats");
3251     parameters[numberParameters-1].append("boundsint");
3252     parameters[numberParameters-1].append("boundsall");
3253     parameters[numberParameters-1].setLonghelp
3254     (
3255          "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
3256integer - nonzero integer column variables\n\
3257special - in format suitable for OsiRowCutDebugger\n\
3258rows - nonzero column variables and row activities\n\
3259all - all column variables and row activities.\n\
3260\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
3261Also see printMask for controlling output."
3262     );
3263     parameters[numberParameters++] =
3264          CbcOrClpParam("printM!ask", "Control printing of solution on a  mask",
3265                        CLP_PARAM_ACTION_PRINTMASK, 3);
3266     parameters[numberParameters-1].setLonghelp
3267     (
3268          "If set then only those names which match mask are printed in a solution. \
3269'?' matches any character and '*' matches any set of characters. \
3270 The default is '' i.e. unset so all variables are printed. \
3271This is only active if model has names."
3272     );
3273#ifdef COIN_HAS_CBC
3274     parameters[numberParameters++] =
3275          CbcOrClpParam("prio!rityIn", "Import priorities etc from file",
3276                        CBC_PARAM_ACTION_PRIORITYIN, 3);
3277     parameters[numberParameters-1].setLonghelp
3278     (
3279          "This will read a file with priorities from the given file name.  It will use the default\
3280 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3281 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
3282File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
3283 name and number must be given."
3284     );
3285     parameters[numberParameters++] =
3286          CbcOrClpParam("probing!Cuts", "Whether to use Probing cuts",
3287                        "off", CBC_PARAM_STR_PROBINGCUTS);
3288     parameters[numberParameters-1].append("on");
3289     parameters[numberParameters-1].append("root");
3290     parameters[numberParameters-1].append("ifmove");
3291     parameters[numberParameters-1].append("forceOn");
3292     parameters[numberParameters-1].append("onglobal");
3293     parameters[numberParameters-1].append("forceonglobal");
3294     parameters[numberParameters-1].append("forceOnBut");
3295     parameters[numberParameters-1].append("forceOnStrong");
3296     parameters[numberParameters-1].append("forceOnButStrong");
3297     parameters[numberParameters-1].append("strongRoot");
3298     parameters[numberParameters-1].setLonghelp
3299     (
3300          "This switches on probing cuts (either at root or in entire tree) \
3301See branchAndCut for information on options. \
3302but strong options do more probing"
3303     );
3304     parameters[numberParameters++] =
3305          CbcOrClpParam("proximity!Search", "Whether to do proximity search heuristic",
3306                        "off", CBC_PARAM_STR_PROXIMITY);
3307     parameters[numberParameters-1].append("on");
3308     parameters[numberParameters-1].append("both");
3309     parameters[numberParameters-1].append("before");
3310     parameters[numberParameters-1].append("10");
3311     parameters[numberParameters-1].append("100");
3312     parameters[numberParameters-1].append("300");
3313     // but allow numbers after this (returning 1)
3314     parameters[numberParameters-1].setFakeKeyWord(1);
3315     parameters[numberParameters-1].setLonghelp
3316     (
3317          "This switches on a heuristic which looks for a solution close \
3318to incumbent solution (Fischetti and Monaci). \
3319See Rounding for meaning of on,both,before. \
3320Can also set different maxNode settings by plusnnnn (and are 'on'(on==30))."
3321     );
3322     parameters[numberParameters++] =
3323          CbcOrClpParam("pumpC!utoff", "Fake cutoff for use in feasibility pump",
3324                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKECUTOFF);
3325     parameters[numberParameters-1].setDoubleValue(0.0);
3326     parameters[numberParameters-1].setLonghelp
3327     (
3328          "0.0 off - otherwise add a constraint forcing objective below this value\
3329 in feasibility pump"
3330     );
3331     parameters[numberParameters++] =
3332          CbcOrClpParam("pumpI!ncrement", "Fake increment for use in feasibility pump",
3333                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKEINCREMENT, 1);
3334     parameters[numberParameters-1].setDoubleValue(0.0);
3335     parameters[numberParameters-1].setLonghelp
3336     (
3337          "0.0 off - otherwise use as absolute increment to cutoff \
3338when solution found in feasibility pump"
3339     );
3340     parameters[numberParameters++] =
3341          CbcOrClpParam("pumpT!une", "Dubious ideas for feasibility pump",
3342                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE);
3343     parameters[numberParameters-1].setLonghelp
3344     (
3345          "This fine tunes Feasibility Pump \n\
3346\t>=10000000 use as objective weight switch\n\
3347\t>=1000000 use as accumulate switch\n\
3348\t>=1000 use index+1 as number of large loops\n\
3349\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\
3350\t%100 == 10,20 affects how each solve is done\n\
3351\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \
3352If accumulate is on then after a major pass, variables which have not moved \
3353are fixed and a small branch and bound is tried."
3354     );
3355     parameters[numberParameters-1].setIntValue(0);
3356#endif
3357     parameters[numberParameters++] =
3358          CbcOrClpParam("quit", "Stops clp execution",
3359                        CLP_PARAM_ACTION_EXIT);
3360     parameters[numberParameters-1].setLonghelp
3361     (
3362          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3363     );
3364#ifdef COIN_HAS_CBC
3365     parameters[numberParameters++] =
3366          CbcOrClpParam("randomC!bcSeed", "Random seed for Cbc",
3367                        -1, COIN_INT_MAX, CBC_PARAM_INT_RANDOMSEED);
3368     parameters[numberParameters-1].setLonghelp
3369     (
3370          "This sets a random seed for Cbc \
3371- 0 says use time of day, -1 is as now."
3372     );
3373     parameters[numberParameters-1].setIntValue(-1);
3374     parameters[numberParameters++] =
3375          CbcOrClpParam("randomi!zedRounding", "Whether to try randomized rounding heuristic",
3376                        "off", CBC_PARAM_STR_RANDROUND);
3377     parameters[numberParameters-1].append("on");
3378     parameters[numberParameters-1].append("both");
3379     parameters[numberParameters-1].append("before");
3380     parameters[numberParameters-1].setLonghelp
3381     (
3382          "stuff needed. \
3383Doh option does heuristic before preprocessing"     );
3384#endif
3385#ifdef COIN_HAS_CLP
3386     parameters[numberParameters++] =
3387          CbcOrClpParam("randomS!eed", "Random seed for Clp",
3388                        0, COIN_INT_MAX, CLP_PARAM_INT_RANDOMSEED);
3389     parameters[numberParameters-1].setLonghelp
3390     (
3391          "This sets a random seed for Clp \
3392- 0 says use time of day."
3393     );
3394     parameters[numberParameters-1].setIntValue(1234567);
3395#endif
3396#ifdef COIN_HAS_CBC
3397     parameters[numberParameters++] =
3398          CbcOrClpParam("ratio!Gap", "Stop when gap between best possible and \
3399best less than this fraction of larger of two",
3400                        0.0, 1.0e20, CBC_PARAM_DBL_GAPRATIO);
3401     parameters[numberParameters-1].setDoubleValue(0.0);
3402     parameters[numberParameters-1].setLonghelp
3403     (
3404          "If the gap between best solution and best possible solution is less than this fraction \
3405of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
3406way of using absolute value rather than fraction."
3407     );
3408#endif
3409     parameters[numberParameters++] =
3410          CbcOrClpParam("restoreS!olution", "reads solution from file",
3411                        CLP_PARAM_ACTION_RESTORESOL);
3412     parameters[numberParameters-1].setLonghelp
3413     (
3414          "This will read a binary solution file from the given file name.  It will use the default\
3415 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3416 is initialized to 'solution.file'.  This reads in a file from saveSolution"
3417     );
3418#ifdef COIN_HAS_CBC
3419     parameters[numberParameters++] =
3420          CbcOrClpParam("readSt!ored", "Import stored cuts from file",
3421                        CLP_PARAM_ACTION_STOREDFILE, 3, 0);
3422#endif
3423#ifdef COIN_HAS_CLP
3424     parameters[numberParameters++] =
3425          CbcOrClpParam("reallyO!bjectiveScale", "Scale factor to apply to objective in place",
3426                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE2, 0);
3427     parameters[numberParameters-1].setLonghelp
3428     (
3429          "You can set this to -1.0 to test maximization or other to stress code"
3430     );
3431     parameters[numberParameters-1].setDoubleValue(1.0);
3432     parameters[numberParameters++] =
3433          CbcOrClpParam("reallyS!cale", "Scales model in place",
3434                        CLP_PARAM_ACTION_REALLY_SCALE, 7, 0);
3435#endif
3436#ifdef COIN_HAS_CBC
3437     parameters[numberParameters++] =
3438          CbcOrClpParam("reduce!AndSplitCuts", "Whether to use Reduce-and-Split cuts",
3439                        "off", CBC_PARAM_STR_REDSPLITCUTS);
3440     parameters[numberParameters-1].append("on");
3441     parameters[numberParameters-1].append("root");
3442     parameters[numberParameters-1].append("ifmove");
3443     parameters[numberParameters-1].append("forceOn");
3444     parameters[numberParameters-1].setLonghelp
3445     (
3446          "This switches on reduce and split  cuts (either at root or in entire tree). \
3447May be slow \
3448See branchAndCut for information on options."
3449     );
3450      parameters[numberParameters++] =
3451          CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2",
3452                        "off", CBC_PARAM_STR_REDSPLIT2CUTS);
3453     parameters[numberParameters-1].append("on");
3454     parameters[numberParameters-1].append("root");
3455     parameters[numberParameters-1].append("longOn");
3456     parameters[numberParameters-1].append("longRoot");
3457     parameters[numberParameters-1].setLonghelp
3458     (
3459          "This switches on reduce and split  cuts (either at root or in entire tree) \
3460This version is by Giacomo Nannicini based on Francois Margot's version \
3461Standard setting only uses rows in tableau <=256, long uses all \
3462May be slow \
3463See branchAndCut for information on options."
3464     );
3465     parameters[numberParameters++] =
3466          CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2",
3467                        "off", CBC_PARAM_STR_REDSPLIT2CUTS);
3468     parameters[numberParameters-1].append("on");
3469     parameters[numberParameters-1].append("root");
3470     parameters[numberParameters-1].append("longOn");
3471     parameters[numberParameters-1].append("longRoot");
3472     parameters[numberParameters-1].setLonghelp
3473     (
3474          "This switches on reduce and split  cuts (either at root or in entire tree) \
3475This version is by Giacomo Nannicini based on Francois Margot's version \
3476Standard setting only uses rows in tableau <=256, long uses all \
3477See branchAndCut for information on options."
3478     );
3479     parameters[numberParameters++] =
3480          CbcOrClpParam("residual!CapacityCuts", "Whether to use Residual Capacity cuts",
3481                        "off", CBC_PARAM_STR_RESIDCUTS);
3482     parameters[numberParameters-1].append("on");
3483     parameters[numberParameters-1].append("root");
3484     parameters[numberParameters-1].append("ifmove");
3485     parameters[numberParameters-1].append("forceOn");
3486     parameters[numberParameters-1].setLonghelp
3487     (
3488          "Residual capacity cuts. \
3489See branchAndCut for information on options."
3490     );
3491#endif
3492#ifdef COIN_HAS_CLP
3493     parameters[numberParameters++] =
3494          CbcOrClpParam("restore!Model", "Restore model from binary file",
3495                        CLP_PARAM_ACTION_RESTORE, 7, 1);
3496     parameters[numberParameters-1].setLonghelp
3497     (
3498          "This reads data save by saveModel from the given file.  It will use the default\
3499 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3500 is initialized to 'default.prob'."
3501     );
3502     parameters[numberParameters++] =
3503          CbcOrClpParam("reverse", "Reverses sign of objective",
3504                        CLP_PARAM_ACTION_REVERSE, 7, 0);
3505     parameters[numberParameters-1].setLonghelp
3506     (
3507          "Useful for testing if maximization works correctly"
3508     );
3509     parameters[numberParameters++] =
3510          CbcOrClpParam("rhs!Scale", "Scale factor to apply to rhs and bounds",
3511                        -1.0e20, 1.0e20, CLP_PARAM_DBL_RHSSCALE, 0);
3512     parameters[numberParameters-1].setLonghelp
3513     (
3514          "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
3515 internally by this amount.  It can also be set by autoscale.  This should not be needed."
3516     );
3517     parameters[numberParameters-1].setDoubleValue(1.0);
3518#endif
3519#ifdef COIN_HAS_CBC
3520     parameters[numberParameters++] =
3521          CbcOrClpParam("Rens", "Whether to try Relaxation Enforced Neighborhood Search",
3522                        "off", CBC_PARAM_STR_RENS);
3523     parameters[numberParameters-1].append("on");
3524     parameters[numberParameters-1].append("both");
3525     parameters[numberParameters-1].append("before");
3526     parameters[numberParameters-1].append("200");
3527     parameters[numberParameters-1].append("1000");
3528     parameters[numberParameters-1].append("10000");
3529     parameters[numberParameters-1].append("dj");
3530     parameters[numberParameters-1].append("djbefore");
3531     parameters[numberParameters-1].append("usesolution");
3532     parameters[numberParameters-1].setLonghelp
3533     (
3534          "This switches on Relaxation enforced neighborhood Search. \
3535on just does 50 nodes \
3536200 or 1000 does that many nodes. \
3537Doh option does heuristic before preprocessing"     );
3538     parameters[numberParameters++] =
3539          CbcOrClpParam("Rins", "Whether to try Relaxed Induced Neighborhood Search",
3540                        "off", CBC_PARAM_STR_RINS);
3541     parameters[numberParameters-1].append("on");
3542     parameters[numberParameters-1].append("both");
3543     parameters[numberParameters-1].append("before");
3544     parameters[numberParameters-1].append("often");
3545     parameters[numberParameters-1].setLonghelp
3546     (
3547          "This switches on Relaxed induced neighborhood Search. \
3548Doh option does heuristic before preprocessing"     );
3549     parameters[numberParameters++] =
3550          CbcOrClpParam("round!ingHeuristic", "Whether to use Rounding heuristic",
3551                        "off", CBC_PARAM_STR_ROUNDING);
3552     parameters[numberParameters-1].append("on");
3553     parameters[numberParameters-1].append("both");
3554     parameters[numberParameters-1].append("before");
3555     parameters[numberParameters-1].setLonghelp
3556     (
3557          "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
3558On means do in solve i.e. after preprocessing, \
3559Before means do if doHeuristics used, off otherwise, \
3560and both means do if doHeuristics and in solve."
3561     );
3562
3563#endif
3564     parameters[numberParameters++] =
3565          CbcOrClpParam("saveM!odel", "Save model to binary file",
3566                        CLP_PARAM_ACTION_SAVE, 7, 1);
3567     parameters[numberParameters-1].setLonghelp
3568     (
3569          "This will save the problem to the given file name for future use\
3570 by restoreModel.  It will use the default\
3571 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3572 is initialized to 'default.prob'."
3573     );
3574     parameters[numberParameters++] =
3575          CbcOrClpParam("saveS!olution", "saves solution to file",
3576                        CLP_PARAM_ACTION_SAVESOL);
3577     parameters[numberParameters-1].setLonghelp
3578     (
3579          "This will write a binary solution file to the given file name.  It will use the default\
3580 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3581 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
3582and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
3583activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
3584If name contains '_fix_read_' then does not write but reads and will fix all variables"
3585     );
3586     parameters[numberParameters++] =
3587          CbcOrClpParam("scal!ing", "Whether to scale problem",
3588                        "off", CLP_PARAM_STR_SCALING);
3589     parameters[numberParameters-1].append("equi!librium");
3590     parameters[numberParameters-1].append("geo!metric");
3591     parameters[numberParameters-1].append("auto!matic");
3592     parameters[numberParameters-1].append("dynamic");
3593     parameters[numberParameters-1].append("rows!only");
3594     parameters[numberParameters-1].setLonghelp
3595     (
3596          "Scaling can help in solving problems which might otherwise fail because of lack of\
3597 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
3598 of elements is small.  When unscaled it is possible that there may be small primal and/or\
3599 infeasibilities."
3600     );
3601     parameters[numberParameters-1].setCurrentOption(3); // say auto
3602#ifndef COIN_HAS_CBC
3603     parameters[numberParameters++] =
3604          CbcOrClpParam("sec!onds", "Maximum seconds",
3605                        -1.0, 1.0e12, CLP_PARAM_DBL_TIMELIMIT);
3606     parameters[numberParameters-1].setLonghelp
3607     (
3608          "After this many seconds clp will act as if maximum iterations had been reached \
3609(if value >=0)."
3610     );
3611#else
3612     parameters[numberParameters++] =
3613          CbcOrClpParam("sec!onds", "maximum seconds",
3614                        -1.0, 1.0e12, CBC_PARAM_DBL_TIMELIMIT_BAB);
3615     parameters[numberParameters-1].setLonghelp
3616     (
3617          "After this many seconds coin solver will act as if maximum nodes had been reached."
3618     );
3619#endif
3620     parameters[numberParameters++] =
3621          CbcOrClpParam("sleep", "for debug",
3622                        CLP_PARAM_ACTION_DUMMY, 7, 0);
3623     parameters[numberParameters-1].setLonghelp
3624     (
3625          "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
3626     );
3627#ifdef COIN_HAS_CBC
3628     parameters[numberParameters++] =
3629          CbcOrClpParam("slow!cutpasses", "Maximum number of tries for slower cuts",
3630                        -1, COIN_INT_MAX, CBC_PARAM_INT_MAX_SLOW_CUTS);
3631     parameters[numberParameters-1].setLonghelp
3632     (
3633          "Some cut generators are fairly slow - this limits the number of times they are tried."
3634     );
3635     parameters[numberParameters-1].setIntValue(10);
3636#endif
3637#ifdef COIN_HAS_CLP
3638     parameters[numberParameters++] =
3639          CbcOrClpParam("slp!Value", "Number of slp passes before primal",
3640                        -50000, 50000, CLP_PARAM_INT_SLPVALUE, 1);
3641     parameters[numberParameters-1].setLonghelp
3642     (
3643          "If you are solving a quadratic problem using primal then it may be helpful to do some \
3644sequential Lps to get a good approximate solution."
3645     );
3646#if CLP_MULTIPLE_FACTORIZATIONS > 0
3647     parameters[numberParameters++] =
3648          CbcOrClpParam("small!Factorization", "Whether to use small factorization",
3649                        -1, 10000, CBC_PARAM_INT_SMALLFACT, 1);
3650     parameters[numberParameters-1].setLonghelp
3651     (
3652          "If processed problem <= this use small factorization"
3653     );
3654     parameters[numberParameters-1].setIntValue(-1);
3655#endif
3656#endif
3657     parameters[numberParameters++] =
3658          CbcOrClpParam("solu!tion", "Prints solution to file",
3659                        CLP_PARAM_ACTION_SOLUTION);
3660     parameters[numberParameters-1].setLonghelp
3661     (
3662          "This will write a primitive solution file to the given file name.  It will use the default\
3663 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3664 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
3665     );
3666#ifdef COIN_HAS_CLP
3667#ifdef COIN_HAS_CBC
3668     parameters[numberParameters++] =
3669          CbcOrClpParam("solv!e", "Solve problem",
3670                        CBC_PARAM_ACTION_BAB);
3671     parameters[numberParameters-1].setLonghelp
3672     (
3673          "If there are no integer variables then this just solves LP.  If there are integer variables \
3674this does branch and cut."
3675     );
3676     parameters[numberParameters++] =
3677          CbcOrClpParam("sos!Options", "Whether to use SOS from AMPL",
3678                        "off", CBC_PARAM_STR_SOS);
3679     parameters[numberParameters-1].append("on");
3680     parameters[numberParameters-1].setCurrentOption("on");
3681     parameters[numberParameters-1].setLonghelp
3682     (
3683          "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
3684 be turned off - this does so."
3685     );
3686     parameters[numberParameters++] =
3687          CbcOrClpParam("slog!Level", "Level of detail in (LP) Solver output",
3688                        -1, 63, CLP_PARAM_INT_SOLVERLOGLEVEL);
3689     parameters[numberParameters-1].setLonghelp
3690     (
3691          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
3692 value for most uses, while 2 and 3 give more information.  This parameter is only used inside MIP - for Clp use 'log'"
3693     );
3694#else
3695     // allow solve as synonym for possible dual
3696     parameters[numberParameters++] =
3697       CbcOrClpParam("solv!e", "Solve problem using dual simplex (probably)",
3698                        CLP_PARAM_ACTION_EITHERSIMPLEX);
3699     parameters[numberParameters-1].setLonghelp
3700     (
3701          "Just so can use solve for clp as well as in cbc"
3702     );
3703#endif
3704#endif
3705#ifdef COIN_HAS_CLP
3706     parameters[numberParameters++] =
3707          CbcOrClpParam("spars!eFactor", "Whether factorization treated as sparse",
3708                        "on", CLP_PARAM_STR_SPARSEFACTOR, 7, 0);
3709     parameters[numberParameters-1].append("off");
3710     parameters[numberParameters++] =
3711          CbcOrClpParam("special!Options", "Dubious options for Simplex - see ClpSimplex.hpp",
3712                        0, COIN_INT_MAX, CLP_PARAM_INT_SPECIALOPTIONS, 0);
3713     parameters[numberParameters++] =
3714          CbcOrClpParam("sprint!Crash", "Whether to try sprint crash",
3715                        -1, 5000000, CLP_PARAM_INT_SPRINT);
3716     parameters[numberParameters-1].setLonghelp
3717     (
3718          "For long and thin problems this program may solve a series of small problems\
3719 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
3720 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
3721  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
3722     );
3723     parameters[numberParameters++] =
3724          CbcOrClpParam("stat!istics", "Print some statistics",
3725                        CLP_PARAM_ACTION_STATISTICS);
3726     parameters[numberParameters-1].setLonghelp
3727     (
3728          "This command prints some statistics for the current model.\
3729 If log level >1 then more is printed.\
3730 These are for presolved model if presolve on (and unscaled)."
3731     );
3732#endif
3733     parameters[numberParameters++] =
3734          CbcOrClpParam("stop", "Stops clp execution",
3735                        CLP_PARAM_ACTION_EXIT);
3736     parameters[numberParameters-1].setLonghelp
3737     (
3738          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3739     );
3740#ifdef COIN_HAS_CBC
3741     parameters[numberParameters++] =
3742          CbcOrClpParam("strat!egy", "Switches on groups of features",
3743                        0, 2, CBC_PARAM_INT_STRATEGY);
3744     parameters[numberParameters-1].setLonghelp
3745     (
3746          "This turns on newer features. \
3747Use 0 for easy problems, 1 is default, 2 is aggressive. \
37481 uses Gomory cuts using tolerance of 0.01 at root, \
3749does a possible restart after 100 nodes if can fix many \
3750and activates a diving and RINS heuristic and makes feasibility pump \
3751more aggressive. \
3752This does not apply to unit tests (where 'experiment' may have similar effects)."
3753     );
3754     parameters[numberParameters-1].setIntValue(1);
3755#ifdef CBC_KEEP_DEPRECATED
3756     parameters[numberParameters++] =
3757          CbcOrClpParam("strengthen", "Create strengthened problem",
3758                        CBC_PARAM_ACTION_STRENGTHEN, 3);
3759     parameters[numberParameters-1].setLonghelp
3760     (
3761          "This creates a new problem by applying the root node cuts.  All tight constraints \
3762will be in resulting problem"
3763     );
3764#endif
3765     parameters[numberParameters++] =
3766          CbcOrClpParam("strong!Branching", "Number of variables to look at in strong branching",
3767                        0, COIN_INT_MAX, CBC_PARAM_INT_STRONGBRANCHING);
3768     parameters[numberParameters-1].setLonghelp
3769     (
3770          "In order to decide which variable to branch on, the code will choose up to this number \
3771of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
3772If a variable is branched on many times then the previous average up and down costs may be used - \
3773see number before trust."
3774     );
3775#endif
3776#ifdef COIN_HAS_CLP
3777     parameters[numberParameters++] =
3778          CbcOrClpParam("subs!titution", "How long a column to substitute for in presolve",
3779                        0, 10000, CLP_PARAM_INT_SUBSTITUTION, 0);
3780     parameters[numberParameters-1].setLonghelp
3781     (
3782          "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
3783 variables in column.  If you increase this the number of rows may decrease but number of \
3784 elements may increase."
3785     );
3786#endif
3787#ifdef COIN_HAS_CBC
3788     parameters[numberParameters++] =
3789          CbcOrClpParam("testO!si", "Test OsiObject stuff",
3790                        -1, COIN_INT_MAX, CBC_PARAM_INT_TESTOSI, 0);
3791#endif
3792#ifdef CBC_THREAD
3793     parameters[numberParameters++] =
3794          CbcOrClpParam("thread!s", "Number of threads to try and use",
3795                        -100, 100000, CBC_PARAM_INT_THREADS, 1);
3796     parameters[numberParameters-1].setLonghelp
3797     (
3798          "To use multiple threads, set threads to number wanted.  It may be better \
3799to use one or two more than number of cpus available.  If 100+n then n threads and \
3800search is repeatable (maybe be somewhat slower), \
3801if 200+n use threads for root cuts, 400+n threads used in sub-trees."
3802     );
3803#endif
3804#ifdef COIN_HAS_CBC
3805     parameters[numberParameters++] =
3806          CbcOrClpParam("tighten!Factor", "Tighten bounds using this times largest \
3807activity at continuous solution",
3808                        1.0e-3, 1.0e20, CBC_PARAM_DBL_TIGHTENFACTOR, 0);
3809     parameters[numberParameters-1].setLonghelp
3810     (
3811          "This sleazy trick can help on some problems."
3812     );
3813#endif
3814#ifdef COIN_HAS_CLP
3815     parameters[numberParameters++] =
3816          CbcOrClpParam("tightLP", "Poor person's preSolve for now",
3817                        CLP_PARAM_ACTION_TIGHTEN, 7, 0);
3818#endif
3819     parameters[numberParameters++] =
3820          CbcOrClpParam("timeM!ode", "Whether to use CPU or elapsed time",
3821                        "cpu", CLP_PARAM_STR_TIME_MODE);
3822     parameters[numberParameters-1].append("elapsed");
3823     parameters[numberParameters-1].setLonghelp
3824     (
3825          "cpu uses CPU time for stopping, while elapsed uses elapsed time. \
3826(On Windows, elapsed time is always used)."
3827     );
3828#ifdef COIN_HAS_CBC
3829     parameters[numberParameters++] =
3830          CbcOrClpParam("trust!PseudoCosts", "Number of branches before we trust pseudocosts",
3831                        -3, 2000000000, CBC_PARAM_INT_NUMBERBEFORE);
3832     parameters[numberParameters-1].setLonghelp
3833     (
3834          "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
3835trust the pseudo costs and do not do any more strong branching."
3836     );
3837#endif
3838#ifdef COIN_HAS_CBC
3839     parameters[numberParameters++] =
3840          CbcOrClpParam("tune!PreProcess", "Dubious tuning parameters",
3841                        0, 2000000000, CLP_PARAM_INT_PROCESSTUNE, 1);
3842     parameters[numberParameters-1].setLonghelp
3843     (
3844          "Format aabbcccc - \n If aa then this is number of major passes (i.e. with presolve) \n \
3845If bb and bb>0 then this is number of minor passes (if unset or 0 then 10) \n \
3846cccc is bit set \n 0 - 1 Heavy probing \n 1 - 2 Make variables integer if possible (if obj value)\n \
38472 - 4 As above but even if zero objective value\n \
38487 - 128 Try and create cliques\n 8 - 256 If all +1 try hard for dominated rows\n \
384910 - 1024 Use a larger feasibility tolerance in presolve\n \
385011 - 2048 Try probing before creating cliques"
3851     );
3852     parameters[numberParameters++] =
3853          CbcOrClpParam("two!MirCuts", "Whether to use Two phase Mixed Integer Rounding cuts",
3854                        "off", CBC_PARAM_STR_TWOMIRCUTS);
3855     parameters[numberParameters-1].append("on");
3856     parameters[numberParameters-1].append("root");
3857     parameters[numberParameters-1].append("ifmove");
3858     parameters[numberParameters-1].append("forceOn");
3859     parameters[numberParameters-1].append("onglobal");
3860     parameters[numberParameters-1].append("forceandglobal");
3861     parameters[numberParameters-1].append("forceLongOn");
3862     parameters[numberParameters-1].setLonghelp
3863     (
3864          "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
3865See branchAndCut for information on options."
3866     );
3867#endif
3868     parameters[numberParameters++] =
3869          CbcOrClpParam("unitTest", "Do unit test",
3870                        CLP_PARAM_ACTION_UNITTEST, 3, 1);
3871     parameters[numberParameters-1].setLonghelp
3872     (
3873          "This exercises the unit test for clp"
3874     );
3875     parameters[numberParameters++] =
3876          CbcOrClpParam("userClp", "Hand coded Clp stuff",
3877                        CLP_PARAM_ACTION_USERCLP, 0, 0);
3878     parameters[numberParameters-1].setLonghelp
3879     (
3880          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3881Look for USERCLP in main driver and modify sample code."
3882     );
3883#ifdef COIN_HAS_CBC
3884     parameters[numberParameters++] =
3885          CbcOrClpParam("userCbc", "Hand coded Cbc stuff",
3886                        CBC_PARAM_ACTION_USERCBC, 0, 0);
3887     parameters[numberParameters-1].setLonghelp
3888     (
3889          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3890Look for USERCBC in main driver and modify sample code. \
3891It is possible you can get same effect by using example driver4.cpp."
3892     );
3893     parameters[numberParameters++] =
3894          CbcOrClpParam("Vnd!VariableNeighborhoodSearch", "Whether to try Variable Neighborhood Search",
3895                        "off", CBC_PARAM_STR_VND);
3896     parameters[numberParameters-1].append("on");
3897     parameters[numberParameters-1].append("both");
3898     parameters[numberParameters-1].append("before");
3899     parameters[numberParameters-1].append("intree");
3900     parameters[numberParameters-1].setLonghelp
3901     (
3902          "This switches on variable neighborhood Search. \
3903Doh option does heuristic before preprocessing"     );
3904#endif
3905     parameters[numberParameters++] =
3906          CbcOrClpParam("vector", "Whether to use vector? Form of matrix in simplex",
3907                        "off", CLP_PARAM_STR_VECTOR, 7, 0);
3908     parameters[numberParameters-1].append("on");
3909     parameters[numberParameters-1].setLonghelp
3910     (
3911          "If this is on ClpPackedMatrix uses extra column copy in odd format."
3912     );
3913     parameters[numberParameters++] =
3914          CbcOrClpParam("verbose", "Switches on longer help on single ?",
3915                        0, 31, CLP_PARAM_INT_VERBOSE, 0);
3916     parameters[numberParameters-1].setLonghelp
3917     (
3918          "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
3919     );
3920     parameters[numberParameters-1].setIntValue(0);
3921#ifdef COIN_HAS_CBC
3922     parameters[numberParameters++] =
3923          CbcOrClpParam("vub!heuristic", "Type of vub heuristic",
3924                        -2, 20, CBC_PARAM_INT_VUBTRY, 0);
3925     parameters[numberParameters-1].setLonghelp
3926     (
3927          "If set will try and fix some integer variables"
3928     );
3929     parameters[numberParameters-1].setIntValue(-1);
3930     parameters[numberParameters++] =
3931          CbcOrClpParam("zero!HalfCuts", "Whether to use zero half cuts",
3932                        "off", CBC_PARAM_STR_ZEROHALFCUTS);
3933     parameters[numberParameters-1].append("on");
3934     parameters[numberParameters-1].append("root");
3935     parameters[numberParameters-1].append("ifmove");
3936     parameters[numberParameters-1].append("forceOn");
3937     parameters[numberParameters-1].append("onglobal");
3938     parameters[numberParameters-1].setLonghelp
3939     (
3940          "This switches on zero-half cuts (either at root or in entire tree) \
3941See branchAndCut for information on options.  This implementation was written by \
3942Alberto Caprara."
3943     );
3944#endif
3945     parameters[numberParameters++] =
3946          CbcOrClpParam("zeroT!olerance", "Kill all coefficients \
3947whose absolute value is less than this value",
3948                        1.0e-100, 1.0e-5, CLP_PARAM_DBL_ZEROTOLERANCE);
3949     parameters[numberParameters-1].setLonghelp
3950     (
3951          "This applies to reading mps files (and also lp files \
3952if KILL_ZERO_READLP defined)"
3953     );
3954     parameters[numberParameters-1].setDoubleValue(1.0e-20);
3955     assert(numberParameters < CBCMAXPARAMETERS);
3956}
3957// Given a parameter type - returns its number in list
3958int whichParam (CbcOrClpParameterType name,
3959                int numberParameters, CbcOrClpParam *const parameters)
3960{
3961     int i;
3962     for (i = 0; i < numberParameters; i++) {
3963          if (parameters[i].type() == name)
3964               break;
3965     }
3966     assert (i < numberParameters);
3967     return i;
3968}
3969#ifdef COIN_HAS_CLP
3970/* Restore a solution from file.
3971   mode 0 normal, 1 swap rows and columns and primal and dual
3972   if 2 set then also change signs
3973*/
3974void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode)
3975{
3976     FILE * fp = fopen(fileName.c_str(), "rb");
3977     if (fp) {
3978          int numberRows = lpSolver->numberRows();
3979          int numberColumns = lpSolver->numberColumns();
3980          int numberRowsFile;
3981          int numberColumnsFile;
3982          double objectiveValue;
3983          size_t nRead;
3984          nRead = fread(&numberRowsFile, sizeof(int), 1, fp);
3985          if (nRead != 1)
3986               throw("Error in fread");
3987          nRead = fread(&numberColumnsFile, sizeof(int), 1, fp);
3988          if (nRead != 1)
3989               throw("Error in fread");
3990          nRead = fread(&objectiveValue, sizeof(double), 1, fp);
3991          if (nRead != 1)
3992               throw("Error in fread");
3993          double * dualRowSolution = lpSolver->dualRowSolution();
3994          double * primalRowSolution = lpSolver->primalRowSolution();
3995          double * dualColumnSolution = lpSolver->dualColumnSolution();
3996          double * primalColumnSolution = lpSolver->primalColumnSolution();
3997          if (mode) {
3998               // swap
3999               int k = numberRows;
4000               numberRows = numberColumns;
4001               numberColumns = k;
4002               double * temp;
4003               temp = dualRowSolution;
4004               dualRowSolution = primalColumnSolution;
4005               primalColumnSolution = temp;
4006               temp = dualColumnSolution;
4007               dualColumnSolution = primalRowSolution;
4008               primalRowSolution = temp;
4009          }
4010          if (numberRows > numberRowsFile || numberColumns > numberColumnsFile) {
4011               std::cout << "Mismatch on rows and/or columns - giving up" << std::endl;
4012          } else {
4013               lpSolver->setObjectiveValue(objectiveValue);
4014               if (numberRows == numberRowsFile && numberColumns == numberColumnsFile) {
4015                    nRead = fread(primalRowSolution, sizeof(double), numberRows, fp);
4016                    if (nRead != static_cast<size_t>(numberRows))
4017                         throw("Error in fread");
4018                    nRead = fread(dualRowSolution, sizeof(double), numberRows, fp);
4019                    if (nRead != static_cast<size_t>(numberRows))
4020                         throw("Error in fread");
4021                    nRead = fread(primalColumnSolution, sizeof(double), numberColumns, fp);
4022                    if (nRead != static_cast<size_t>(numberColumns))
4023                         throw("Error in fread");
4024                    nRead = fread(dualColumnSolution, sizeof(double), numberColumns, fp);
4025                    if (nRead != static_cast<size_t>(numberColumns))
4026                         throw("Error in fread");
4027               } else {
4028                    std::cout << "Mismatch on rows and/or columns - truncating" << std::endl;
4029                    double * temp = new double [CoinMax(numberRowsFile, numberColumnsFile)];
4030                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
4031                    if (nRead != static_cast<size_t>(numberRowsFile))
4032                         throw("Error in fread");
4033                    CoinMemcpyN(temp, numberRows, primalRowSolution);
4034                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
4035                    if (nRead != static_cast<size_t>(numberRowsFile))
4036                         throw("Error in fread");
4037                    CoinMemcpyN(temp, numberRows, dualRowSolution);
4038                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
4039                    if (nRead != static_cast<size_t>(numberColumnsFile))
4040                         throw("Error in fread");
4041                    CoinMemcpyN(temp, numberColumns, primalColumnSolution);
4042                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
4043                    if (nRead != static_cast<size_t>(numberColumnsFile))
4044                         throw("Error in fread");
4045                    CoinMemcpyN(temp, numberColumns, dualColumnSolution);
4046                    delete [] temp;
4047                           }
4048               if (mode == 3) {
4049                    int i;
4050                    for (i = 0; i < numberRows; i++) {
4051                         primalRowSolution[i] = -primalRowSolution[i];
4052                         dualRowSolution[i] = -dualRowSolution[i];
4053                    }
4054                    for (i = 0; i < numberColumns; i++) {
4055                         primalColumnSolution[i] = -primalColumnSolution[i];
4056                         dualColumnSolution[i] = -dualColumnSolution[i];
4057                    }
4058               }
4059          }
4060          fclose(fp);
4061     } else {
4062          std::cout << "Unable to open file " << fileName << std::endl;
4063     }
4064}
4065// Dump a solution to file
4066void saveSolution(const ClpSimplex * lpSolver, std::string fileName)
4067{
4068     if (strstr(fileName.c_str(), "_fix_read_")) {
4069          FILE * fp = fopen(fileName.c_str(), "rb");
4070          if (fp) {
4071               ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
4072               restoreSolution(solver, fileName, 0);
4073               // fix all
4074               int logLevel = solver->logLevel();
4075               int iColumn;
4076               int numberColumns = solver->numberColumns();
4077               double * primalColumnSolution =
4078                    solver->primalColumnSolution();
4079               double * columnLower = solver->columnLower();
4080               double * columnUpper = solver->columnUpper();
4081               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
4082                    double value = primalColumnSolution[iColumn];
4083                    if (value > columnUpper[iColumn]) {
4084                         if (value > columnUpper[iColumn] + 1.0e-6 && logLevel > 1)
4085                              printf("%d value of %g - bounds %g %g\n",
4086                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
4087                         value = columnUpper[iColumn];
4088                    } else if (value < columnLower[iColumn]) {
4089                         if (value < columnLower[iColumn] - 1.0e-6 && logLevel > 1)
4090                              printf("%d value of %g - bounds %g %g\n",
4091                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
4092                         value = columnLower[iColumn];
4093                    }
4094                    columnLower[iColumn] = value;
4095                    columnUpper[iColumn] = value;
4096               }
4097               return;
4098          }
4099     }
4100     FILE * fp = fopen(fileName.c_str(), "wb");
4101     if (fp) {
4102          int numberRows = lpSolver->numberRows();
4103          int numberColumns = lpSolver->numberColumns();
4104          double objectiveValue = lpSolver->objectiveValue();
4105          size_t nWrite;
4106          nWrite = fwrite(&numberRows, sizeof(int), 1, fp);
4107          if (nWrite != 1)
4108               throw("Error in fwrite");
4109          nWrite = fwrite(&numberColumns, sizeof(int), 1, fp);
4110          if (nWrite != 1)
4111               throw("Error in fwrite");
4112          nWrite = fwrite(&objectiveValue, sizeof(double), 1, fp);
4113          if (nWrite != 1)
4114               throw("Error in fwrite");
4115          double * dualRowSolution = lpSolver->dualRowSolution();
4116          double * primalRowSolution = lpSolver->primalRowSolution();
4117          nWrite = fwrite(primalRowSolution, sizeof(double), numberRows, fp);
4118          if (nWrite != static_cast<size_t>(numberRows))
4119               throw("Error in fwrite");
4120          nWrite = fwrite(dualRowSolution, sizeof(double), numberRows, fp);
4121          if (nWrite != static_cast<size_t>(numberRows))
4122               throw("Error in fwrite");
4123          double * dualColumnSolution = lpSolver->dualColumnSolution();
4124          double * primalColumnSolution = lpSolver->primalColumnSolution();
4125          nWrite = fwrite(primalColumnSolution, sizeof(double), numberColumns, fp);
4126          if (nWrite != static_cast<size_t>(numberColumns))
4127               throw("Error in fwrite");
4128          nWrite = fwrite(dualColumnSolution, sizeof(double), numberColumns, fp);
4129          if (nWrite != static_cast<size_t>(numberColumns))
4130               throw("Error in fwrite");
4131          fclose(fp);
4132     } else {
4133          std::cout << "Unable to open file " << fileName << std::endl;
4134     }
4135}
4136#endif
Note: See TracBrowser for help on using the repository browser.