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

Last change on this file since 1852 was 1852, checked in by forrest, 8 years ago

change for mipstart

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