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

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

allow for setting small element tolerance in readMps

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