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

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

more special options

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