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

Last change on this file since 1906 was 1906, checked in by forrest, 7 years ago

more options

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