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

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

minor changes to implement Aboca

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