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

Last change on this file since 1711 was 1711, checked in by forrest, 10 years ago

allow for elapsed time on unix systems

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