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

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

allow setting of random seed

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