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

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