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

Last change on this file since 1904 was 1904, checked in by forrest, 8 years ago

for multiple root solvers

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