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

Last change on this file since 2374 was 2374, checked in by forrest, 5 months ago

for debug

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 178.5 KB
Line 
1/* $Id: CbcOrClpParam.cpp 2374 2018-11-23 19:00:33Z 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].append("simple");
2998     parameters[numberParameters-1].setLonghelp
2999     (
3000          "This switches on Orbital branching. \
3001On just adds orbital, strong tries extra fixing in strong branching");
3002#endif
3003     parameters[numberParameters++] =
3004          CbcOrClpParam("PrepN!ames", "If column names will be kept in pre-processed model",
3005                        "off", CBC_PARAM_STR_PREPROCNAMES);
3006     parameters[numberParameters-1].append("on");
3007     parameters[numberParameters-1].setLonghelp
3008     (
3009           "Normally the preprocessed model has column names replaced by new names C0000...\
3010Setting this option to on keeps original names in variables which still exist in the preprocessed problem");
3011
3012     parameters[numberParameters++] =
3013          CbcOrClpParam("outDup!licates", "takes duplicate rows etc out of integer model",
3014                        CLP_PARAM_ACTION_OUTDUPROWS, 7, 0);
3015#endif
3016     parameters[numberParameters++] =
3017          CbcOrClpParam("output!Format", "Which output format to use",
3018                        1, 6, CLP_PARAM_INT_OUTPUTFORMAT);
3019     parameters[numberParameters-1].setLonghelp
3020     (
3021          "Normally export will be done using normal representation for numbers and two values\
3022 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
3023 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
3024 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
3025 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
3026values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
3027     );
3028#ifdef COIN_HAS_CLP
3029     parameters[numberParameters++] =
3030          CbcOrClpParam("para!metrics", "Import data from file and do parametrics",
3031                        CLP_PARAM_ACTION_PARAMETRICS, 3);
3032     parameters[numberParameters-1].setLonghelp
3033     (
3034          "This will read a file with parametric data from the given file name \
3035and then do parametrics.  It will use the default\
3036 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3037 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
3038File is in modified csv format - a line ROWS will be followed by rows data \
3039while a line COLUMNS will be followed by column data.  The last line \
3040should be ENDATA. The ROWS line must exist and is in the format \
3041ROWS, inital theta, final theta, interval theta, n where n is 0 to get \
3042CLPI0062 message at interval or at each change of theta \
3043and 1 to get CLPI0063 message at each iteration.  If interval theta is 0.0 \
3044or >= final theta then no interval reporting.  n may be missed out when it is \
3045taken as 0.  If there is Row data then \
3046there is a headings line with allowed headings - name, number, \
3047lower(rhs change), upper(rhs change), rhs(change).  Either the lower and upper \
3048fields should be given or the rhs field. \
3049The optional COLUMNS line is followed by a headings line with allowed \
3050headings - name, number, objective(change), lower(change), upper(change). \
3051 Exactly one of name and number must be given for either section and \
3052missing ones have value 0.0."
3053     );
3054#endif
3055#ifdef COIN_HAS_CBC
3056     parameters[numberParameters++] =
3057          CbcOrClpParam("passC!uts", "Number of cut passes at root node",
3058                        -9999999, 9999999, CBC_PARAM_INT_CUTPASS);
3059     parameters[numberParameters-1].setLonghelp
3060     (
3061          "The default is 100 passes if less than 500 columns, 100 passes (but \
3062stop if drop small if less than 5000 columns, 20 otherwise"
3063     );
3064     parameters[numberParameters++] =
3065          CbcOrClpParam("passF!easibilityPump", "How many passes in feasibility pump",
3066                        0, 10000, CBC_PARAM_INT_FPUMPITS);
3067     parameters[numberParameters-1].setLonghelp
3068     (
3069          "This fine tunes Feasibility Pump by doing more or fewer passes."
3070     );
3071     parameters[numberParameters-1].setIntValue(20);
3072#endif
3073#ifdef COIN_HAS_CLP
3074     parameters[numberParameters++] =
3075          CbcOrClpParam("passP!resolve", "How many passes in presolve",
3076                        -200, 100, CLP_PARAM_INT_PRESOLVEPASS, 1);
3077     parameters[numberParameters-1].setLonghelp
3078     (
3079          "Normally Presolve does 10 passes but you may want to do less to make it\
3080 more lightweight or do more if improvements are still being made.  As Presolve will return\
3081 if nothing is being taken out, you should not normally need to use this fine tuning."
3082     );
3083#endif
3084#ifdef COIN_HAS_CBC
3085     parameters[numberParameters++] =
3086          CbcOrClpParam("passT!reeCuts", "Number of cut passes in tree",
3087                        -9999999, 9999999, CBC_PARAM_INT_CUTPASSINTREE);
3088     parameters[numberParameters-1].setLonghelp
3089     (
3090          "The default is one pass"
3091     );
3092#endif
3093#ifdef COIN_HAS_CLP
3094     parameters[numberParameters++] =
3095          CbcOrClpParam("pertV!alue", "Method of perturbation",
3096                        -5000, 102, CLP_PARAM_INT_PERTVALUE, 1);
3097     parameters[numberParameters++] =
3098          CbcOrClpParam("perturb!ation", "Whether to perturb problem",
3099                        "on", CLP_PARAM_STR_PERTURBATION);
3100     parameters[numberParameters-1].append("off");
3101     parameters[numberParameters-1].setLonghelp
3102     (
3103          "Perturbation helps to stop cycling, but Clp uses other measures for this.\
3104  However large problems and especially ones with unit elements and unit rhs or costs\
3105 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
3106  The Clp library has this off by default.  This program has it on by default."
3107     );
3108     parameters[numberParameters++] =
3109          CbcOrClpParam("PFI", "Whether to use Product Form of Inverse in simplex",
3110                        "off", CLP_PARAM_STR_PFI, 7, 0);
3111     parameters[numberParameters-1].append("on");
3112     parameters[numberParameters-1].setLonghelp
3113     (
3114          "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
3115     );
3116#endif
3117#ifdef COIN_HAS_CBC
3118     parameters[numberParameters++] =
3119          CbcOrClpParam("pivotAndC!omplement", "Whether to try Pivot and Complement heuristic",
3120                        "off", CBC_PARAM_STR_PIVOTANDCOMPLEMENT);
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     parameters[numberParameters++] =
3129          CbcOrClpParam("pivotAndF!ix", "Whether to try Pivot and Fix heuristic",
3130                        "off", CBC_PARAM_STR_PIVOTANDFIX);
3131     parameters[numberParameters-1].append("on");
3132     parameters[numberParameters-1].append("both");
3133     parameters[numberParameters-1].append("before");
3134     parameters[numberParameters-1].setLonghelp
3135     (
3136          "stuff needed. \
3137Doh option does heuristic before preprocessing"     );
3138#endif
3139#ifdef COIN_HAS_CLP
3140     parameters[numberParameters++] =
3141          CbcOrClpParam("plus!Minus", "Tries to make +- 1 matrix",
3142                        CLP_PARAM_ACTION_PLUSMINUS, 7, 0);
3143     parameters[numberParameters-1].setLonghelp
3144     (
3145          "Clp will go slightly faster if the matrix can be converted so that the elements are\
3146 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
3147 see if it can convert the problem so you should not need to use this."
3148     );
3149     parameters[numberParameters++] =
3150          CbcOrClpParam("pO!ptions", "Dubious print options",
3151                        0, COIN_INT_MAX, CLP_PARAM_INT_PRINTOPTIONS, 1);
3152     parameters[numberParameters-1].setIntValue(0);
3153     parameters[numberParameters-1].setLonghelp
3154     (
3155          "If this is > 0 then presolve will give more information and branch and cut will give statistics"
3156     );
3157     parameters[numberParameters++] =
3158          CbcOrClpParam("preO!pt", "Presolve options",
3159                        0, COIN_INT_MAX, CLP_PARAM_INT_PRESOLVEOPTIONS, 0);
3160#endif
3161     parameters[numberParameters++] =
3162          CbcOrClpParam("presolve", "Whether to presolve problem",
3163                        "on", CLP_PARAM_STR_PRESOLVE);
3164     parameters[numberParameters-1].append("off");
3165     parameters[numberParameters-1].append("more");
3166     parameters[numberParameters-1].append("file");
3167     parameters[numberParameters-1].setLonghelp
3168     (
3169          "Presolve analyzes the model to find such things as redundant equations, equations\
3170 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
3171 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
3172on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
3173to write the original to file using 'file'."
3174     );
3175#ifdef COIN_HAS_CBC
3176     parameters[numberParameters++] =
3177          CbcOrClpParam("preprocess", "Whether to use integer preprocessing",
3178                        "off", CBC_PARAM_STR_PREPROCESS);
3179     parameters[numberParameters-1].append("on");
3180     parameters[numberParameters-1].append("save");
3181     parameters[numberParameters-1].append("equal");
3182     parameters[numberParameters-1].append("sos");
3183     parameters[numberParameters-1].append("trysos");
3184     parameters[numberParameters-1].append("equalall");
3185     parameters[numberParameters-1].append("strategy");
3186     parameters[numberParameters-1].append("aggregate");
3187     parameters[numberParameters-1].append("forcesos");
3188     parameters[numberParameters-1].append("stop!aftersaving");
3189     parameters[numberParameters-1].setLonghelp
3190     (
3191          "This tries to reduce size of model in a similar way to presolve and \
3192it also tries to strengthen the model - this can be very useful and is worth trying. \
3193 Save option saves on file presolved.mps.  equal will turn <= cliques into \
3194==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
3195and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
3196valid inequalities into equalities with integer slacks.  strategy is as \
3197on but uses CbcStrategy."
3198     );
3199#endif
3200#ifdef COIN_HAS_CLP
3201     parameters[numberParameters++] =
3202          CbcOrClpParam("preT!olerance", "Tolerance to use in presolve",
3203                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRESOLVETOLERANCE);
3204     parameters[numberParameters-1].setLonghelp
3205     (
3206          "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
3207infeasible and you have awkward numbers and you are sure the problem is really feasible."
3208     );
3209     parameters[numberParameters++] =
3210          CbcOrClpParam("primalP!ivot", "Primal pivot choice algorithm",
3211                        "auto!matic", CLP_PARAM_STR_PRIMALPIVOT, 7, 1);
3212     parameters[numberParameters-1].append("exa!ct");
3213     parameters[numberParameters-1].append("dant!zig");
3214     parameters[numberParameters-1].append("part!ial");
3215     parameters[numberParameters-1].append("steep!est");
3216     parameters[numberParameters-1].append("change");
3217     parameters[numberParameters-1].append("sprint");
3218     parameters[numberParameters-1].append("PEsteep!est");
3219     parameters[numberParameters-1].append("PEdantzig");
3220     parameters[numberParameters-1].setLonghelp
3221     (
3222          "Clp can use any pivot selection algorithm which the user codes as long as it\
3223 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
3224 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
3225 are two variants which keep all weights updated but only scan a subset each iteration.\
3226 Partial switches this on while change initially does dantzig until the factorization\
3227 becomes denser.  This is still a work in progress. \n\
3228** NEWS - the Positive Edge criterion has been added. \
3229This selects incoming variables to try and avoid degenerate moves. Code \
3230donated by Jeremy Omer.  See \
3231Towhidi, M., Desrosiers, J., Soumis, F., The positive edge criterion within COIN-OR’s CLP. and \
3232Omer, J., Towhidi, M., Soumis, F., The positive edge pricing rule for the dual simplex."
3233     );
3234     parameters[numberParameters++] =
3235          CbcOrClpParam("primalS!implex", "Do primal simplex algorithm",
3236                        CLP_PARAM_ACTION_PRIMALSIMPLEX);
3237     parameters[numberParameters-1].setLonghelp
3238     (
3239          "This command solves the continuous relaxation of the current model using the primal algorithm.\
3240  The default is to use exact devex.\
3241 The time and iterations may be affected by settings such as presolve, scaling, crash\
3242 and also by column selection  method, infeasibility weight and dual and primal tolerances."
3243     );
3244#endif
3245     parameters[numberParameters++] =
3246          CbcOrClpParam("primalT!olerance", "For an optimal solution \
3247no primal infeasibility may exceed this value",
3248                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRIMALTOLERANCE);
3249     parameters[numberParameters-1].setLonghelp
3250     (
3251          "Normally the default tolerance is fine, but you may want to increase it a\
3252 bit if a primal run seems to be having a hard time"
3253     );
3254#ifdef COIN_HAS_CLP
3255     parameters[numberParameters++] =
3256          CbcOrClpParam("primalW!eight", "Initially algorithm acts as if it \
3257costs this much to be infeasible",
3258                        1.0e-20, 1.0e20, CLP_PARAM_DBL_PRIMALWEIGHT);
3259     parameters[numberParameters-1].setLonghelp
3260     (
3261          "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
3262 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
3263 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
3264  Too high a value may mean more iterations, while too low a bound means\
3265 the code may go all the way and then have to increase the weight in order to get feasible.\
3266  OSL had a heuristic to\
3267 adjust bounds, maybe we need that here."
3268     );
3269     parameters[numberParameters++] =
3270          CbcOrClpParam("psi", "Two-dimension pricing factor for Positive edge",
3271                        -1.1, 1.1, CLP_PARAM_DBL_PSI);
3272     parameters[numberParameters-1].setDoubleValue(-0.5);
3273     parameters[numberParameters-1].setLonghelp
3274     (
3275          "The Positive Edge criterion has been added to \
3276select incoming variables to try and avoid degenerate moves. \
3277Variables not in promising set have their infeasibility weight multiplied by psi \
3278so 0.01 would mean that if there were any promising variables, then they would always be chosen, \
3279while 1.0 effectively switches algorithm off. \
3280There are two ways of switching on this feature.  One way is to set psi positive and then \
3281the Positive Edge criterion will be used for Primal and Dual.  The other way is to select pesteep \
3282in dualpivot choice (for example), then the absolute value of psi is used - default 0.5. \
3283Until this settles down it is only implemented in clp. \
3284Code donated by Jeremy Omer.  See \
3285Towhidi, M., Desrosiers, J., Soumis, F., The positive edge criterion within COIN-OR’s CLP. and \
3286Omer, J., Towhidi, M., Soumis, F., The positive edge pricing rule for the dual simplex."
3287     );
3288#endif
3289     parameters[numberParameters++] =
3290          CbcOrClpParam("printi!ngOptions", "Print options",
3291                        "normal", CLP_PARAM_STR_INTPRINT, 3);
3292     parameters[numberParameters-1].append("integer");
3293     parameters[numberParameters-1].append("special");
3294     parameters[numberParameters-1].append("rows");
3295     parameters[numberParameters-1].append("all");
3296     parameters[numberParameters-1].append("csv");
3297     parameters[numberParameters-1].append("bound!ranging");
3298     parameters[numberParameters-1].append("rhs!ranging");
3299     parameters[numberParameters-1].append("objective!ranging");
3300     parameters[numberParameters-1].append("stats");
3301     parameters[numberParameters-1].append("boundsint");
3302     parameters[numberParameters-1].append("boundsall");
3303     parameters[numberParameters-1].setLonghelp
3304     (
3305          "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
3306integer - nonzero integer column variables\n\
3307special - in format suitable for OsiRowCutDebugger\n\
3308rows - nonzero column variables and row activities\n\
3309all - all column variables and row activities.\n\
3310\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
3311Also see printMask for controlling output."
3312     );
3313     parameters[numberParameters++] =
3314          CbcOrClpParam("printM!ask", "Control printing of solution on a  mask",
3315                        CLP_PARAM_ACTION_PRINTMASK, 3);
3316     parameters[numberParameters-1].setLonghelp
3317     (
3318          "If set then only those names which match mask are printed in a solution. \
3319'?' matches any character and '*' matches any set of characters. \
3320 The default is '' i.e. unset so all variables are printed. \
3321This is only active if model has names."
3322     );
3323#ifdef COIN_HAS_CBC
3324     parameters[numberParameters++] =
3325          CbcOrClpParam("prio!rityIn", "Import priorities etc from file",
3326                        CBC_PARAM_ACTION_PRIORITYIN, 3);
3327     parameters[numberParameters-1].setLonghelp
3328     (
3329          "This will read a file with priorities from the given file name.  It will use the default\
3330 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3331 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
3332File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
3333 name and number must be given."
3334     );
3335     parameters[numberParameters++] =
3336          CbcOrClpParam("probing!Cuts", "Whether to use Probing cuts",
3337                        "off", CBC_PARAM_STR_PROBINGCUTS);
3338     parameters[numberParameters-1].append("on");
3339     parameters[numberParameters-1].append("root");
3340     parameters[numberParameters-1].append("ifmove");
3341     parameters[numberParameters-1].append("forceOn");
3342     parameters[numberParameters-1].append("onglobal");
3343     parameters[numberParameters-1].append("forceonglobal");
3344     parameters[numberParameters-1].append("forceOnBut");
3345     parameters[numberParameters-1].append("forceOnStrong");
3346     parameters[numberParameters-1].append("forceOnButStrong");
3347     parameters[numberParameters-1].append("strongRoot");
3348     parameters[numberParameters-1].setLonghelp
3349     (
3350          "This switches on probing cuts (either at root or in entire tree) \
3351See branchAndCut for information on options. \
3352but strong options do more probing"
3353     );
3354     parameters[numberParameters++] =
3355          CbcOrClpParam("proximity!Search", "Whether to do proximity search heuristic",
3356                        "off", CBC_PARAM_STR_PROXIMITY);
3357     parameters[numberParameters-1].append("on");
3358     parameters[numberParameters-1].append("both");
3359     parameters[numberParameters-1].append("before");
3360     parameters[numberParameters-1].append("10");
3361     parameters[numberParameters-1].append("100");
3362     parameters[numberParameters-1].append("300");
3363     // but allow numbers after this (returning 1)
3364     parameters[numberParameters-1].setFakeKeyWord(1);
3365     parameters[numberParameters-1].setLonghelp
3366     (
3367          "This switches on a heuristic which looks for a solution close \
3368to incumbent solution (Fischetti and Monaci). \
3369See Rounding for meaning of on,both,before. \
3370Can also set different maxNode settings by plusnnnn (and are 'on'(on==30))."
3371     );
3372     parameters[numberParameters++] =
3373          CbcOrClpParam("pumpC!utoff", "Fake cutoff for use in feasibility pump",
3374                        -1.0e100, 1.0e100, CBC_PARAM_DBL_FAKECUTOFF);
3375     parameters[numberParameters-1].setDoubleValue(0.0);
3376     parameters[numberParameters-1].setLonghelp
3377     (
3378          "0.0 off - otherwise add a constraint forcing objective below this value\
3379 in feasibility pump"
3380     );
3381     parameters[numberParameters++] =
3382          CbcOrClpParam("pumpI!ncrement", "Fake increment for use in feasibility pump",
3383                        -1.0e100, 1.0e100, CBC_PARAM_DBL_FAKEINCREMENT, 1);
3384     parameters[numberParameters-1].setDoubleValue(0.0);
3385     parameters[numberParameters-1].setLonghelp
3386     (
3387          "0.0 off - otherwise use as absolute increment to cutoff \
3388when solution found in feasibility pump"
3389     );
3390     parameters[numberParameters++] =
3391          CbcOrClpParam("pumpT!une", "Dubious ideas for feasibility pump",
3392                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE);
3393     parameters[numberParameters-1].setLonghelp
3394     (
3395          "This fine tunes Feasibility Pump \n\
3396\t>=10000000 use as objective weight switch\n\
3397\t>=1000000 use as accumulate switch\n\
3398\t>=1000 use index+1 as number of large loops\n\
3399\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\
3400\t%100 == 10,20 affects how each solve is done\n\
3401\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \
3402If accumulate is on then after a major pass, variables which have not moved \
3403are fixed and a small branch and bound is tried."
3404     );
3405     parameters[numberParameters-1].setIntValue(0);
3406#endif
3407     parameters[numberParameters++] =
3408          CbcOrClpParam("quit", "Stops clp execution",
3409                        CLP_PARAM_ACTION_EXIT);
3410     parameters[numberParameters-1].setLonghelp
3411     (
3412          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3413     );
3414#ifdef COIN_HAS_CBC
3415     parameters[numberParameters++] =
3416          CbcOrClpParam("randomC!bcSeed", "Random seed for Cbc",
3417                        -1, COIN_INT_MAX, CBC_PARAM_INT_RANDOMSEED);
3418     parameters[numberParameters-1].setLonghelp
3419     (
3420          "This sets a random seed for Cbc \
3421- 0 says use time of day, -1 is as now."
3422     );
3423     parameters[numberParameters-1].setIntValue(-1);
3424     parameters[numberParameters++] =
3425          CbcOrClpParam("randomi!zedRounding", "Whether to try randomized rounding heuristic",
3426                        "off", CBC_PARAM_STR_RANDROUND);
3427     parameters[numberParameters-1].append("on");
3428     parameters[numberParameters-1].append("both");
3429     parameters[numberParameters-1].append("before");
3430     parameters[numberParameters-1].setLonghelp
3431     (
3432          "stuff needed. \
3433Doh option does heuristic before preprocessing"     );
3434#endif
3435#ifdef COIN_HAS_CLP
3436     parameters[numberParameters++] =
3437          CbcOrClpParam("randomS!eed", "Random seed for Clp",
3438                        0, COIN_INT_MAX, CLP_PARAM_INT_RANDOMSEED);
3439     parameters[numberParameters-1].setLonghelp
3440     (
3441          "This sets a random seed for Clp \
3442- 0 says use time of day."
3443     );
3444     parameters[numberParameters-1].setIntValue(1234567);
3445#endif
3446#ifdef COIN_HAS_CBC
3447     parameters[numberParameters++] =
3448          CbcOrClpParam("ratio!Gap", "Stop when gap between best possible and \
3449best less than this fraction of larger of two",
3450                        0.0, 1.0e20, CBC_PARAM_DBL_GAPRATIO);
3451     parameters[numberParameters-1].setDoubleValue(0.0);
3452     parameters[numberParameters-1].setLonghelp
3453     (
3454          "If the gap between best solution and best possible solution is less than this fraction \
3455of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
3456way of using absolute value rather than fraction."
3457     );
3458#endif
3459     parameters[numberParameters++] =
3460          CbcOrClpParam("restoreS!olution", "reads solution from file",
3461                        CLP_PARAM_ACTION_RESTORESOL);
3462     parameters[numberParameters-1].setLonghelp
3463     (
3464          "This will read a binary solution file from the given file name.  It will use the default\
3465 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3466 is initialized to 'solution.file'.  This reads in a file from saveSolution"
3467     );
3468#ifdef COIN_HAS_CBC
3469     parameters[numberParameters++] =
3470          CbcOrClpParam("readSt!ored", "Import stored cuts from file",
3471                        CLP_PARAM_ACTION_STOREDFILE, 3, 0);
3472#endif
3473#ifdef COIN_HAS_CLP
3474     parameters[numberParameters++] =
3475          CbcOrClpParam("reallyO!bjectiveScale", "Scale factor to apply to objective in place",
3476                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE2, 0);
3477     parameters[numberParameters-1].setLonghelp
3478     (
3479          "You can set this to -1.0 to test maximization or other to stress code"
3480     );
3481     parameters[numberParameters-1].setDoubleValue(1.0);
3482     parameters[numberParameters++] =
3483          CbcOrClpParam("reallyS!cale", "Scales model in place",
3484                        CLP_PARAM_ACTION_REALLY_SCALE, 7, 0);
3485#endif
3486#ifdef COIN_HAS_CBC
3487     parameters[numberParameters++] =
3488          CbcOrClpParam("reduce!AndSplitCuts", "Whether to use Reduce-and-Split cuts",
3489                        "off", CBC_PARAM_STR_REDSPLITCUTS);
3490     parameters[numberParameters-1].append("on");
3491     parameters[numberParameters-1].append("root");
3492     parameters[numberParameters-1].append("ifmove");
3493     parameters[numberParameters-1].append("forceOn");
3494     parameters[numberParameters-1].setLonghelp
3495     (
3496          "This switches on reduce and split  cuts (either at root or in entire tree). \
3497May be slow \
3498See branchAndCut for information on options."
3499     );
3500      parameters[numberParameters++] =
3501          CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2",
3502                        "off", CBC_PARAM_STR_REDSPLIT2CUTS);
3503     parameters[numberParameters-1].append("on");
3504     parameters[numberParameters-1].append("root");
3505     parameters[numberParameters-1].append("longOn");
3506     parameters[numberParameters-1].append("longRoot");
3507     parameters[numberParameters-1].setLonghelp
3508     (
3509          "This switches on reduce and split  cuts (either at root or in entire tree) \
3510This version is by Giacomo Nannicini based on Francois Margot's version \
3511Standard setting only uses rows in tableau <=256, long uses all \
3512May be slow \
3513See branchAndCut for information on options."
3514     );
3515     parameters[numberParameters++] =
3516          CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2",
3517                        "off", CBC_PARAM_STR_REDSPLIT2CUTS);
3518     parameters[numberParameters-1].append("on");
3519     parameters[numberParameters-1].append("root");
3520     parameters[numberParameters-1].append("longOn");
3521     parameters[numberParameters-1].append("longRoot");
3522     parameters[numberParameters-1].setLonghelp
3523     (
3524          "This switches on reduce and split  cuts (either at root or in entire tree) \
3525This version is by Giacomo Nannicini based on Francois Margot's version \
3526Standard setting only uses rows in tableau <=256, long uses all \
3527See branchAndCut for information on options."
3528     );
3529     parameters[numberParameters++] =
3530          CbcOrClpParam("residual!CapacityCuts", "Whether to use Residual Capacity cuts",
3531                        "off", CBC_PARAM_STR_RESIDCUTS);
3532     parameters[numberParameters-1].append("on");
3533     parameters[numberParameters-1].append("root");
3534     parameters[numberParameters-1].append("ifmove");
3535     parameters[numberParameters-1].append("forceOn");
3536     parameters[numberParameters-1].setLonghelp
3537     (
3538          "Residual capacity cuts. \
3539See branchAndCut for information on options."
3540     );
3541#endif
3542#ifdef COIN_HAS_CLP
3543     parameters[numberParameters++] =
3544          CbcOrClpParam("restore!Model", "Restore model from binary file",
3545                        CLP_PARAM_ACTION_RESTORE, 7, 1);
3546     parameters[numberParameters-1].setLonghelp
3547     (
3548          "This reads data save by saveModel from the given file.  It will use the default\
3549 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3550 is initialized to 'default.prob'."
3551     );
3552     parameters[numberParameters++] =
3553          CbcOrClpParam("reverse", "Reverses sign of objective",
3554                        CLP_PARAM_ACTION_REVERSE, 7, 0);
3555     parameters[numberParameters-1].setLonghelp
3556     (
3557          "Useful for testing if maximization works correctly"
3558     );
3559     parameters[numberParameters++] =
3560          CbcOrClpParam("rhs!Scale", "Scale factor to apply to rhs and bounds",
3561                        -1.0e20, 1.0e20, CLP_PARAM_DBL_RHSSCALE, 0);
3562     parameters[numberParameters-1].setLonghelp
3563     (
3564          "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
3565 internally by this amount.  It can also be set by autoscale.  This should not be needed."
3566     );
3567     parameters[numberParameters-1].setDoubleValue(1.0);
3568#endif
3569#ifdef COIN_HAS_CBC
3570     parameters[numberParameters++] =
3571          CbcOrClpParam("Rens", "Whether to try Relaxation Enforced Neighborhood Search",
3572                        "off", CBC_PARAM_STR_RENS);
3573     parameters[numberParameters-1].append("on");
3574     parameters[numberParameters-1].append("both");
3575     parameters[numberParameters-1].append("before");
3576     parameters[numberParameters-1].append("200");
3577     parameters[numberParameters-1].append("1000");
3578     parameters[numberParameters-1].append("10000");
3579     parameters[numberParameters-1].append("dj");
3580     parameters[numberParameters-1].append("djbefore");
3581     parameters[numberParameters-1].append("usesolution");
3582     parameters[numberParameters-1].setLonghelp
3583     (
3584          "This switches on Relaxation enforced neighborhood Search. \
3585on just does 50 nodes \
3586200 or 1000 does that many nodes. \
3587Doh option does heuristic before preprocessing"     );
3588     parameters[numberParameters++] =
3589          CbcOrClpParam("Rins", "Whether to try Relaxed Induced Neighborhood Search",
3590                        "off", CBC_PARAM_STR_RINS);
3591     parameters[numberParameters-1].append("on");
3592     parameters[numberParameters-1].append("both");
3593     parameters[numberParameters-1].append("before");
3594     parameters[numberParameters-1].append("often");
3595     parameters[numberParameters-1].setLonghelp
3596     (
3597          "This switches on Relaxed induced neighborhood Search. \
3598Doh option does heuristic before preprocessing"     );
3599     parameters[numberParameters++] =
3600          CbcOrClpParam("round!ingHeuristic", "Whether to use Rounding heuristic",
3601                        "off", CBC_PARAM_STR_ROUNDING);
3602     parameters[numberParameters-1].append("on");
3603     parameters[numberParameters-1].append("both");
3604     parameters[numberParameters-1].append("before");
3605     parameters[numberParameters-1].setLonghelp
3606     (
3607          "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
3608On means do in solve i.e. after preprocessing, \
3609Before means do if doHeuristics used, off otherwise, \
3610and both means do if doHeuristics and in solve."
3611     );
3612
3613#endif
3614     parameters[numberParameters++] =
3615          CbcOrClpParam("saveM!odel", "Save model to binary file",
3616                        CLP_PARAM_ACTION_SAVE, 7, 1);
3617     parameters[numberParameters-1].setLonghelp
3618     (
3619          "This will save the problem to the given file name for future use\
3620 by restoreModel.  It will use the default\
3621 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3622 is initialized to 'default.prob'."
3623     );
3624     parameters[numberParameters++] =
3625          CbcOrClpParam("saveS!olution", "saves solution to file",
3626                        CLP_PARAM_ACTION_SAVESOL);
3627     parameters[numberParameters-1].setLonghelp
3628     (
3629          "This will write a binary solution file to the given file name.  It will use the default\
3630 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3631 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
3632and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
3633activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
3634If name contains '_fix_read_' then does not write but reads and will fix all variables"
3635     );
3636     parameters[numberParameters++] =
3637          CbcOrClpParam("scal!ing", "Whether to scale problem",
3638                        "off", CLP_PARAM_STR_SCALING);
3639     parameters[numberParameters-1].append("equi!librium");
3640     parameters[numberParameters-1].append("geo!metric");
3641     parameters[numberParameters-1].append("auto!matic");
3642     parameters[numberParameters-1].append("dynamic");
3643     parameters[numberParameters-1].append("rows!only");
3644     parameters[numberParameters-1].setLonghelp
3645     (
3646          "Scaling can help in solving problems which might otherwise fail because of lack of\
3647 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
3648 of elements is small.  When unscaled it is possible that there may be small primal and/or\
3649 infeasibilities."
3650     );
3651     parameters[numberParameters-1].setCurrentOption(3); // say auto
3652#ifndef COIN_HAS_CBC
3653     parameters[numberParameters++] =
3654          CbcOrClpParam("sec!onds", "Maximum seconds",
3655                        -1.0, 1.0e12, CLP_PARAM_DBL_TIMELIMIT);
3656     parameters[numberParameters-1].setLonghelp
3657     (
3658          "After this many seconds clp will act as if maximum iterations had been reached \
3659(if value >=0)."
3660     );
3661#else
3662     parameters[numberParameters++] =
3663          CbcOrClpParam("sec!onds", "maximum seconds",
3664                        -1.0, 1.0e12, CBC_PARAM_DBL_TIMELIMIT_BAB);
3665     parameters[numberParameters-1].setLonghelp
3666     (
3667          "After this many seconds coin solver will act as if maximum nodes had been reached."
3668     );
3669#endif
3670     parameters[numberParameters++] =
3671          CbcOrClpParam("sleep", "for debug",
3672                        CLP_PARAM_ACTION_DUMMY, 7, 0);
3673     parameters[numberParameters-1].setLonghelp
3674     (
3675          "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
3676     );
3677#ifdef COIN_HAS_CBC
3678     parameters[numberParameters++] =
3679          CbcOrClpParam("slow!cutpasses", "Maximum number of tries for slower cuts",
3680                        -1, COIN_INT_MAX, CBC_PARAM_INT_MAX_SLOW_CUTS);
3681     parameters[numberParameters-1].setLonghelp
3682     (
3683          "Some cut generators are fairly slow - this limits the number of times they are tried."
3684     );
3685     parameters[numberParameters-1].setIntValue(10);
3686#endif
3687#ifdef COIN_HAS_CLP
3688     parameters[numberParameters++] =
3689          CbcOrClpParam("slp!Value", "Number of slp passes before primal",
3690                        -50000, 50000, CLP_PARAM_INT_SLPVALUE, 1);
3691     parameters[numberParameters-1].setLonghelp
3692     (
3693          "If you are solving a quadratic problem using primal then it may be helpful to do some \
3694sequential Lps to get a good approximate solution."
3695     );
3696#if CLP_MULTIPLE_FACTORIZATIONS > 0
3697     parameters[numberParameters++] =
3698          CbcOrClpParam("small!Factorization", "Whether to use small factorization",
3699                        -1, 10000, CBC_PARAM_INT_SMALLFACT, 1);
3700     parameters[numberParameters-1].setLonghelp
3701     (
3702          "If processed problem <= this use small factorization"
3703     );
3704     parameters[numberParameters-1].setIntValue(-1);
3705#endif
3706#endif
3707     parameters[numberParameters++] =
3708          CbcOrClpParam("solu!tion", "Prints solution to file",
3709                        CLP_PARAM_ACTION_SOLUTION);
3710     parameters[numberParameters-1].setLonghelp
3711     (
3712          "This will write a primitive solution file to the given file name.  It will use the default\
3713 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3714 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
3715     );
3716#ifdef COIN_HAS_CLP
3717#ifdef COIN_HAS_CBC
3718     parameters[numberParameters++] =
3719          CbcOrClpParam("solv!e", "Solve problem",
3720                        CBC_PARAM_ACTION_BAB);
3721     parameters[numberParameters-1].setLonghelp
3722     (
3723          "If there are no integer variables then this just solves LP.  If there are integer variables \
3724this does branch and cut."
3725     );
3726     parameters[numberParameters++] =
3727          CbcOrClpParam("sosO!ptions", "Whether to use SOS from AMPL",
3728                        "off", CBC_PARAM_STR_SOS);
3729     parameters[numberParameters-1].append("on");
3730     parameters[numberParameters-1].setCurrentOption("on");
3731     parameters[numberParameters-1].setLonghelp
3732     (
3733          "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
3734 be turned off - this does so."
3735     );
3736     // Due to James Howey
3737     parameters[numberParameters++] =
3738          CbcOrClpParam("sosP!rioritize", "How to deal with SOS priorities",
3739                        "off", CBC_PARAM_STR_SOSPRIORITIZE);
3740     parameters[numberParameters-1].append("high");
3741     parameters[numberParameters-1].append("low");
3742     parameters[numberParameters-1].append("orderhigh");
3743     parameters[numberParameters-1].append("orderlow");
3744     parameters[numberParameters-1].setLonghelp
3745     (
3746          "This sets priorities for SOS.  The first two just set priority \
3747relative to integers.  Orderhigh gives first set highest priority and integers \
3748a low priority.  Orderlow gives integers high priority then SOS in order."
3749     );
3750     parameters[numberParameters++] =
3751          CbcOrClpParam("slog!Level", "Level of detail in (LP) Solver output",
3752                        -1, 63, CLP_PARAM_INT_SOLVERLOGLEVEL);
3753     parameters[numberParameters-1].setLonghelp
3754     (
3755          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
3756 value for most uses, while 2 and 3 give more information.  This parameter is only used inside MIP - for Clp use 'log'"
3757     );
3758#else
3759     // allow solve as synonym for possible dual
3760     parameters[numberParameters++] =
3761       CbcOrClpParam("solv!e", "Solve problem using dual simplex (probably)",
3762                        CLP_PARAM_ACTION_EITHERSIMPLEX);
3763     parameters[numberParameters-1].setLonghelp
3764     (
3765          "Just so can use solve for clp as well as in cbc"
3766     );
3767#endif
3768#endif
3769#ifdef COIN_HAS_CLP
3770     parameters[numberParameters++] =
3771          CbcOrClpParam("spars!eFactor", "Whether factorization treated as sparse",
3772                        "on", CLP_PARAM_STR_SPARSEFACTOR, 7, 0);
3773     parameters[numberParameters-1].append("off");
3774     parameters[numberParameters++] =
3775          CbcOrClpParam("special!Options", "Dubious options for Simplex - see ClpSimplex.hpp",
3776                        0, COIN_INT_MAX, CLP_PARAM_INT_SPECIALOPTIONS, 0);
3777     parameters[numberParameters++] =
3778          CbcOrClpParam("sprint!Crash", "Whether to try sprint crash",
3779                        -1, 5000000, CLP_PARAM_INT_SPRINT);
3780     parameters[numberParameters-1].setLonghelp
3781     (
3782          "For long and thin problems this program may solve a series of small problems\
3783 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
3784 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
3785  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
3786     );
3787     parameters[numberParameters++] =
3788          CbcOrClpParam("stat!istics", "Print some statistics",
3789                        CLP_PARAM_ACTION_STATISTICS);
3790     parameters[numberParameters-1].setLonghelp
3791     (
3792          "This command prints some statistics for the current model.\
3793 If log level >1 then more is printed.\
3794 These are for presolved model if presolve on (and unscaled)."
3795     );
3796#endif
3797     parameters[numberParameters++] =
3798          CbcOrClpParam("stop", "Stops clp execution",
3799                        CLP_PARAM_ACTION_EXIT);
3800     parameters[numberParameters-1].setLonghelp
3801     (
3802          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3803     );
3804#ifdef COIN_HAS_CBC
3805     parameters[numberParameters++] =
3806          CbcOrClpParam("strat!egy", "Switches on groups of features",
3807                        0, 2, CBC_PARAM_INT_STRATEGY);
3808     parameters[numberParameters-1].setLonghelp
3809     (
3810          "This turns on newer features. \
3811Use 0 for easy problems, 1 is default, 2 is aggressive. \
38121 uses Gomory cuts using tolerance of 0.01 at root, \
3813does a possible restart after 100 nodes if can fix many \
3814and activates a diving and RINS heuristic and makes feasibility pump \
3815more aggressive. \
3816This does not apply to unit tests (where 'experiment' may have similar effects)."
3817     );
3818     parameters[numberParameters-1].setIntValue(1);
3819#ifdef CBC_KEEP_DEPRECATED
3820     parameters[numberParameters++] =
3821          CbcOrClpParam("strengthen", "Create strengthened problem",
3822                        CBC_PARAM_ACTION_STRENGTHEN, 3);
3823     parameters[numberParameters-1].setLonghelp
3824     (
3825          "This creates a new problem by applying the root node cuts.  All tight constraints \
3826will be in resulting problem"
3827     );
3828#endif
3829     parameters[numberParameters++] =
3830          CbcOrClpParam("strong!Branching", "Number of variables to look at in strong branching",
3831                        0, COIN_INT_MAX, CBC_PARAM_INT_STRONGBRANCHING);
3832     parameters[numberParameters-1].setLonghelp
3833     (
3834          "In order to decide which variable to branch on, the code will choose up to this number \
3835of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
3836If a variable is branched on many times then the previous average up and down costs may be used - \
3837see number before trust."
3838     );
3839#endif
3840#ifdef COIN_HAS_CLP
3841     parameters[numberParameters++] =
3842          CbcOrClpParam("subs!titution", "How long a column to substitute for in presolve",
3843                        0, 10000, CLP_PARAM_INT_SUBSTITUTION, 0);
3844     parameters[numberParameters-1].setLonghelp
3845     (
3846          "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
3847 variables in column.  If you increase this the number of rows may decrease but number of \
3848 elements may increase."
3849     );
3850#endif
3851#ifdef COIN_HAS_CBC
3852     parameters[numberParameters++] =
3853          CbcOrClpParam("testO!si", "Test OsiObject stuff",
3854                        -1, COIN_INT_MAX, CBC_PARAM_INT_TESTOSI, 0);
3855#endif
3856#ifdef CBC_THREAD
3857     parameters[numberParameters++] =
3858          CbcOrClpParam("thread!s", "Number of threads to try and use",
3859                        -100, 100000, CBC_PARAM_INT_THREADS, 1);
3860     parameters[numberParameters-1].setLonghelp
3861     (
3862          "To use multiple threads, set threads to number wanted.  It may be better \
3863to use one or two more than number of cpus available.  If 100+n then n threads and \
3864search is repeatable (maybe be somewhat slower), \
3865if 200+n use threads for root cuts, 400+n threads used in sub-trees."
3866     );
3867#endif
3868#ifdef COIN_HAS_CBC
3869     parameters[numberParameters++] =
3870          CbcOrClpParam("tighten!Factor", "Tighten bounds using this times largest \
3871activity at continuous solution",
3872                        1.0e-3, 1.0e20, CBC_PARAM_DBL_TIGHTENFACTOR, 0);
3873     parameters[numberParameters-1].setLonghelp
3874     (
3875          "This sleazy trick can help on some problems."
3876     );
3877#endif
3878#ifdef COIN_HAS_CLP
3879     parameters[numberParameters++] =
3880          CbcOrClpParam("tightLP", "Poor person's preSolve for now",
3881                        CLP_PARAM_ACTION_TIGHTEN, 7, 0);
3882#endif
3883     parameters[numberParameters++] =
3884          CbcOrClpParam("timeM!ode", "Whether to use CPU or elapsed time",
3885                        "cpu", CLP_PARAM_STR_TIME_MODE);
3886     parameters[numberParameters-1].append("elapsed");
3887     parameters[numberParameters-1].setLonghelp
3888     (
3889          "cpu uses CPU time for stopping, while elapsed uses elapsed time. \
3890(On Windows, elapsed time is always used)."
3891     );
3892#ifdef COIN_HAS_CBC
3893     parameters[numberParameters++] =
3894          CbcOrClpParam("trust!PseudoCosts", "Number of branches before we trust pseudocosts",
3895                        -3, 2000000000, CBC_PARAM_INT_NUMBERBEFORE);
3896     parameters[numberParameters-1].setLonghelp
3897     (
3898          "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
3899trust the pseudo costs and do not do any more strong branching."
3900     );
3901#endif
3902#ifdef COIN_HAS_CBC
3903     parameters[numberParameters++] =
3904          CbcOrClpParam("tune!PreProcess", "Dubious tuning parameters",
3905                        0, 2000000000, CLP_PARAM_INT_PROCESSTUNE, 1);
3906     parameters[numberParameters-1].setLonghelp
3907     (
3908          "Format aabbcccc - \n If aa then this is number of major passes (i.e. with presolve) \n \
3909If bb and bb>0 then this is number of minor passes (if unset or 0 then 10) \n \
3910cccc is bit set \n 0 - 1 Heavy probing \n 1 - 2 Make variables integer if possible (if obj value)\n \
39112 - 4 As above but even if zero objective value\n \
39127 - 128 Try and create cliques\n 8 - 256 If all +1 try hard for dominated rows\n \
391310 - 1024 Use a larger feasibility tolerance in presolve\n \
391411 - 2048 Try probing before creating cliques\n \
391512 - 4096 Switch off duplicate column checking for integers"
3916     );
3917     parameters[numberParameters++] =
3918          CbcOrClpParam("two!MirCuts", "Whether to use Two phase Mixed Integer Rounding cuts",
3919                        "off", CBC_PARAM_STR_TWOMIRCUTS);
3920     parameters[numberParameters-1].append("on");
3921     parameters[numberParameters-1].append("root");
3922     parameters[numberParameters-1].append("ifmove");
3923     parameters[numberParameters-1].append("forceOn");
3924     parameters[numberParameters-1].append("onglobal");
3925     parameters[numberParameters-1].append("forceandglobal");
3926     parameters[numberParameters-1].append("forceLongOn");
3927     parameters[numberParameters-1].setLonghelp
3928     (
3929          "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
3930See branchAndCut for information on options."
3931     );
3932#endif
3933     parameters[numberParameters++] =
3934          CbcOrClpParam("unitTest", "Do unit test",
3935                        CLP_PARAM_ACTION_UNITTEST, 3, 1);
3936     parameters[numberParameters-1].setLonghelp
3937     (
3938          "This exercises the unit test for clp"
3939     );
3940     parameters[numberParameters++] =
3941          CbcOrClpParam("userClp", "Hand coded Clp stuff",
3942                        CLP_PARAM_ACTION_USERCLP, 0, 0);
3943     parameters[numberParameters-1].setLonghelp
3944     (
3945          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3946Look for USERCLP in main driver and modify sample code."
3947     );
3948#ifdef COIN_HAS_CBC
3949     parameters[numberParameters++] =
3950          CbcOrClpParam("userCbc", "Hand coded Cbc stuff",
3951                        CBC_PARAM_ACTION_USERCBC, 0, 0);
3952     parameters[numberParameters-1].setLonghelp
3953     (
3954          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3955Look for USERCBC in main driver and modify sample code. \
3956It is possible you can get same effect by using example driver4.cpp."
3957     );
3958#endif
3959#ifdef COIN_AVX2
3960     parameters[numberParameters++] =
3961          CbcOrClpParam("vector!Mode", "Try and use vector instructions",
3962                        0, 11, CLP_PARAM_INT_VECTOR_MODE);
3963     parameters[numberParameters-1].setLonghelp
3964     (
3965          "At present only for Intel architectures - but could be extended.  \
3966Uses avx2 or avx512 instructions. Uses different storage for matrix - can be \
3967of benefit without instruction set on some problems.  \
3968Being lazy I have used 10 to switch on a pool matrix (11 may come later)"
3969     );
3970     parameters[numberParameters-1].setIntValue(0);
3971#endif
3972#ifdef COIN_HAS_CBC
3973     parameters[numberParameters++] =
3974          CbcOrClpParam("Vnd!VariableNeighborhoodSearch", "Whether to try Variable Neighborhood Search",
3975                        "off", CBC_PARAM_STR_VND);
3976     parameters[numberParameters-1].append("on");
3977     parameters[numberParameters-1].append("both");
3978     parameters[numberParameters-1].append("before");
3979     parameters[numberParameters-1].append("intree");
3980     parameters[numberParameters-1].setLonghelp
3981     (
3982          "This switches on variable neighborhood Search. \
3983Doh option does heuristic before preprocessing"     );
3984#endif
3985     parameters[numberParameters++] =
3986          CbcOrClpParam("vector", "Whether to use vector? Form of matrix in simplex",
3987                        "off", CLP_PARAM_STR_VECTOR, 7, 0);
3988     parameters[numberParameters-1].append("on");
3989     parameters[numberParameters-1].setLonghelp
3990     (
3991          "If this is on ClpPackedMatrix uses extra column copy in odd format."
3992     );
3993     parameters[numberParameters++] =
3994          CbcOrClpParam("verbose", "Switches on longer help on single ?",
3995                        0, 31, CLP_PARAM_INT_VERBOSE, 0);
3996     parameters[numberParameters-1].setLonghelp
3997     (
3998          "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
3999     );
4000     parameters[numberParameters-1].setIntValue(0);
4001#ifdef COIN_HAS_CBC
4002     parameters[numberParameters++] =
4003          CbcOrClpParam("vub!heuristic", "Type of vub heuristic",
4004                        -2, 20, CBC_PARAM_INT_VUBTRY, 0);
4005     parameters[numberParameters-1].setLonghelp
4006     (
4007          "If set will try and fix some integer variables"
4008     );
4009     parameters[numberParameters-1].setIntValue(-1);
4010     parameters[numberParameters++] =
4011          CbcOrClpParam("zero!HalfCuts", "Whether to use zero half cuts",
4012                        "off", CBC_PARAM_STR_ZEROHALFCUTS);
4013     parameters[numberParameters-1].append("on");
4014     parameters[numberParameters-1].append("root");
4015     parameters[numberParameters-1].append("ifmove");
4016     parameters[numberParameters-1].append("forceOn");
4017     parameters[numberParameters-1].append("onglobal");
4018     parameters[numberParameters-1].setLonghelp
4019     (
4020          "This switches on zero-half cuts (either at root or in entire tree) \
4021See branchAndCut for information on options.  This implementation was written by \
4022Alberto Caprara."
4023     );
4024#endif
4025     parameters[numberParameters++] =
4026          CbcOrClpParam("zeroT!olerance", "Kill all coefficients \
4027whose absolute value is less than this value",
4028                        1.0e-100, 1.0e-5, CLP_PARAM_DBL_ZEROTOLERANCE);
4029     parameters[numberParameters-1].setLonghelp
4030     (
4031          "This applies to reading mps files (and also lp files \
4032if KILL_ZERO_READLP defined)"
4033     );
4034     parameters[numberParameters-1].setDoubleValue(1.0e-20);
4035     assert(numberParameters < CBCMAXPARAMETERS);
4036}
4037// Given a parameter type - returns its number in list
4038int whichParam (CbcOrClpParameterType name,
4039                int numberParameters, CbcOrClpParam *const parameters)
4040{
4041     int i;
4042     for (i = 0; i < numberParameters; i++) {
4043          if (parameters[i].type() == name)
4044               break;
4045     }
4046     assert (i < numberParameters);
4047     return i;
4048}
4049#ifdef COIN_HAS_CLP
4050/* Restore a solution from file.
4051   mode 0 normal, 1 swap rows and columns and primal and dual
4052   if 2 set then also change signs
4053*/
4054void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode)
4055{
4056     FILE * fp = fopen(fileName.c_str(), "rb");
4057     if (fp) {
4058          int numberRows = lpSolver->numberRows();
4059          int numberColumns = lpSolver->numberColumns();
4060          int numberRowsFile;
4061          int numberColumnsFile;
4062          double objectiveValue;
4063          size_t nRead;
4064          nRead = fread(&numberRowsFile, sizeof(int), 1, fp);
4065          if (nRead != 1)
4066               throw("Error in fread");
4067          nRead = fread(&numberColumnsFile, sizeof(int), 1, fp);
4068          if (nRead != 1)
4069               throw("Error in fread");
4070          nRead = fread(&objectiveValue, sizeof(double), 1, fp);
4071          if (nRead != 1)
4072               throw("Error in fread");
4073          double * dualRowSolution = lpSolver->dualRowSolution();
4074          double * primalRowSolution = lpSolver->primalRowSolution();
4075          double * dualColumnSolution = lpSolver->dualColumnSolution();
4076          double * primalColumnSolution = lpSolver->primalColumnSolution();
4077          if (mode) {
4078               // swap
4079               int k = numberRows;
4080               numberRows = numberColumns;
4081               numberColumns = k;
4082               double * temp;
4083               temp = dualRowSolution;
4084               dualRowSolution = primalColumnSolution;
4085               primalColumnSolution = temp;
4086               temp = dualColumnSolution;
4087               dualColumnSolution = primalRowSolution;
4088               primalRowSolution = temp;
4089          }
4090          if (numberRows > numberRowsFile || numberColumns > numberColumnsFile) {
4091               std::cout << "Mismatch on rows and/or columns - giving up" << std::endl;
4092          } else {
4093               lpSolver->setObjectiveValue(objectiveValue);
4094               if (numberRows == numberRowsFile && numberColumns == numberColumnsFile) {
4095                    nRead = fread(primalRowSolution, sizeof(double), numberRows, fp);
4096                    if (nRead != static_cast<size_t>(numberRows))
4097                         throw("Error in fread");
4098                    nRead = fread(dualRowSolution, sizeof(double), numberRows, fp);
4099                    if (nRead != static_cast<size_t>(numberRows))
4100                         throw("Error in fread");
4101                    nRead = fread(primalColumnSolution, sizeof(double), numberColumns, fp);
4102                    if (nRead != static_cast<size_t>(numberColumns))
4103                         throw("Error in fread");
4104                    nRead = fread(dualColumnSolution, sizeof(double), numberColumns, fp);
4105                    if (nRead != static_cast<size_t>(numberColumns))
4106                         throw("Error in fread");
4107               } else {
4108                    std::cout << "Mismatch on rows and/or columns - truncating" << std::endl;
4109                    double * temp = new double [CoinMax(numberRowsFile, numberColumnsFile)];
4110                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
4111                    if (nRead != static_cast<size_t>(numberRowsFile))
4112                         throw("Error in fread");
4113                    CoinMemcpyN(temp, numberRows, primalRowSolution);
4114                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
4115                    if (nRead != static_cast<size_t>(numberRowsFile))
4116                         throw("Error in fread");
4117                    CoinMemcpyN(temp, numberRows, dualRowSolution);
4118                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
4119                    if (nRead != static_cast<size_t>(numberColumnsFile))
4120                         throw("Error in fread");
4121                    CoinMemcpyN(temp, numberColumns, primalColumnSolution);
4122                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
4123                    if (nRead != static_cast<size_t>(numberColumnsFile))
4124                         throw("Error in fread");
4125                    CoinMemcpyN(temp, numberColumns, dualColumnSolution);
4126                    delete [] temp;
4127                           }
4128               if (mode == 3) {
4129                    int i;
4130                    for (i = 0; i < numberRows; i++) {
4131                         primalRowSolution[i] = -primalRowSolution[i];
4132                         dualRowSolution[i] = -dualRowSolution[i];
4133                    }
4134                    for (i = 0; i < numberColumns; i++) {
4135                         primalColumnSolution[i] = -primalColumnSolution[i];
4136                         dualColumnSolution[i] = -dualColumnSolution[i];
4137                    }
4138               }
4139          }
4140          fclose(fp);
4141     } else {
4142          std::cout << "Unable to open file " << fileName << std::endl;
4143     }
4144}
4145// Dump a solution to file
4146void saveSolution(const ClpSimplex * lpSolver, std::string fileName)
4147{
4148     if (strstr(fileName.c_str(), "_fix_read_")) {
4149          FILE * fp = fopen(fileName.c_str(), "rb");
4150          if (fp) {
4151               ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
4152               restoreSolution(solver, fileName, 0);
4153               // fix all
4154               int logLevel = solver->logLevel();
4155               int iColumn;
4156               int numberColumns = solver->numberColumns();
4157               double * primalColumnSolution =
4158                    solver->primalColumnSolution();
4159               double * columnLower = solver->columnLower();
4160               double * columnUpper = solver->columnUpper();
4161               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
4162                    double value = primalColumnSolution[iColumn];
4163                    if (value > columnUpper[iColumn]) {
4164                         if (value > columnUpper[iColumn] + 1.0e-6 && logLevel > 1)
4165                              printf("%d value of %g - bounds %g %g\n",
4166                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
4167                         value = columnUpper[iColumn];
4168                    } else if (value < columnLower[iColumn]) {
4169                         if (value < columnLower[iColumn] - 1.0e-6 && logLevel > 1)
4170                              printf("%d value of %g - bounds %g %g\n",
4171                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
4172                         value = columnLower[iColumn];
4173                    }
4174                    columnLower[iColumn] = value;
4175                    columnUpper[iColumn] = value;
4176               }
4177               return;
4178          }
4179     }
4180     FILE * fp = fopen(fileName.c_str(), "wb");
4181     if (fp) {
4182          int numberRows = lpSolver->numberRows();
4183          int numberColumns = lpSolver->numberColumns();
4184          double objectiveValue = lpSolver->objectiveValue();
4185          size_t nWrite;
4186          nWrite = fwrite(&numberRows, sizeof(int), 1, fp);
4187          if (nWrite != 1)
4188               throw("Error in fwrite");
4189          nWrite = fwrite(&numberColumns, sizeof(int), 1, fp);
4190          if (nWrite != 1)
4191               throw("Error in fwrite");
4192          nWrite = fwrite(&objectiveValue, sizeof(double), 1, fp);
4193          if (nWrite != 1)
4194               throw("Error in fwrite");
4195          double * dualRowSolution = lpSolver->dualRowSolution();
4196          double * primalRowSolution = lpSolver->primalRowSolution();
4197          nWrite = fwrite(primalRowSolution, sizeof(double), numberRows, fp);
4198          if (nWrite != static_cast<size_t>(numberRows))
4199               throw("Error in fwrite");
4200          nWrite = fwrite(dualRowSolution, sizeof(double), numberRows, fp);
4201          if (nWrite != static_cast<size_t>(numberRows))
4202               throw("Error in fwrite");
4203          double * dualColumnSolution = lpSolver->dualColumnSolution();
4204          double * primalColumnSolution = lpSolver->primalColumnSolution();
4205          nWrite = fwrite(primalColumnSolution, sizeof(double), numberColumns, fp);
4206          if (nWrite != static_cast<size_t>(numberColumns))
4207               throw("Error in fwrite");
4208          nWrite = fwrite(dualColumnSolution, sizeof(double), numberColumns, fp);
4209          if (nWrite != static_cast<size_t>(numberColumns))
4210               throw("Error in fwrite");
4211          fclose(fp);
4212     } else {
4213          std::cout << "Unable to open file " << fileName << std::endl;
4214     }
4215}
4216#endif
Note: See TracBrowser for help on using the repository browser.