source: stable/1.14/Clp/src/CbcOrClpParam.cpp @ 1886

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

add proximity search to possibilities

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 154.8 KB
Line 
1/* $Id: CbcOrClpParam.cpp 1886 2012-11-21 09:34:47Z 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               fprintf(stdout, coin_prompt);
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);
2395     parameters[numberParameters-1].setLonghelp
2396     ("\
2397The MIPStart allows one to enter an initial integer feasible solution \
2398to CBC. Values of the main decision variables which are active (have \
2399non-zero values) in this solution are specified in a text  file. The \
2400text file format used is the same of the solutions saved by CBC, but \
2401not all fields are required to be filled. First line may contain the \
2402solution status and will be ignored, remaning lines contain column \
2403indexes, names and values as in this example:\n\
2404\n\
2405Stopped on iterations - objective value 57597.00000000\n\
2406      0  x(1,1,2,2)               1 \n\
2407      1  x(3,1,3,2)               1 \n\
2408      5  v(5,1)                   2 \n\
2409      33 x(8,1,5,2)               1 \n\
2410      ...\n\
2411\n\
2412Column indexes are also ignored since pre-processing can change them. \
2413There is no need to include values for continuous or integer auxiliary \
2414variables, since they can be computed based on main decision variables. \
2415Starting CBC with an integer feasible solution can dramatically improve \
2416its performance: several MIP heuristics (e.g. RINS) rely on having at \
2417least one feasible solution available and can start immediately if the \
2418user provides one. Feasibility Pump (FP) is a heuristic which tries to \
2419overcome the problem of taking too long to find feasible solution (or \
2420not finding at all), but it not always suceeds. If you provide one \
2421starting solution you will probably save some time by disabling FP. \
2422\n\n\
2423Knowledge specific to your problem can be considered to write an \
2424external module to quickly produce an initial feasible solution - some \
2425alternatives are the implementation of simple greedy heuristics or the \
2426solution (by CBC for example) of a simpler model created just to find \
2427a feasible solution. \
2428\n\n\
2429Question and suggestions regarding MIPStart can be directed to\n\
2430haroldo.santos@gmail.com.\
2431");
2432     parameters[numberParameters++] =
2433          CbcOrClpParam("moreT!une", "Yet more dubious ideas for feasibility pump",
2434                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE2, 0);
2435     parameters[numberParameters-1].setLonghelp
2436     (
2437          "Yet more ideas for Feasibility Pump \n\
2438\t/100000 == 1 use box constraints and original obj in cleanup\n\
2439\t/1000 == 1 Pump will run twice if no solution found\n\
2440\t/1000 == 2 Pump will only run after root cuts if no solution found\n\
2441\t/1000 >10 as above but even if solution found\n\
2442\t/100 == 1,3.. exact 1.0 for objective values\n\
2443\t/100 == 2,3.. allow more iterations per pass\n\
2444\t n fix if value of variable same for last n iterations."
2445     );
2446     parameters[numberParameters-1].setIntValue(0);
2447     parameters[numberParameters++] =
2448          CbcOrClpParam("miplib", "Do some of miplib test set",
2449                        CBC_PARAM_ACTION_MIPLIB, 3, 1);
2450     parameters[numberParameters++] =
2451          CbcOrClpParam("naive!Heuristics", "Whether to try some stupid heuristic",
2452                        "off", CBC_PARAM_STR_NAIVE, 7, 1);
2453     parameters[numberParameters-1].append("on");
2454     parameters[numberParameters-1].append("both");
2455     parameters[numberParameters-1].append("before");
2456     parameters[numberParameters-1].setLonghelp
2457     (
2458          "Really silly stuff e.g. fix all integers with costs to zero!. \
2459Doh option does heuristic before preprocessing"     );
2460#endif
2461#ifdef COIN_HAS_CLP
2462     parameters[numberParameters++] =
2463          CbcOrClpParam("netlib", "Solve entire netlib test set",
2464                        CLP_PARAM_ACTION_NETLIB_EITHER, 3, 1);
2465     parameters[numberParameters-1].setLonghelp
2466     (
2467          "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
2468The user can set options before e.g. clp -presolve off -netlib"
2469     );
2470     parameters[numberParameters++] =
2471          CbcOrClpParam("netlibB!arrier", "Solve entire netlib test set with barrier",
2472                        CLP_PARAM_ACTION_NETLIB_BARRIER, 3, 1);
2473     parameters[numberParameters-1].setLonghelp
2474     (
2475          "This exercises the unit test for clp and then solves the netlib test set using barrier.\
2476The user can set options before e.g. clp -kkt on -netlib"
2477     );
2478     parameters[numberParameters++] =
2479          CbcOrClpParam("netlibD!ual", "Solve entire netlib test set (dual)",
2480                        CLP_PARAM_ACTION_NETLIB_DUAL, 3, 1);
2481     parameters[numberParameters-1].setLonghelp
2482     (
2483          "This exercises the unit test for clp and then solves the netlib test set using dual.\
2484The user can set options before e.g. clp -presolve off -netlib"
2485     );
2486     parameters[numberParameters++] =
2487          CbcOrClpParam("netlibP!rimal", "Solve entire netlib test set (primal)",
2488                        CLP_PARAM_ACTION_NETLIB_PRIMAL, 3, 1);
2489     parameters[numberParameters-1].setLonghelp
2490     (
2491          "This exercises the unit test for clp and then solves the netlib test set using primal.\
2492The user can set options before e.g. clp -presolve off -netlibp"
2493     );
2494     parameters[numberParameters++] =
2495          CbcOrClpParam("netlibT!une", "Solve entire netlib test set with 'best' algorithm",
2496                        CLP_PARAM_ACTION_NETLIB_TUNE, 3, 1);
2497     parameters[numberParameters-1].setLonghelp
2498     (
2499          "This exercises the unit test for clp and then solves the netlib test set using whatever \
2500works best.  I know this is cheating but it also stresses the code better by doing a \
2501mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
2502with University of Florida ordering."
2503     );
2504     parameters[numberParameters++] =
2505          CbcOrClpParam("network", "Tries to make network matrix",
2506                        CLP_PARAM_ACTION_NETWORK, 7, 0);
2507     parameters[numberParameters-1].setLonghelp
2508     (
2509          "Clp will go faster if the matrix can be converted to a network.  The matrix\
2510 operations may be a bit faster with more efficient storage, but the main advantage\
2511 comes from using a network factorization.  It will probably not be as fast as a \
2512specialized network code."
2513     );
2514#ifdef COIN_HAS_CBC
2515     parameters[numberParameters++] =
2516          CbcOrClpParam("nextB!estSolution", "Prints next best saved solution to file",
2517                        CLP_PARAM_ACTION_NEXTBESTSOLUTION);
2518     parameters[numberParameters-1].setLonghelp
2519     (
2520          "To write best solution, just use solution.  This prints next best (if exists) \
2521 and then deletes it. \
2522 This will write a primitive solution file to the given file name.  It will use the default\
2523 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2524 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
2525     );
2526     parameters[numberParameters++] =
2527          CbcOrClpParam("node!Strategy", "What strategy to use to select nodes",
2528                        "hybrid", CBC_PARAM_STR_NODESTRATEGY);
2529     parameters[numberParameters-1].append("fewest");
2530     parameters[numberParameters-1].append("depth");
2531     parameters[numberParameters-1].append("upfewest");
2532     parameters[numberParameters-1].append("downfewest");
2533     parameters[numberParameters-1].append("updepth");
2534     parameters[numberParameters-1].append("downdepth");
2535     parameters[numberParameters-1].setLonghelp
2536     (
2537          "Normally before a solution the code will choose node with fewest infeasibilities. \
2538You can choose depth as the criterion.  You can also say if up or down branch must \
2539be done first (the up down choice will carry on after solution). \
2540Default has now been changed to hybrid which is breadth first on small depth nodes then fewest."
2541     );
2542     parameters[numberParameters++] =
2543          CbcOrClpParam("numberA!nalyze", "Number of analysis iterations",
2544                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_NUMBERANALYZE, 0);
2545     parameters[numberParameters-1].setLonghelp
2546     (
2547          "This says how many iterations to spend at root node analyzing problem. \
2548This is a first try and will hopefully become more sophisticated."
2549     );
2550#endif
2551     parameters[numberParameters++] =
2552          CbcOrClpParam("objective!Scale", "Scale factor to apply to objective",
2553                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE, 1);
2554     parameters[numberParameters-1].setLonghelp
2555     (
2556          "If the objective function has some very large values, you may wish to scale them\
2557 internally by this amount.  It can also be set by autoscale.  It is applied after scaling.  You are unlikely to need this."
2558     );
2559     parameters[numberParameters-1].setDoubleValue(1.0);
2560#endif
2561#ifdef COIN_HAS_CBC
2562     parameters[numberParameters++] =
2563          CbcOrClpParam("outDup!licates", "takes duplicate rows etc out of integer model",
2564                        CLP_PARAM_ACTION_OUTDUPROWS, 7, 0);
2565#endif
2566     parameters[numberParameters++] =
2567          CbcOrClpParam("output!Format", "Which output format to use",
2568                        1, 6, CLP_PARAM_INT_OUTPUTFORMAT);
2569     parameters[numberParameters-1].setLonghelp
2570     (
2571          "Normally export will be done using normal representation for numbers and two values\
2572 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
2573 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
2574 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
2575 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
2576values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
2577     );
2578#ifdef COIN_HAS_CLP
2579     parameters[numberParameters++] =
2580          CbcOrClpParam("para!metrics", "Import data from file and do parametrics",
2581                        CLP_PARAM_ACTION_PARAMETRICS, 3);
2582     parameters[numberParameters-1].setLonghelp
2583     (
2584          "This will read a file with parametric data from the given file name \
2585and then do parametrics.  It will use the default\
2586 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2587 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2588File is in modified csv format - a line ROWS will be followed by rows data \
2589while a line COLUMNS will be followed by column data.  The last line \
2590should be ENDATA. The ROWS line must exist and is in the format \
2591ROWS, inital theta, final theta, interval theta, n where n is 0 to get \
2592CLPI0062 message at interval or at each change of theta \
2593and 1 to get CLPI0063 message at each iteration.  If interval theta is 0.0 \
2594or >= final theta then no interval reporting.  n may be missed out when it is \
2595taken as 0.  If there is Row data then \
2596there is a headings line with allowed headings - name, number, \
2597lower(rhs change), upper(rhs change), rhs(change).  Either the lower and upper \
2598fields should be given or the rhs field. \
2599The optional COLUMNS line is followed by a headings line with allowed \
2600headings - name, number, objective(change), lower(change), upper(change). \
2601 Exactly one of name and number must be given for either section and \
2602missing ones have value 0.0."
2603     );
2604#endif
2605#ifdef COIN_HAS_CBC
2606     parameters[numberParameters++] =
2607          CbcOrClpParam("passC!uts", "Number of cut passes at root node",
2608                        -9999999, 9999999, CBC_PARAM_INT_CUTPASS);
2609     parameters[numberParameters-1].setLonghelp
2610     (
2611          "The default is 100 passes if less than 500 columns, 100 passes (but \
2612stop if drop small if less than 5000 columns, 20 otherwise"
2613     );
2614     parameters[numberParameters++] =
2615          CbcOrClpParam("passF!easibilityPump", "How many passes in feasibility pump",
2616                        0, 10000, CBC_PARAM_INT_FPUMPITS);
2617     parameters[numberParameters-1].setLonghelp
2618     (
2619          "This fine tunes Feasibility Pump by doing more or fewer passes."
2620     );
2621     parameters[numberParameters-1].setIntValue(20);
2622#endif
2623#ifdef COIN_HAS_CLP
2624     parameters[numberParameters++] =
2625          CbcOrClpParam("passP!resolve", "How many passes in presolve",
2626                        -200, 100, CLP_PARAM_INT_PRESOLVEPASS, 1);
2627     parameters[numberParameters-1].setLonghelp
2628     (
2629          "Normally Presolve does 5 passes but you may want to do less to make it\
2630 more lightweight or do more if improvements are still being made.  As Presolve will return\
2631 if nothing is being taken out, you should not normally need to use this fine tuning."
2632     );
2633#endif
2634#ifdef COIN_HAS_CBC
2635     parameters[numberParameters++] =
2636          CbcOrClpParam("passT!reeCuts", "Number of cut passes in tree",
2637                        -9999999, 9999999, CBC_PARAM_INT_CUTPASSINTREE);
2638     parameters[numberParameters-1].setLonghelp
2639     (
2640          "The default is one pass"
2641     );
2642#endif
2643#ifdef COIN_HAS_CLP
2644     parameters[numberParameters++] =
2645          CbcOrClpParam("pertV!alue", "Method of perturbation",
2646                        -5000, 102, CLP_PARAM_INT_PERTVALUE, 1);
2647     parameters[numberParameters++] =
2648          CbcOrClpParam("perturb!ation", "Whether to perturb problem",
2649                        "on", CLP_PARAM_STR_PERTURBATION);
2650     parameters[numberParameters-1].append("off");
2651     parameters[numberParameters-1].setLonghelp
2652     (
2653          "Perturbation helps to stop cycling, but Clp uses other measures for this.\
2654  However large problems and especially ones with unit elements and unit rhs or costs\
2655 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
2656  The Clp library has this off by default.  This program has it on by default."
2657     );
2658     parameters[numberParameters++] =
2659          CbcOrClpParam("PFI", "Whether to use Product Form of Inverse in simplex",
2660                        "off", CLP_PARAM_STR_PFI, 7, 0);
2661     parameters[numberParameters-1].append("on");
2662     parameters[numberParameters-1].setLonghelp
2663     (
2664          "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
2665     );
2666#endif
2667#ifdef COIN_HAS_CBC
2668     parameters[numberParameters++] =
2669          CbcOrClpParam("pivotAndC!omplement", "Whether to try Pivot and Complement heuristic",
2670                        "off", CBC_PARAM_STR_PIVOTANDCOMPLEMENT);
2671     parameters[numberParameters-1].append("on");
2672     parameters[numberParameters-1].append("both");
2673     parameters[numberParameters-1].append("before");
2674     parameters[numberParameters-1].setLonghelp
2675     (
2676          "stuff needed. \
2677Doh option does heuristic before preprocessing"     );
2678     parameters[numberParameters++] =
2679          CbcOrClpParam("pivotAndF!ix", "Whether to try Pivot and Fix heuristic",
2680                        "off", CBC_PARAM_STR_PIVOTANDFIX);
2681     parameters[numberParameters-1].append("on");
2682     parameters[numberParameters-1].append("both");
2683     parameters[numberParameters-1].append("before");
2684     parameters[numberParameters-1].setLonghelp
2685     (
2686          "stuff needed. \
2687Doh option does heuristic before preprocessing"     );
2688#endif
2689#ifdef COIN_HAS_CLP
2690     parameters[numberParameters++] =
2691          CbcOrClpParam("plus!Minus", "Tries to make +- 1 matrix",
2692                        CLP_PARAM_ACTION_PLUSMINUS, 7, 0);
2693     parameters[numberParameters-1].setLonghelp
2694     (
2695          "Clp will go slightly faster if the matrix can be converted so that the elements are\
2696 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
2697 see if it can convert the problem so you should not need to use this."
2698     );
2699     parameters[numberParameters++] =
2700          CbcOrClpParam("pO!ptions", "Dubious print options",
2701                        0, COIN_INT_MAX, CLP_PARAM_INT_PRINTOPTIONS, 1);
2702     parameters[numberParameters-1].setIntValue(0);
2703     parameters[numberParameters-1].setLonghelp
2704     (
2705          "If this is > 0 then presolve will give more information and branch and cut will give statistics"
2706     );
2707     parameters[numberParameters++] =
2708          CbcOrClpParam("preO!pt", "Presolve options",
2709                        0, COIN_INT_MAX, CLP_PARAM_INT_PRESOLVEOPTIONS, 0);
2710#endif
2711     parameters[numberParameters++] =
2712          CbcOrClpParam("presolve", "Whether to presolve problem",
2713                        "on", CLP_PARAM_STR_PRESOLVE);
2714     parameters[numberParameters-1].append("off");
2715     parameters[numberParameters-1].append("more");
2716     parameters[numberParameters-1].append("file");
2717     parameters[numberParameters-1].setLonghelp
2718     (
2719          "Presolve analyzes the model to find such things as redundant equations, equations\
2720 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
2721 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
2722on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
2723to write the original to file using 'file'."
2724     );
2725#ifdef COIN_HAS_CBC
2726     parameters[numberParameters++] =
2727          CbcOrClpParam("preprocess", "Whether to use integer preprocessing",
2728                        "off", CBC_PARAM_STR_PREPROCESS);
2729     parameters[numberParameters-1].append("on");
2730     parameters[numberParameters-1].append("save");
2731     parameters[numberParameters-1].append("equal");
2732     parameters[numberParameters-1].append("sos");
2733     parameters[numberParameters-1].append("trysos");
2734     parameters[numberParameters-1].append("equalall");
2735     parameters[numberParameters-1].append("strategy");
2736     parameters[numberParameters-1].append("aggregate");
2737     parameters[numberParameters-1].append("forcesos");
2738     parameters[numberParameters-1].setLonghelp
2739     (
2740          "This tries to reduce size of model in a similar way to presolve and \
2741it also tries to strengthen the model - this can be very useful and is worth trying. \
2742 Save option saves on file presolved.mps.  equal will turn <= cliques into \
2743==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
2744and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
2745valid inequalities into equalities with integer slacks.  strategy is as \
2746on but uses CbcStrategy."
2747     );
2748#endif
2749#ifdef COIN_HAS_CLP
2750     parameters[numberParameters++] =
2751          CbcOrClpParam("preT!olerance", "Tolerance to use in presolve",
2752                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRESOLVETOLERANCE);
2753     parameters[numberParameters-1].setLonghelp
2754     (
2755          "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
2756infeasible and you have awkward numbers and you are sure the problem is really feasible."
2757     );
2758     parameters[numberParameters++] =
2759          CbcOrClpParam("primalP!ivot", "Primal pivot choice algorithm",
2760                        "auto!matic", CLP_PARAM_STR_PRIMALPIVOT, 7, 1);
2761     parameters[numberParameters-1].append("exa!ct");
2762     parameters[numberParameters-1].append("dant!zig");
2763     parameters[numberParameters-1].append("part!ial");
2764     parameters[numberParameters-1].append("steep!est");
2765     parameters[numberParameters-1].append("change");
2766     parameters[numberParameters-1].append("sprint");
2767     parameters[numberParameters-1].setLonghelp
2768     (
2769          "Clp can use any pivot selection algorithm which the user codes as long as it\
2770 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
2771 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
2772 are two variants which keep all weights updated but only scan a subset each iteration.\
2773 Partial switches this on while change initially does dantzig until the factorization\
2774 becomes denser.  This is still a work in progress."
2775     );
2776     parameters[numberParameters++] =
2777          CbcOrClpParam("primalS!implex", "Do primal simplex algorithm",
2778                        CLP_PARAM_ACTION_PRIMALSIMPLEX);
2779     parameters[numberParameters-1].setLonghelp
2780     (
2781          "This command solves the current model using the primal algorithm.\
2782  The default is to use exact devex.\
2783 The time and iterations may be affected by settings such as presolve, scaling, crash\
2784 and also by column selection  method, infeasibility weight and dual and primal tolerances."
2785     );
2786#endif
2787     parameters[numberParameters++] =
2788          CbcOrClpParam("primalT!olerance", "For an optimal solution \
2789no primal infeasibility may exceed this value",
2790                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRIMALTOLERANCE);
2791     parameters[numberParameters-1].setLonghelp
2792     (
2793          "Normally the default tolerance is fine, but you may want to increase it a\
2794 bit if a primal run seems to be having a hard time"
2795     );
2796#ifdef COIN_HAS_CLP
2797     parameters[numberParameters++] =
2798          CbcOrClpParam("primalW!eight", "Initially algorithm acts as if it \
2799costs this much to be infeasible",
2800                        1.0e-20, 1.0e20, CLP_PARAM_DBL_PRIMALWEIGHT);
2801     parameters[numberParameters-1].setLonghelp
2802     (
2803          "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
2804 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
2805 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
2806  Too high a value may mean more iterations, while too low a bound means\
2807 the code may go all the way and then have to increase the weight in order to get feasible.\
2808  OSL had a heuristic to\
2809 adjust bounds, maybe we need that here."
2810     );
2811#endif
2812     parameters[numberParameters++] =
2813          CbcOrClpParam("printi!ngOptions", "Print options",
2814                        "normal", CLP_PARAM_STR_INTPRINT, 3);
2815     parameters[numberParameters-1].append("integer");
2816     parameters[numberParameters-1].append("special");
2817     parameters[numberParameters-1].append("rows");
2818     parameters[numberParameters-1].append("all");
2819     parameters[numberParameters-1].append("csv");
2820     parameters[numberParameters-1].append("bound!ranging");
2821     parameters[numberParameters-1].append("rhs!ranging");
2822     parameters[numberParameters-1].append("objective!ranging");
2823     parameters[numberParameters-1].setLonghelp
2824     (
2825          "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
2826integer - nonzero integer column variables\n\
2827special - in format suitable for OsiRowCutDebugger\n\
2828rows - nonzero column variables and row activities\n\
2829all - all column variables and row activities.\n\
2830\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
2831Also see printMask for controlling output."
2832     );
2833     parameters[numberParameters++] =
2834          CbcOrClpParam("printM!ask", "Control printing of solution on a  mask",
2835                        CLP_PARAM_ACTION_PRINTMASK, 3);
2836     parameters[numberParameters-1].setLonghelp
2837     (
2838          "If set then only those names which match mask are printed in a solution. \
2839'?' matches any character and '*' matches any set of characters. \
2840 The default is '' i.e. unset so all variables are printed. \
2841This is only active if model has names."
2842     );
2843#ifdef COIN_HAS_CBC
2844     parameters[numberParameters++] =
2845          CbcOrClpParam("prio!rityIn", "Import priorities etc from file",
2846                        CBC_PARAM_ACTION_PRIORITYIN, 3);
2847     parameters[numberParameters-1].setLonghelp
2848     (
2849          "This will read a file with priorities from the given file name.  It will use the default\
2850 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2851 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2852File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
2853 name and number must be given."
2854     );
2855     parameters[numberParameters++] =
2856          CbcOrClpParam("probing!Cuts", "Whether to use Probing cuts",
2857                        "off", CBC_PARAM_STR_PROBINGCUTS);
2858     parameters[numberParameters-1].append("on");
2859     parameters[numberParameters-1].append("root");
2860     parameters[numberParameters-1].append("ifmove");
2861     parameters[numberParameters-1].append("forceOn");
2862     parameters[numberParameters-1].append("onglobal");
2863     parameters[numberParameters-1].append("forceonglobal");
2864     parameters[numberParameters-1].append("forceOnBut");
2865     parameters[numberParameters-1].append("forceOnStrong");
2866     parameters[numberParameters-1].append("forceOnButStrong");
2867     parameters[numberParameters-1].append("strongRoot");
2868     parameters[numberParameters-1].setLonghelp
2869     (
2870          "This switches on probing cuts (either at root or in entire tree) \
2871See branchAndCut for information on options. \
2872but strong options do more probing"
2873     );
2874     parameters[numberParameters++] =
2875          CbcOrClpParam("proximity!Search", "Whether to do proximity search heuristic",
2876                        "off", CBC_PARAM_STR_PROXIMITY);
2877     parameters[numberParameters-1].append("on");
2878     parameters[numberParameters-1].append("both");
2879     parameters[numberParameters-1].append("before");
2880     parameters[numberParameters-1].append("10");
2881     parameters[numberParameters-1].append("100");
2882     parameters[numberParameters-1].append("300");
2883     parameters[numberParameters-1].setLonghelp
2884     (
2885          "This switches on a heuristic which looks for a solution close \
2886to incumbent solution (Fischetti and Monaci). \
2887See Rounding for meaning of on,both,before. \
2888The ones at end have different maxNode settings (and are 'on'(on==30))."
2889     );
2890     parameters[numberParameters++] =
2891          CbcOrClpParam("pumpC!utoff", "Fake cutoff for use in feasibility pump",
2892                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKECUTOFF);
2893     parameters[numberParameters-1].setDoubleValue(0.0);
2894     parameters[numberParameters-1].setLonghelp
2895     (
2896          "0.0 off - otherwise add a constraint forcing objective below this value\
2897 in feasibility pump"
2898     );
2899     parameters[numberParameters++] =
2900          CbcOrClpParam("pumpI!ncrement", "Fake increment for use in feasibility pump",
2901                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKEINCREMENT, 1);
2902     parameters[numberParameters-1].setDoubleValue(0.0);
2903     parameters[numberParameters-1].setLonghelp
2904     (
2905          "0.0 off - otherwise use as absolute increment to cutoff \
2906when solution found in feasibility pump"
2907     );
2908     parameters[numberParameters++] =
2909          CbcOrClpParam("pumpT!une", "Dubious ideas for feasibility pump",
2910                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE);
2911     parameters[numberParameters-1].setLonghelp
2912     (
2913          "This fine tunes Feasibility Pump \n\
2914\t>=10000000 use as objective weight switch\n\
2915\t>=1000000 use as accumulate switch\n\
2916\t>=1000 use index+1 as number of large loops\n\
2917\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\
2918\t%100 == 10,20 affects how each solve is done\n\
2919\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \
2920If accumulate is on then after a major pass, variables which have not moved \
2921are fixed and a small branch and bound is tried."
2922     );
2923     parameters[numberParameters-1].setIntValue(0);
2924#endif
2925     parameters[numberParameters++] =
2926          CbcOrClpParam("quit", "Stops clp execution",
2927                        CLP_PARAM_ACTION_EXIT);
2928     parameters[numberParameters-1].setLonghelp
2929     (
2930          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2931     );
2932#ifdef COIN_HAS_CBC
2933     parameters[numberParameters++] =
2934          CbcOrClpParam("rand!omizedRounding", "Whether to try randomized rounding heuristic",
2935                        "off", CBC_PARAM_STR_RANDROUND);
2936     parameters[numberParameters-1].append("on");
2937     parameters[numberParameters-1].append("both");
2938     parameters[numberParameters-1].append("before");
2939     parameters[numberParameters-1].setLonghelp
2940     (
2941          "stuff needed. \
2942Doh option does heuristic before preprocessing"     );
2943     parameters[numberParameters++] =
2944          CbcOrClpParam("ratio!Gap", "Stop when gap between best possible and \
2945best less than this fraction of larger of two",
2946                        0.0, 1.0e20, CBC_PARAM_DBL_GAPRATIO);
2947     parameters[numberParameters-1].setDoubleValue(0.0);
2948     parameters[numberParameters-1].setLonghelp
2949     (
2950          "If the gap between best solution and best possible solution is less than this fraction \
2951of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
2952way of using absolute value rather than fraction."
2953     );
2954     parameters[numberParameters++] =
2955          CbcOrClpParam("readS!tored", "Import stored cuts from file",
2956                        CLP_PARAM_ACTION_STOREDFILE, 3, 0);
2957#endif
2958#ifdef COIN_HAS_CLP
2959     parameters[numberParameters++] =
2960          CbcOrClpParam("reallyO!bjectiveScale", "Scale factor to apply to objective in place",
2961                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE2, 0);
2962     parameters[numberParameters-1].setLonghelp
2963     (
2964          "You can set this to -1.0 to test maximization or other to stress code"
2965     );
2966     parameters[numberParameters-1].setDoubleValue(1.0);
2967     parameters[numberParameters++] =
2968          CbcOrClpParam("reallyS!cale", "Scales model in place",
2969                        CLP_PARAM_ACTION_REALLY_SCALE, 7, 0);
2970#endif
2971#ifdef COIN_HAS_CBC
2972     parameters[numberParameters++] =
2973          CbcOrClpParam("reduce!AndSplitCuts", "Whether to use Reduce-and-Split cuts",
2974                        "off", CBC_PARAM_STR_REDSPLITCUTS);
2975     parameters[numberParameters-1].append("on");
2976     parameters[numberParameters-1].append("root");
2977     parameters[numberParameters-1].append("ifmove");
2978     parameters[numberParameters-1].append("forceOn");
2979     parameters[numberParameters-1].setLonghelp
2980     (
2981          "This switches on reduce and split  cuts (either at root or in entire tree) \
2982See branchAndCut for information on options."
2983     );
2984     parameters[numberParameters++] =
2985          CbcOrClpParam("residual!CapacityCuts", "Whether to use Residual Capacity cuts",
2986                        "off", CBC_PARAM_STR_RESIDCUTS);
2987     parameters[numberParameters-1].append("on");
2988     parameters[numberParameters-1].append("root");
2989     parameters[numberParameters-1].append("ifmove");
2990     parameters[numberParameters-1].append("forceOn");
2991     parameters[numberParameters-1].setLonghelp
2992     (
2993          "Residual capacity cuts. \
2994See branchAndCut for information on options."
2995     );
2996#endif
2997#ifdef COIN_HAS_CLP
2998     parameters[numberParameters++] =
2999          CbcOrClpParam("restore!Model", "Restore model from binary file",
3000                        CLP_PARAM_ACTION_RESTORE, 7, 1);
3001     parameters[numberParameters-1].setLonghelp
3002     (
3003          "This reads data save by saveModel from the given file.  It will use the default\
3004 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3005 is initialized to 'default.prob'."
3006     );
3007     parameters[numberParameters++] =
3008          CbcOrClpParam("reverse", "Reverses sign of objective",
3009                        CLP_PARAM_ACTION_REVERSE, 7, 0);
3010     parameters[numberParameters-1].setLonghelp
3011     (
3012          "Useful for testing if maximization works correctly"
3013     );
3014     parameters[numberParameters++] =
3015          CbcOrClpParam("rhs!Scale", "Scale factor to apply to rhs and bounds",
3016                        -1.0e20, 1.0e20, CLP_PARAM_DBL_RHSSCALE, 0);
3017     parameters[numberParameters-1].setLonghelp
3018     (
3019          "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
3020 internally by this amount.  It can also be set by autoscale.  This should not be needed."
3021     );
3022     parameters[numberParameters-1].setDoubleValue(1.0);
3023#endif
3024#ifdef COIN_HAS_CBC
3025     parameters[numberParameters++] =
3026          CbcOrClpParam("Rens", "Whether to try Relaxation Enforced Neighborhood Search",
3027                        "off", CBC_PARAM_STR_RENS);
3028     parameters[numberParameters-1].append("on");
3029     parameters[numberParameters-1].append("both");
3030     parameters[numberParameters-1].append("before");
3031     parameters[numberParameters-1].append("200");
3032     parameters[numberParameters-1].append("1000");
3033     parameters[numberParameters-1].append("10000");
3034     parameters[numberParameters-1].append("dj");
3035     parameters[numberParameters-1].append("djbefore");
3036     parameters[numberParameters-1].setLonghelp
3037     (
3038          "This switches on Relaxation enforced neighborhood Search. \
3039on just does 50 nodes \
3040200 or 1000 does that many nodes. \
3041Doh option does heuristic before preprocessing"     );
3042     parameters[numberParameters++] =
3043          CbcOrClpParam("Rins", "Whether to try Relaxed Induced Neighborhood Search",
3044                        "off", CBC_PARAM_STR_RINS);
3045     parameters[numberParameters-1].append("on");
3046     parameters[numberParameters-1].append("both");
3047     parameters[numberParameters-1].append("before");
3048     parameters[numberParameters-1].append("often");
3049     parameters[numberParameters-1].setLonghelp
3050     (
3051          "This switches on Relaxed induced neighborhood Search. \
3052Doh option does heuristic before preprocessing"     );
3053     parameters[numberParameters++] =
3054          CbcOrClpParam("round!ingHeuristic", "Whether to use Rounding heuristic",
3055                        "off", CBC_PARAM_STR_ROUNDING);
3056     parameters[numberParameters-1].append("on");
3057     parameters[numberParameters-1].append("both");
3058     parameters[numberParameters-1].append("before");
3059     parameters[numberParameters-1].setLonghelp
3060     (
3061          "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
3062On means do in solve i.e. after preprocessing, \
3063Before means do if doHeuristics used, off otherwise, \
3064and both means do if doHeuristics and in solve."
3065     );
3066
3067#endif
3068     parameters[numberParameters++] =
3069          CbcOrClpParam("saveM!odel", "Save model to binary file",
3070                        CLP_PARAM_ACTION_SAVE, 7, 1);
3071     parameters[numberParameters-1].setLonghelp
3072     (
3073          "This will save the problem to the given file name for future use\
3074 by restoreModel.  It will use the default\
3075 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3076 is initialized to 'default.prob'."
3077     );
3078     parameters[numberParameters++] =
3079          CbcOrClpParam("saveS!olution", "saves solution to file",
3080                        CLP_PARAM_ACTION_SAVESOL);
3081     parameters[numberParameters-1].setLonghelp
3082     (
3083          "This will write a binary solution file to the given file name.  It will use the default\
3084 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3085 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
3086and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
3087activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
3088If name contains '_fix_read_' then does not write but reads and will fix all variables"
3089     );
3090     parameters[numberParameters++] =
3091          CbcOrClpParam("scal!ing", "Whether to scale problem",
3092                        "off", CLP_PARAM_STR_SCALING);
3093     parameters[numberParameters-1].append("equi!librium");
3094     parameters[numberParameters-1].append("geo!metric");
3095     parameters[numberParameters-1].append("auto!matic");
3096     parameters[numberParameters-1].append("dynamic");
3097     parameters[numberParameters-1].append("rows!only");
3098     parameters[numberParameters-1].setLonghelp
3099     (
3100          "Scaling can help in solving problems which might otherwise fail because of lack of\
3101 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
3102 of elements is small.  When unscaled it is possible that there may be small primal and/or\
3103 infeasibilities."
3104     );
3105     parameters[numberParameters-1].setCurrentOption(3); // say auto
3106#ifndef COIN_HAS_CBC
3107     parameters[numberParameters++] =
3108          CbcOrClpParam("sec!onds", "Maximum seconds",
3109                        -1.0, 1.0e12, CLP_PARAM_DBL_TIMELIMIT);
3110     parameters[numberParameters-1].setLonghelp
3111     (
3112          "After this many seconds clp will act as if maximum iterations had been reached \
3113(if value >=0)."
3114     );
3115#else
3116     parameters[numberParameters++] =
3117          CbcOrClpParam("sec!onds", "maximum seconds",
3118                        -1.0, 1.0e12, CBC_PARAM_DBL_TIMELIMIT_BAB);
3119     parameters[numberParameters-1].setLonghelp
3120     (
3121          "After this many seconds coin solver will act as if maximum nodes had been reached."
3122     );
3123#endif
3124     parameters[numberParameters++] =
3125          CbcOrClpParam("sleep", "for debug",
3126                        CLP_PARAM_ACTION_DUMMY, 7, 0);
3127     parameters[numberParameters-1].setLonghelp
3128     (
3129          "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
3130     );
3131#ifdef COIN_HAS_CLP
3132     parameters[numberParameters++] =
3133          CbcOrClpParam("slp!Value", "Number of slp passes before primal",
3134                        -1, 50000, CLP_PARAM_INT_SLPVALUE, 1);
3135     parameters[numberParameters-1].setLonghelp
3136     (
3137          "If you are solving a quadratic problem using primal then it may be helpful to do some \
3138sequential Lps to get a good approximate solution."
3139     );
3140#if CLP_MULTIPLE_FACTORIZATIONS > 0
3141     parameters[numberParameters++] =
3142          CbcOrClpParam("small!Factorization", "Whether to use small factorization",
3143                        -1, 10000, CBC_PARAM_INT_SMALLFACT, 1);
3144     parameters[numberParameters-1].setLonghelp
3145     (
3146          "If processed problem <= this use small factorization"
3147     );
3148     parameters[numberParameters-1].setIntValue(-1);
3149#endif
3150#endif
3151     parameters[numberParameters++] =
3152          CbcOrClpParam("solu!tion", "Prints solution to file",
3153                        CLP_PARAM_ACTION_SOLUTION);
3154     parameters[numberParameters-1].setLonghelp
3155     (
3156          "This will write a primitive solution file to the given file name.  It will use the default\
3157 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3158 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
3159     );
3160#ifdef COIN_HAS_CLP
3161#ifdef COIN_HAS_CBC
3162     parameters[numberParameters++] =
3163          CbcOrClpParam("solv!e", "Solve problem",
3164                        CBC_PARAM_ACTION_BAB);
3165     parameters[numberParameters-1].setLonghelp
3166     (
3167          "If there are no integer variables then this just solves LP.  If there are integer variables \
3168this does branch and cut."
3169     );
3170     parameters[numberParameters++] =
3171          CbcOrClpParam("sos!Options", "Whether to use SOS from AMPL",
3172                        "off", CBC_PARAM_STR_SOS);
3173     parameters[numberParameters-1].append("on");
3174     parameters[numberParameters-1].setCurrentOption("on");
3175     parameters[numberParameters-1].setLonghelp
3176     (
3177          "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
3178 be turned off - this does so."
3179     );
3180     parameters[numberParameters++] =
3181          CbcOrClpParam("slog!Level", "Level of detail in (LP) Solver output",
3182                        -1, 63, CLP_PARAM_INT_SOLVERLOGLEVEL);
3183     parameters[numberParameters-1].setLonghelp
3184     (
3185          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
3186 value for most uses, while 2 and 3 give more information.  This parameter is only used inside MIP - for Clp use 'log'"
3187     );
3188#else
3189     // allow solve as synonym for dual
3190     parameters[numberParameters++] =
3191          CbcOrClpParam("solv!e", "Solve problem using dual simplex",
3192                        CBC_PARAM_ACTION_BAB);
3193     parameters[numberParameters-1].setLonghelp
3194     (
3195          "Just so can use solve for clp as well as in cbc"
3196     );
3197#endif
3198#endif
3199#ifdef COIN_HAS_CLP
3200     parameters[numberParameters++] =
3201          CbcOrClpParam("spars!eFactor", "Whether factorization treated as sparse",
3202                        "on", CLP_PARAM_STR_SPARSEFACTOR, 7, 0);
3203     parameters[numberParameters-1].append("off");
3204     parameters[numberParameters++] =
3205          CbcOrClpParam("special!Options", "Dubious options for Simplex - see ClpSimplex.hpp",
3206                        0, COIN_INT_MAX, CLP_PARAM_INT_SPECIALOPTIONS, 0);
3207     parameters[numberParameters++] =
3208          CbcOrClpParam("sprint!Crash", "Whether to try sprint crash",
3209                        -1, 5000000, CLP_PARAM_INT_SPRINT);
3210     parameters[numberParameters-1].setLonghelp
3211     (
3212          "For long and thin problems this program may solve a series of small problems\
3213 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
3214 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
3215  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
3216     );
3217     parameters[numberParameters++] =
3218          CbcOrClpParam("stat!istics", "Print some statistics",
3219                        CLP_PARAM_ACTION_STATISTICS);
3220     parameters[numberParameters-1].setLonghelp
3221     (
3222          "This command prints some statistics for the current model.\
3223 If log level >1 then more is printed.\
3224 These are for presolved model if presolve on (and unscaled)."
3225     );
3226#endif
3227     parameters[numberParameters++] =
3228          CbcOrClpParam("stop", "Stops clp execution",
3229                        CLP_PARAM_ACTION_EXIT);
3230     parameters[numberParameters-1].setLonghelp
3231     (
3232          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3233     );
3234#ifdef COIN_HAS_CBC
3235     parameters[numberParameters++] =
3236          CbcOrClpParam("strat!egy", "Switches on groups of features",
3237                        0, 2, CBC_PARAM_INT_STRATEGY);
3238     parameters[numberParameters-1].setLonghelp
3239     (
3240          "This turns on newer features. \
3241Use 0 for easy problems, 1 is default, 2 is aggressive. \
32421 uses Gomory cuts using tolerance of 0.01 at root, \
3243does a possible restart after 100 nodes if can fix many \
3244and activates a diving and RINS heuristic and makes feasibility pump \
3245more aggressive. \
3246This does not apply to unit tests (where 'experiment' may have similar effects)."
3247     );
3248     parameters[numberParameters-1].setIntValue(1);
3249#ifdef CBC_KEEP_DEPRECATED
3250     parameters[numberParameters++] =
3251          CbcOrClpParam("strengthen", "Create strengthened problem",
3252                        CBC_PARAM_ACTION_STRENGTHEN, 3);
3253     parameters[numberParameters-1].setLonghelp
3254     (
3255          "This creates a new problem by applying the root node cuts.  All tight constraints \
3256will be in resulting problem"
3257     );
3258#endif
3259     parameters[numberParameters++] =
3260          CbcOrClpParam("strong!Branching", "Number of variables to look at in strong branching",
3261                        0, 999999, CBC_PARAM_INT_STRONGBRANCHING);
3262     parameters[numberParameters-1].setLonghelp
3263     (
3264          "In order to decide which variable to branch on, the code will choose up to this number \
3265of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
3266If a variable is branched on many times then the previous average up and down costs may be used - \
3267see number before trust."
3268     );
3269#endif
3270#ifdef COIN_HAS_CLP
3271     parameters[numberParameters++] =
3272          CbcOrClpParam("subs!titution", "How long a column to substitute for in presolve",
3273                        0, 10000, CLP_PARAM_INT_SUBSTITUTION, 0);
3274     parameters[numberParameters-1].setLonghelp
3275     (
3276          "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
3277 variables in column.  If you increase this the number of rows may decrease but number of \
3278 elements may increase."
3279     );
3280#endif
3281#ifdef COIN_HAS_CBC
3282     parameters[numberParameters++] =
3283          CbcOrClpParam("testO!si", "Test OsiObject stuff",
3284                        -1, COIN_INT_MAX, CBC_PARAM_INT_TESTOSI, 0);
3285#endif
3286#ifdef CBC_THREAD
3287     parameters[numberParameters++] =
3288          CbcOrClpParam("thread!s", "Number of threads to try and use",
3289                        -100, 100000, CBC_PARAM_INT_THREADS, 1);
3290     parameters[numberParameters-1].setLonghelp
3291     (
3292          "To use multiple threads, set threads to number wanted.  It may be better \
3293to use one or two more than number of cpus available.  If 100+n then n threads and \
3294search is repeatable (maybe be somewhat slower), \
3295if 200+n use threads for root cuts, 400+n threads used in sub-trees."
3296     );
3297#endif
3298#ifdef COIN_HAS_CBC
3299     parameters[numberParameters++] =
3300          CbcOrClpParam("tighten!Factor", "Tighten bounds using this times largest \
3301activity at continuous solution",
3302                        1.0e-3, 1.0e20, CBC_PARAM_DBL_TIGHTENFACTOR, 0);
3303     parameters[numberParameters-1].setLonghelp
3304     (
3305          "This sleazy trick can help on some problems."
3306     );
3307#endif
3308#ifdef COIN_HAS_CLP
3309     parameters[numberParameters++] =
3310          CbcOrClpParam("tightLP", "Poor person's preSolve for now",
3311                        CLP_PARAM_ACTION_TIGHTEN, 7, 0);
3312#endif
3313     parameters[numberParameters++] =
3314          CbcOrClpParam("timeM!ode", "Whether to use CPU or elapsed time",
3315                        "cpu", CLP_PARAM_STR_TIME_MODE);
3316     parameters[numberParameters-1].append("elapsed");
3317     parameters[numberParameters-1].setLonghelp
3318     (
3319          "cpu uses CPU time for stopping, while elapsed uses elapsed time. \
3320(On Windows, elapsed time is always used)."
3321     );
3322#ifdef COIN_HAS_CBC
3323     parameters[numberParameters++] =
3324          CbcOrClpParam("trust!PseudoCosts", "Number of branches before we trust pseudocosts",
3325                        -3, 2000000000, CBC_PARAM_INT_NUMBERBEFORE);
3326     parameters[numberParameters-1].setLonghelp
3327     (
3328          "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
3329trust the pseudo costs and do not do any more strong branching."
3330     );
3331#endif
3332#ifdef COIN_HAS_CBC
3333     parameters[numberParameters++] =
3334          CbcOrClpParam("tune!PreProcess", "Dubious tuning parameters",
3335                        0, 20000000, CLP_PARAM_INT_PROCESSTUNE, 1);
3336     parameters[numberParameters-1].setLonghelp
3337     (
3338          "For making equality cliques this is minimumsize.  Also for adding \
3339integer slacks.  May be used for more later \
3340If <10000 that is what it does.  If <1000000 - numberPasses is (value/10000)-1 and tune is tune %10000. \
3341If >= 1000000! - numberPasses is (value/1000000)-1 and tune is tune %1000000.  In this case if tune is now still >=10000 \
3342numberPassesPerInnerLoop is changed from 10 to (tune-10000)-1 and tune becomes tune % 10000!!!!! - happy? - \
3343so to keep normal limit on cliques of 5, do 3 major passes (include presolves) but only doing one tightening pass per major pass - \
3344you would use 3010005 (I think)"
3345     );
3346     parameters[numberParameters++] =
3347          CbcOrClpParam("two!MirCuts", "Whether to use Two phase Mixed Integer Rounding cuts",
3348                        "off", CBC_PARAM_STR_TWOMIRCUTS);
3349     parameters[numberParameters-1].append("on");
3350     parameters[numberParameters-1].append("root");
3351     parameters[numberParameters-1].append("ifmove");
3352     parameters[numberParameters-1].append("forceOn");
3353     parameters[numberParameters-1].append("onglobal");
3354     parameters[numberParameters-1].append("forceandglobal");
3355     parameters[numberParameters-1].append("forceLongOn");
3356     parameters[numberParameters-1].setLonghelp
3357     (
3358          "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
3359See branchAndCut for information on options."
3360     );
3361#endif
3362     parameters[numberParameters++] =
3363          CbcOrClpParam("unitTest", "Do unit test",
3364                        CLP_PARAM_ACTION_UNITTEST, 3, 1);
3365     parameters[numberParameters-1].setLonghelp
3366     (
3367          "This exercises the unit test for clp"
3368     );
3369     parameters[numberParameters++] =
3370          CbcOrClpParam("userClp", "Hand coded Clp stuff",
3371                        CLP_PARAM_ACTION_USERCLP, 0, 0);
3372     parameters[numberParameters-1].setLonghelp
3373     (
3374          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3375Look for USERCLP in main driver and modify sample code."
3376     );
3377#ifdef COIN_HAS_CBC
3378     parameters[numberParameters++] =
3379          CbcOrClpParam("userCbc", "Hand coded Cbc stuff",
3380                        CBC_PARAM_ACTION_USERCBC, 0, 0);
3381     parameters[numberParameters-1].setLonghelp
3382     (
3383          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3384Look for USERCBC in main driver and modify sample code. \
3385It is possible you can get same effect by using example driver4.cpp."
3386     );
3387     parameters[numberParameters++] =
3388          CbcOrClpParam("Vnd!VariableNeighborhoodSearch", "Whether to try Variable Neighborhood Search",
3389                        "off", CBC_PARAM_STR_VND);
3390     parameters[numberParameters-1].append("on");
3391     parameters[numberParameters-1].append("both");
3392     parameters[numberParameters-1].append("before");
3393     parameters[numberParameters-1].append("intree");
3394     parameters[numberParameters-1].setLonghelp
3395     (
3396          "This switches on variable neighborhood Search. \
3397Doh option does heuristic before preprocessing"     );
3398#endif
3399     parameters[numberParameters++] =
3400          CbcOrClpParam("vector", "Whether to use vector? Form of matrix in simplex",
3401                        "off", CLP_PARAM_STR_VECTOR, 7, 0);
3402     parameters[numberParameters-1].append("on");
3403     parameters[numberParameters-1].setLonghelp
3404     (
3405          "If this is on ClpPackedMatrix uses extra column copy in odd format."
3406     );
3407     parameters[numberParameters++] =
3408          CbcOrClpParam("verbose", "Switches on longer help on single ?",
3409                        0, 31, CLP_PARAM_INT_VERBOSE, 0);
3410     parameters[numberParameters-1].setLonghelp
3411     (
3412          "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
3413     );
3414     parameters[numberParameters-1].setIntValue(0);
3415#ifdef COIN_HAS_CBC
3416     parameters[numberParameters++] =
3417          CbcOrClpParam("vub!heuristic", "Type of vub heuristic",
3418                        -2, 20, CBC_PARAM_INT_VUBTRY, 0);
3419     parameters[numberParameters-1].setLonghelp
3420     (
3421          "If set will try and fix some integer variables"
3422     );
3423     parameters[numberParameters-1].setIntValue(-1);
3424#ifdef ZERO_HALF_CUTS
3425     parameters[numberParameters++] =
3426          CbcOrClpParam("zero!HalfCuts", "Whether to use zero half cuts",
3427                        "off", CBC_PARAM_STR_ZEROHALFCUTS);
3428     parameters[numberParameters-1].append("on");
3429     parameters[numberParameters-1].append("root");
3430     parameters[numberParameters-1].append("ifmove");
3431     parameters[numberParameters-1].append("forceOn");
3432     parameters[numberParameters-1].append("onglobal");
3433     parameters[numberParameters-1].setLonghelp
3434     (
3435          "This switches on zero-half cuts (either at root or in entire tree) \
3436See branchAndCut for information on options."
3437     );
3438#endif
3439#endif
3440     parameters[numberParameters++] =
3441          CbcOrClpParam("zeroT!olerance", "Kill all coefficients \
3442whose absolute value is less than this value",
3443                        1.0e-100, 1.0e-5, CLP_PARAM_DBL_ZEROTOLERANCE);
3444     parameters[numberParameters-1].setLonghelp
3445     (
3446          "This applies to reading mps files (and also lp files \
3447if KILL_ZERO_READLP defined)"
3448     );
3449     parameters[numberParameters-1].setDoubleValue(1.0e-20);
3450     assert(numberParameters < CBCMAXPARAMETERS);
3451}
3452// Given a parameter type - returns its number in list
3453int whichParam (CbcOrClpParameterType name,
3454                int numberParameters, CbcOrClpParam *const parameters)
3455{
3456     int i;
3457     for (i = 0; i < numberParameters; i++) {
3458          if (parameters[i].type() == name)
3459               break;
3460     }
3461     assert (i < numberParameters);
3462     return i;
3463}
3464#ifdef COIN_HAS_CLP
3465/* Restore a solution from file.
3466   mode 0 normal, 1 swap rows and columns and primal and dual
3467   if 2 set then also change signs
3468*/
3469void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode)
3470{
3471     FILE * fp = fopen(fileName.c_str(), "rb");
3472     if (fp) {
3473          int numberRows = lpSolver->numberRows();
3474          int numberColumns = lpSolver->numberColumns();
3475          int numberRowsFile;
3476          int numberColumnsFile;
3477          double objectiveValue;
3478          size_t nRead;
3479          nRead = fread(&numberRowsFile, sizeof(int), 1, fp);
3480          if (nRead != 1)
3481               throw("Error in fread");
3482          nRead = fread(&numberColumnsFile, sizeof(int), 1, fp);
3483          if (nRead != 1)
3484               throw("Error in fread");
3485          nRead = fread(&objectiveValue, sizeof(double), 1, fp);
3486          if (nRead != 1)
3487               throw("Error in fread");
3488          double * dualRowSolution = lpSolver->dualRowSolution();
3489          double * primalRowSolution = lpSolver->primalRowSolution();
3490          double * dualColumnSolution = lpSolver->dualColumnSolution();
3491          double * primalColumnSolution = lpSolver->primalColumnSolution();
3492          if (mode) {
3493               // swap
3494               int k = numberRows;
3495               numberRows = numberColumns;
3496               numberColumns = k;
3497               double * temp;
3498               temp = dualRowSolution;
3499               dualRowSolution = primalColumnSolution;
3500               primalColumnSolution = temp;
3501               temp = dualColumnSolution;
3502               dualColumnSolution = primalRowSolution;
3503               primalRowSolution = temp;
3504          }
3505          if (numberRows > numberRowsFile || numberColumns > numberColumnsFile) {
3506               std::cout << "Mismatch on rows and/or columns - giving up" << std::endl;
3507          } else {
3508               lpSolver->setObjectiveValue(objectiveValue);
3509               if (numberRows == numberRowsFile && numberColumns == numberColumnsFile) {
3510                    nRead = fread(primalRowSolution, sizeof(double), numberRows, fp);
3511                    if (nRead != static_cast<size_t>(numberRows))
3512                         throw("Error in fread");
3513                    nRead = fread(dualRowSolution, sizeof(double), numberRows, fp);
3514                    if (nRead != static_cast<size_t>(numberRows))
3515                         throw("Error in fread");
3516                    nRead = fread(primalColumnSolution, sizeof(double), numberColumns, fp);
3517                    if (nRead != static_cast<size_t>(numberColumns))
3518                         throw("Error in fread");
3519                    nRead = fread(dualColumnSolution, sizeof(double), numberColumns, fp);
3520                    if (nRead != static_cast<size_t>(numberColumns))
3521                         throw("Error in fread");
3522               } else {
3523                    std::cout << "Mismatch on rows and/or columns - truncating" << std::endl;
3524                    double * temp = new double [CoinMax(numberRowsFile, numberColumnsFile)];
3525                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
3526                    if (nRead != static_cast<size_t>(numberRowsFile))
3527                         throw("Error in fread");
3528                    CoinMemcpyN(temp, numberRows, primalRowSolution);
3529                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
3530                    if (nRead != static_cast<size_t>(numberRowsFile))
3531                         throw("Error in fread");
3532                    CoinMemcpyN(temp, numberRows, dualRowSolution);
3533                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
3534                    if (nRead != static_cast<size_t>(numberColumnsFile))
3535                         throw("Error in fread");
3536                    CoinMemcpyN(temp, numberColumns, primalColumnSolution);
3537                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
3538                    if (nRead != static_cast<size_t>(numberColumnsFile))
3539                         throw("Error in fread");
3540                    CoinMemcpyN(temp, numberColumns, dualColumnSolution);
3541                    delete [] temp;
3542                           }
3543               if (mode == 3) {
3544                    int i;
3545                    for (i = 0; i < numberRows; i++) {
3546                         primalRowSolution[i] = -primalRowSolution[i];
3547                         dualRowSolution[i] = -dualRowSolution[i];
3548                    }
3549                    for (i = 0; i < numberColumns; i++) {
3550                         primalColumnSolution[i] = -primalColumnSolution[i];
3551                         dualColumnSolution[i] = -dualColumnSolution[i];
3552                    }
3553               }
3554          }
3555          fclose(fp);
3556     } else {
3557          std::cout << "Unable to open file " << fileName << std::endl;
3558     }
3559}
3560// Dump a solution to file
3561void saveSolution(const ClpSimplex * lpSolver, std::string fileName)
3562{
3563     if (strstr(fileName.c_str(), "_fix_read_")) {
3564          FILE * fp = fopen(fileName.c_str(), "rb");
3565          if (fp) {
3566               ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
3567               restoreSolution(solver, fileName, 0);
3568               // fix all
3569               int logLevel = solver->logLevel();
3570               int iColumn;
3571               int numberColumns = solver->numberColumns();
3572               double * primalColumnSolution =
3573                    solver->primalColumnSolution();
3574               double * columnLower = solver->columnLower();
3575               double * columnUpper = solver->columnUpper();
3576               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3577                    double value = primalColumnSolution[iColumn];
3578                    if (value > columnUpper[iColumn]) {
3579                         if (value > columnUpper[iColumn] + 1.0e-6 && logLevel > 1)
3580                              printf("%d value of %g - bounds %g %g\n",
3581                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
3582                         value = columnUpper[iColumn];
3583                    } else if (value < columnLower[iColumn]) {
3584                         if (value < columnLower[iColumn] - 1.0e-6 && logLevel > 1)
3585                              printf("%d value of %g - bounds %g %g\n",
3586                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
3587                         value = columnLower[iColumn];
3588                    }
3589                    columnLower[iColumn] = value;
3590                    columnUpper[iColumn] = value;
3591               }
3592               return;
3593          }
3594     }
3595     FILE * fp = fopen(fileName.c_str(), "wb");
3596     if (fp) {
3597          int numberRows = lpSolver->numberRows();
3598          int numberColumns = lpSolver->numberColumns();
3599          double objectiveValue = lpSolver->objectiveValue();
3600          size_t nWrite;
3601          nWrite = fwrite(&numberRows, sizeof(int), 1, fp);
3602          if (nWrite != 1)
3603               throw("Error in fwrite");
3604          nWrite = fwrite(&numberColumns, sizeof(int), 1, fp);
3605          if (nWrite != 1)
3606               throw("Error in fwrite");
3607          nWrite = fwrite(&objectiveValue, sizeof(double), 1, fp);
3608          if (nWrite != 1)
3609               throw("Error in fwrite");
3610          double * dualRowSolution = lpSolver->dualRowSolution();
3611          double * primalRowSolution = lpSolver->primalRowSolution();
3612          nWrite = fwrite(primalRowSolution, sizeof(double), numberRows, fp);
3613          if (nWrite != static_cast<size_t>(numberRows))
3614               throw("Error in fwrite");
3615          nWrite = fwrite(dualRowSolution, sizeof(double), numberRows, fp);
3616          if (nWrite != static_cast<size_t>(numberRows))
3617               throw("Error in fwrite");
3618          double * dualColumnSolution = lpSolver->dualColumnSolution();
3619          double * primalColumnSolution = lpSolver->primalColumnSolution();
3620          nWrite = fwrite(primalColumnSolution, sizeof(double), numberColumns, fp);
3621          if (nWrite != static_cast<size_t>(numberColumns))
3622               throw("Error in fwrite");
3623          nWrite = fwrite(dualColumnSolution, sizeof(double), numberColumns, fp);
3624          if (nWrite != static_cast<size_t>(numberColumns))
3625               throw("Error in fwrite");
3626          fclose(fp);
3627     } else {
3628          std::cout << "Unable to open file " << fileName << std::endl;
3629     }
3630}
3631#endif
Note: See TracBrowser for help on using the repository browser.