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

Last change on this file since 2271 was 2271, checked in by forrest, 21 months ago

change some ints to CoinBigIndex?

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