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

Last change on this file since 1726 was 1726, checked in by stefan, 8 years ago

fix compiler warnings, including one that pointed to a bug

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