source: stable/1.14/Clp/src/CbcOrClpParam.cpp @ 1905

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

put multiple root solvers into stable (only on if >Cbc2.8)

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