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

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

try to fix infeasibility ray,
changes as in stable (for presolve),
stuff for Cbc parameters

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