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

Last change on this file since 1596 was 1596, checked in by forrest, 9 years ago

minor changes for making feasible

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