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

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

no proximity search with cbc 2.7

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