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

Last change on this file since 2384 was 2384, checked in by forrest, 4 months ago

Allow a strategy for initial solve where code analyzes problem and guesses at parameters

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