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

Last change on this file since 1908 was 1908, checked in by stefan, 7 years ago

assume latest cbc, i.e., assume that CBC_AFTER_2_8 gets always defined

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