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

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

changes for miqp, parameters and presolve

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 164.2 KB
Line 
1/* $Id: CbcOrClpParam.cpp 1924 2013-03-19 13:01:05Z 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("gomory!Cuts", "Whether to use Gomory cuts",
2193                        "off", CBC_PARAM_STR_GOMORYCUTS);
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("onglobal");
2199     parameters[numberParameters-1].append("forceandglobal");
2200     parameters[numberParameters-1].append("forceLongOn");
2201     parameters[numberParameters-1].append("long");
2202     parameters[numberParameters-1].setLonghelp
2203     (
2204          "The original cuts - beware of imitations!  Having gone out of favor, they are now more \
2205fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
2206give cuts (although in this executable they are limited as to number of variables in cut).  \
2207However the cuts may be dense so it is worth experimenting (Long allows any length). \
2208See branchAndCut for information on options."
2209     );
2210     parameters[numberParameters++] =
2211          CbcOrClpParam("greedy!Heuristic", "Whether to use a greedy heuristic",
2212                        "off", CBC_PARAM_STR_GREEDY);
2213     parameters[numberParameters-1].append("on");
2214     parameters[numberParameters-1].append("both");
2215     parameters[numberParameters-1].append("before");
2216     //parameters[numberParameters-1].append("root");
2217     parameters[numberParameters-1].setLonghelp
2218     (
2219          "Switches on a greedy heuristic which will try and obtain a solution.  It may just fix a \
2220percentage of variables and then try a small branch and cut run. \
2221See Rounding for meaning of on,both,before"
2222     );
2223#endif
2224     parameters[numberParameters++] =
2225          CbcOrClpParam("gsolu!tion", "Puts glpk solution to file",
2226                        CLP_PARAM_ACTION_GMPL_SOLUTION);
2227     parameters[numberParameters-1].setLonghelp
2228     (
2229          "Will write a glpk solution file to the given file name.  It will use the default\
2230 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2231 is initialized to 'stdout' (this defaults to ordinary solution if stdout). \
2232If problem created from gmpl model - will do any reports."
2233     );
2234#ifdef COIN_HAS_CBC
2235     parameters[numberParameters++] =
2236          CbcOrClpParam("heur!isticsOnOff", "Switches most heuristics on or off",
2237                        "off", CBC_PARAM_STR_HEURISTICSTRATEGY);
2238     parameters[numberParameters-1].append("on");
2239     parameters[numberParameters-1].setLonghelp
2240     (
2241          "This can be used to switch on or off all heuristics.  Then you can do \
2242individual ones off or on.  CbcTreeLocal is not included as it dramatically \
2243alters search."
2244     );
2245#endif
2246     parameters[numberParameters++] =
2247          CbcOrClpParam("help", "Print out version, non-standard options and some help",
2248                        CLP_PARAM_ACTION_HELP, 3);
2249     parameters[numberParameters-1].setLonghelp
2250     (
2251          "This prints out some help to get user started.  If you have printed this then \
2252you should be past that stage:-)"
2253     );
2254#ifdef COIN_HAS_CBC
2255     parameters[numberParameters++] =
2256          CbcOrClpParam("hOp!tions", "Heuristic options",
2257                        -9999999, 9999999, CBC_PARAM_INT_HOPTIONS, 1);
2258     parameters[numberParameters-1].setLonghelp
2259     (
2260          "1 says stop heuristic immediately allowable gap reached. \
2261Others are for feasibility pump - \
22622 says do exact number of passes given, \
22634 only applies if initial cutoff given and says relax after 50 passes, \
2264while 8 will adapt cutoff rhs after first solution if it looks as if code is stalling."
2265     );
2266     parameters[numberParameters-1].setIntValue(0);
2267     parameters[numberParameters++] =
2268          CbcOrClpParam("hot!StartMaxIts", "Maximum iterations on hot start",
2269                        0, COIN_INT_MAX, CBC_PARAM_INT_MAXHOTITS);
2270#endif
2271#ifdef COIN_HAS_CLP
2272     parameters[numberParameters++] =
2273          CbcOrClpParam("idiot!Crash", "Whether to try idiot crash",
2274                        -1, 99999999, CLP_PARAM_INT_IDIOT);
2275     parameters[numberParameters-1].setLonghelp
2276     (
2277          "This is a type of 'crash' which works well on some homogeneous problems.\
2278 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
2279 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
2280 0 to switch off or n > 0 to do n passes."
2281     );
2282#endif
2283     parameters[numberParameters++] =
2284          CbcOrClpParam("import", "Import model from mps file",
2285                        CLP_PARAM_ACTION_IMPORT, 3);
2286     parameters[numberParameters-1].setLonghelp
2287     (
2288          "This will read an MPS format file from the given file name.  It will use the default\
2289 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2290 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
2291 files 'xxxxxxxx.gz' or 'xxxxxxxx.bz2'.  \
2292If 'keepnames' is off, then names are dropped -> Rnnnnnnn and Cnnnnnnn."
2293     );
2294#ifdef COIN_HAS_CBC
2295     parameters[numberParameters++] =
2296          CbcOrClpParam("inc!rement", "A valid solution must be at least this \
2297much better than last integer solution",
2298                        -1.0e20, 1.0e20, CBC_PARAM_DBL_INCREMENT);
2299     parameters[numberParameters-1].setLonghelp
2300     (
2301          "Whenever a solution is found the bound on solutions is set to solution (in a minimization\
2302sense) plus this.  If it is not set then the code will try and work one out e.g. if \
2303all objective coefficients are multiples of 0.01 and only integer variables have entries in \
2304objective then this can be set to 0.01.  Be careful if you set this negative!"
2305     );
2306     parameters[numberParameters++] =
2307          CbcOrClpParam("inf!easibilityWeight", "Each integer infeasibility is expected \
2308to cost this much",
2309                        0.0, 1.0e20, CBC_PARAM_DBL_INFEASIBILITYWEIGHT, 1);
2310     parameters[numberParameters-1].setLonghelp
2311     (
2312          "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is \
2313expected to cost this much."
2314     );
2315     parameters[numberParameters++] =
2316          CbcOrClpParam("initialS!olve", "Solve to continuous",
2317                        CLP_PARAM_ACTION_SOLVECONTINUOUS);
2318     parameters[numberParameters-1].setLonghelp
2319     (
2320          "This just solves the problem to continuous - without adding any cuts"
2321     );
2322     parameters[numberParameters++] =
2323          CbcOrClpParam("integerT!olerance", "For an optimal solution \
2324no integer variable may be this away from an integer value",
2325                        1.0e-20, 0.5, CBC_PARAM_DBL_INTEGERTOLERANCE);
2326     parameters[numberParameters-1].setLonghelp
2327     (
2328          "Beware of setting this smaller than the primal tolerance."
2329     );
2330#endif
2331#ifdef COIN_HAS_CLP
2332     parameters[numberParameters++] =
2333          CbcOrClpParam("keepN!ames", "Whether to keep names from import",
2334                        "on", CLP_PARAM_STR_KEEPNAMES);
2335     parameters[numberParameters-1].append("off");
2336     parameters[numberParameters-1].setLonghelp
2337     (
2338          "It saves space to get rid of names so if you need to you can set this to off.  \
2339This needs to be set before the import of model - so -keepnames off -import xxxxx.mps."
2340     );
2341     parameters[numberParameters++] =
2342          CbcOrClpParam("KKT", "Whether to use KKT factorization",
2343                        "off", CLP_PARAM_STR_KKT, 7, 1);
2344     parameters[numberParameters-1].append("on");
2345#endif
2346#ifdef COIN_HAS_CBC
2347     parameters[numberParameters++] =
2348          CbcOrClpParam("knapsack!Cuts", "Whether to use Knapsack cuts",
2349                        "off", CBC_PARAM_STR_KNAPSACKCUTS);
2350     parameters[numberParameters-1].append("on");
2351     parameters[numberParameters-1].append("root");
2352     parameters[numberParameters-1].append("ifmove");
2353     parameters[numberParameters-1].append("forceOn");
2354     parameters[numberParameters-1].append("onglobal");
2355     parameters[numberParameters-1].append("forceandglobal");
2356     parameters[numberParameters-1].setLonghelp
2357     (
2358          "This switches on knapsack cuts (either at root or in entire tree) \
2359See branchAndCut for information on options."
2360     );
2361     parameters[numberParameters++] =
2362          CbcOrClpParam("lagomory!Cuts", "Whether to use Lagrangean Gomory cuts",
2363                        "off", CBC_PARAM_STR_LAGOMORYCUTS);
2364     parameters[numberParameters-1].append("endonlyroot");
2365     parameters[numberParameters-1].append("endcleanroot");
2366     parameters[numberParameters-1].append("endbothroot");
2367     parameters[numberParameters-1].append("endonly");
2368     parameters[numberParameters-1].append("endclean");
2369     parameters[numberParameters-1].append("endboth");
2370     parameters[numberParameters-1].append("onlyaswell");
2371     parameters[numberParameters-1].append("cleanaswell");
2372     parameters[numberParameters-1].append("bothaswell");
2373     parameters[numberParameters-1].append("onlyinstead");
2374     parameters[numberParameters-1].append("cleaninstead");
2375     parameters[numberParameters-1].append("bothinstead");
2376     parameters[numberParameters-1].setLonghelp
2377     (
2378          "This is a gross simplification of 'A Relax-and-Cut Framework for Gomory's Mixed-Integer Cuts' \
2379by Matteo Fischetti & Domenico Salvagnin.  This simplification \
2380just uses original constraints while modifying objective using other cuts. \
2381So you don't use messy constraints generated by Gomory etc. \
2382A variant is to allow non messy cuts e.g. clique cuts. \
2383So 'only' does this while clean also allows integral valued cuts.  \
2384'End' is recommended which waits until other cuts have finished and then \
2385does a few passes. \
2386The length options for gomory cuts are used."
2387     );
2388#ifdef CBC_AFTER_2_9
2389      parameters[numberParameters++] =
2390          CbcOrClpParam("latwomir!Cuts", "Whether to use Lagrangean TwoMir cuts",
2391                        "off", CBC_PARAM_STR_LATWOMIRCUTS);
2392     parameters[numberParameters-1].append("endonlyroot");
2393     parameters[numberParameters-1].append("endcleanroot");
2394     parameters[numberParameters-1].append("endbothroot");
2395     parameters[numberParameters-1].append("endonly");
2396     parameters[numberParameters-1].append("endclean");
2397     parameters[numberParameters-1].append("endboth");
2398     parameters[numberParameters-1].append("onlyaswell");
2399     parameters[numberParameters-1].append("cleanaswell");
2400     parameters[numberParameters-1].append("bothaswell");
2401     parameters[numberParameters-1].append("onlyinstead");
2402     parameters[numberParameters-1].append("cleaninstead");
2403     parameters[numberParameters-1].append("bothinstead");
2404     parameters[numberParameters-1].setLonghelp
2405     (
2406          "This is a lagrangean relaxation for TwoMir cuts.  See \
2407lagomoryCuts for description of options."
2408     );
2409#endif
2410     parameters[numberParameters++] =
2411          CbcOrClpParam("lift!AndProjectCuts", "Whether to use Lift and Project cuts",
2412                        "off", CBC_PARAM_STR_LANDPCUTS);
2413     parameters[numberParameters-1].append("on");
2414     parameters[numberParameters-1].append("root");
2415     parameters[numberParameters-1].append("ifmove");
2416     parameters[numberParameters-1].append("forceOn");
2417     parameters[numberParameters-1].setLonghelp
2418     (
2419          "Lift and project cuts. \
2420May be slow \
2421See branchAndCut for information on options."
2422     );
2423     parameters[numberParameters++] =
2424          CbcOrClpParam("local!TreeSearch", "Whether to use local treesearch",
2425                        "off", CBC_PARAM_STR_LOCALTREE);
2426     parameters[numberParameters-1].append("on");
2427     parameters[numberParameters-1].setLonghelp
2428     (
2429          "This switches on a local search algorithm when a solution is found.  This is from \
2430Fischetti and Lodi and is not really a heuristic although it can be used as one. \
2431When used from Coin solve it has limited functionality.  It is not switched on when \
2432heuristics are switched on."
2433     );
2434#endif
2435#ifndef COIN_HAS_CBC
2436     parameters[numberParameters++] =
2437          CbcOrClpParam("log!Level", "Level of detail in Solver output",
2438                        -1, 999999, CLP_PARAM_INT_SOLVERLOGLEVEL);
2439#else
2440     parameters[numberParameters++] =
2441          CbcOrClpParam("log!Level", "Level of detail in Coin branch and Cut output",
2442                        -63, 63, CLP_PARAM_INT_LOGLEVEL);
2443     parameters[numberParameters-1].setIntValue(1);
2444#endif
2445     parameters[numberParameters-1].setLonghelp
2446     (
2447          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
2448 value for most uses, while 2 and 3 give more information."
2449     );
2450     parameters[numberParameters++] =
2451          CbcOrClpParam("max!imize", "Set optimization direction to maximize",
2452                        CLP_PARAM_ACTION_MAXIMIZE, 7);
2453     parameters[numberParameters-1].setLonghelp
2454     (
2455          "The default is minimize - use 'maximize' for maximization.\n\
2456You can also use the parameters 'direction maximize'."
2457     );
2458#ifdef COIN_HAS_CLP
2459     parameters[numberParameters++] =
2460          CbcOrClpParam("maxF!actor", "Maximum number of iterations between \
2461refactorizations",
2462                        1, 999999, CLP_PARAM_INT_MAXFACTOR);
2463     parameters[numberParameters-1].setLonghelp
2464     (
2465          "If this is at its initial value of 200 then in this executable clp will guess at a\
2466 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
2467 earlier for accuracy."
2468     );
2469     parameters[numberParameters++] =
2470          CbcOrClpParam("maxIt!erations", "Maximum number of iterations before \
2471stopping",
2472                        0, 2147483647, CLP_PARAM_INT_MAXITERATION);
2473     parameters[numberParameters-1].setLonghelp
2474     (
2475          "This can be used for testing purposes.  The corresponding library call\n\
2476      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
2477 seconds or by an interrupt this will be treated as stopping on maximum iterations.  This is ignored in branchAndCut - use maxN!odes."
2478     );
2479#endif
2480#ifdef COIN_HAS_CBC
2481     parameters[numberParameters++] =
2482          CbcOrClpParam("maxN!odes", "Maximum number of nodes to do",
2483                        -1, 2147483647, CBC_PARAM_INT_MAXNODES);
2484     parameters[numberParameters-1].setLonghelp
2485     (
2486          "This is a repeatable way to limit search.  Normally using time is easier \
2487but then the results may not be repeatable."
2488     );
2489     parameters[numberParameters++] =
2490          CbcOrClpParam("maxSaved!Solutions", "Maximum number of solutions to save",
2491                        0, 2147483647, CBC_PARAM_INT_MAXSAVEDSOLS);
2492     parameters[numberParameters-1].setLonghelp
2493     (
2494          "Number of solutions to save."
2495     );
2496     parameters[numberParameters++] =
2497          CbcOrClpParam("maxSo!lutions", "Maximum number of solutions to get",
2498                        1, 2147483647, CBC_PARAM_INT_MAXSOLS);
2499     parameters[numberParameters-1].setLonghelp
2500     (
2501          "You may want to stop after (say) two solutions or an hour.  \
2502This is checked every node in tree, so it is possible to get more solutions from heuristics."
2503     );
2504#endif
2505     parameters[numberParameters++] =
2506          CbcOrClpParam("min!imize", "Set optimization direction to minimize",
2507                        CLP_PARAM_ACTION_MINIMIZE, 7);
2508     parameters[numberParameters-1].setLonghelp
2509     (
2510          "The default is minimize - use 'maximize' for maximization.\n\
2511This should only be necessary if you have previously set maximization \
2512You can also use the parameters 'direction minimize'."
2513     );
2514#ifdef COIN_HAS_CBC
2515     parameters[numberParameters++] =
2516          CbcOrClpParam("mipO!ptions", "Dubious options for mip",
2517                        0, COIN_INT_MAX, CBC_PARAM_INT_MIPOPTIONS, 0);
2518     parameters[numberParameters++] =
2519          CbcOrClpParam("more!MipOptions", "More dubious options for mip",
2520                        -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMIPOPTIONS, 0);
2521     parameters[numberParameters++] =
2522          CbcOrClpParam("mixed!IntegerRoundingCuts", "Whether to use Mixed Integer Rounding cuts",
2523                        "off", CBC_PARAM_STR_MIXEDCUTS);
2524     parameters[numberParameters-1].append("on");
2525     parameters[numberParameters-1].append("root");
2526     parameters[numberParameters-1].append("ifmove");
2527     parameters[numberParameters-1].append("forceOn");
2528     parameters[numberParameters-1].append("onglobal");
2529     parameters[numberParameters-1].setLonghelp
2530     (
2531          "This switches on mixed integer rounding cuts (either at root or in entire tree) \
2532See branchAndCut for information on options."
2533     );
2534#endif
2535     parameters[numberParameters++] =
2536          CbcOrClpParam("mess!ages", "Controls if Clpnnnn is printed",
2537                        "off", CLP_PARAM_STR_MESSAGES);
2538     parameters[numberParameters-1].append("on");
2539     parameters[numberParameters-1].setLonghelp
2540     ("The default behavior is to put out messages such as:\n\
2541   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
2542but this program turns this off to make it look more friendly.  It can be useful\
2543 to turn them back on if you want to be able to 'grep' for particular messages or if\
2544 you intend to override the behavior of a particular message.  This only affects Clp not Cbc."
2545     );
2546     parameters[numberParameters++] =
2547          CbcOrClpParam("miplib", "Do some of miplib test set",
2548                        CBC_PARAM_ACTION_MIPLIB, 3, 1);
2549#ifdef COIN_HAS_CBC
2550      parameters[numberParameters++] =
2551          CbcOrClpParam("mips!tart", "reads an initial feasible solution from file",
2552                        CBC_PARAM_ACTION_MIPSTART);
2553     parameters[numberParameters-1].setLonghelp
2554     ("\
2555The MIPStart allows one to enter an initial integer feasible solution \
2556to CBC. Values of the main decision variables which are active (have \
2557non-zero values) in this solution are specified in a text  file. The \
2558text file format used is the same of the solutions saved by CBC, but \
2559not all fields are required to be filled. First line may contain the \
2560solution status and will be ignored, remaining lines contain column \
2561indexes, names and values as in this example:\n\
2562\n\
2563Stopped on iterations - objective value 57597.00000000\n\
2564      0  x(1,1,2,2)               1 \n\
2565      1  x(3,1,3,2)               1 \n\
2566      5  v(5,1)                   2 \n\
2567      33 x(8,1,5,2)               1 \n\
2568      ...\n\
2569\n\
2570Column indexes are also ignored since pre-processing can change them. \
2571There is no need to include values for continuous or integer auxiliary \
2572variables, since they can be computed based on main decision variables. \
2573Starting CBC with an integer feasible solution can dramatically improve \
2574its performance: several MIP heuristics (e.g. RINS) rely on having at \
2575least one feasible solution available and can start immediately if the \
2576user provides one. Feasibility Pump (FP) is a heuristic which tries to \
2577overcome the problem of taking too long to find feasible solution (or \
2578not finding at all), but it not always succeeds. If you provide one \
2579starting solution you will probably save some time by disabling FP. \
2580\n\n\
2581Knowledge specific to your problem can be considered to write an \
2582external module to quickly produce an initial feasible solution - some \
2583alternatives are the implementation of simple greedy heuristics or the \
2584solution (by CBC for example) of a simpler model created just to find \
2585a feasible solution. \
2586\n\n\
2587Question and suggestions regarding MIPStart can be directed to\n\
2588haroldo.santos@gmail.com.\
2589");
2590#endif
2591     parameters[numberParameters++] =
2592          CbcOrClpParam("moreS!pecialOptions", "Yet more dubious options for Simplex - see ClpSimplex.hpp",
2593                        0, COIN_INT_MAX, CLP_PARAM_INT_MORESPECIALOPTIONS, 0);
2594#ifdef COIN_HAS_CBC
2595     parameters[numberParameters++] =
2596          CbcOrClpParam("moreT!une", "Yet more dubious ideas for feasibility pump",
2597                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE2, 0);
2598     parameters[numberParameters-1].setLonghelp
2599     (
2600          "Yet more ideas for Feasibility Pump \n\
2601\t/100000 == 1 use box constraints and original obj in cleanup\n\
2602\t/1000 == 1 Pump will run twice if no solution found\n\
2603\t/1000 == 2 Pump will only run after root cuts if no solution found\n\
2604\t/1000 >10 as above but even if solution found\n\
2605\t/100 == 1,3.. exact 1.0 for objective values\n\
2606\t/100 == 2,3.. allow more iterations per pass\n\
2607\t n fix if value of variable same for last n iterations."
2608     );
2609     parameters[numberParameters-1].setIntValue(0);
2610     parameters[numberParameters++] =
2611          CbcOrClpParam("multiple!RootPasses", "Do multiple root passes to collect cuts and solutions",
2612                        0, 100000000, CBC_PARAM_INT_MULTIPLEROOTS, 0);
2613     parameters[numberParameters-1].setIntValue(0);
2614     parameters[numberParameters-1].setLonghelp
2615     (
2616          "Do (in parallel if threads enabled) the root phase this number of times \
2617 and collect all solutions and cuts generated.  The actual format is aabbcc \
2618where aa is number of extra passes, if bb is non zero \
2619then it is number of threads to use (otherwise uses threads setting) and \
2620cc is number of times to do root phase.  Yet another one from the Italian idea factory \
2621(This time - Andrea Lodi , Matteo Fischetti , Michele Monaci , Domenico Salvagnin , \
2622+and Andrea Tramontani). \
2623+The solvers do not interact with each other.  However if extra passes are specified \
2624+then cuts are collected and used in later passes - so there is interaction there." 
2625     );
2626     parameters[numberParameters++] =
2627          CbcOrClpParam("naive!Heuristics", "Whether to try some stupid heuristic",
2628                        "off", CBC_PARAM_STR_NAIVE, 7, 1);
2629     parameters[numberParameters-1].append("on");
2630     parameters[numberParameters-1].append("both");
2631     parameters[numberParameters-1].append("before");
2632     parameters[numberParameters-1].setLonghelp
2633     (
2634          "Really silly stuff e.g. fix all integers with costs to zero!. \
2635Doh option does heuristic before preprocessing"     );
2636#endif
2637#ifdef COIN_HAS_CLP
2638     parameters[numberParameters++] =
2639          CbcOrClpParam("netlib", "Solve entire netlib test set",
2640                        CLP_PARAM_ACTION_NETLIB_EITHER, 3, 1);
2641     parameters[numberParameters-1].setLonghelp
2642     (
2643          "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
2644The user can set options before e.g. clp -presolve off -netlib"
2645     );
2646     parameters[numberParameters++] =
2647          CbcOrClpParam("netlibB!arrier", "Solve entire netlib test set with barrier",
2648                        CLP_PARAM_ACTION_NETLIB_BARRIER, 3, 1);
2649     parameters[numberParameters-1].setLonghelp
2650     (
2651          "This exercises the unit test for clp and then solves the netlib test set using barrier.\
2652The user can set options before e.g. clp -kkt on -netlib"
2653     );
2654     parameters[numberParameters++] =
2655          CbcOrClpParam("netlibD!ual", "Solve entire netlib test set (dual)",
2656                        CLP_PARAM_ACTION_NETLIB_DUAL, 3, 1);
2657     parameters[numberParameters-1].setLonghelp
2658     (
2659          "This exercises the unit test for clp and then solves the netlib test set using dual.\
2660The user can set options before e.g. clp -presolve off -netlib"
2661     );
2662     parameters[numberParameters++] =
2663          CbcOrClpParam("netlibP!rimal", "Solve entire netlib test set (primal)",
2664                        CLP_PARAM_ACTION_NETLIB_PRIMAL, 3, 1);
2665     parameters[numberParameters-1].setLonghelp
2666     (
2667          "This exercises the unit test for clp and then solves the netlib test set using primal.\
2668The user can set options before e.g. clp -presolve off -netlibp"
2669     );
2670     parameters[numberParameters++] =
2671          CbcOrClpParam("netlibT!une", "Solve entire netlib test set with 'best' algorithm",
2672                        CLP_PARAM_ACTION_NETLIB_TUNE, 3, 1);
2673     parameters[numberParameters-1].setLonghelp
2674     (
2675          "This exercises the unit test for clp and then solves the netlib test set using whatever \
2676works best.  I know this is cheating but it also stresses the code better by doing a \
2677mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
2678with University of Florida ordering."
2679     );
2680     parameters[numberParameters++] =
2681          CbcOrClpParam("network", "Tries to make network matrix",
2682                        CLP_PARAM_ACTION_NETWORK, 7, 0);
2683     parameters[numberParameters-1].setLonghelp
2684     (
2685          "Clp will go faster if the matrix can be converted to a network.  The matrix\
2686 operations may be a bit faster with more efficient storage, but the main advantage\
2687 comes from using a network factorization.  It will probably not be as fast as a \
2688specialized network code."
2689     );
2690#ifdef COIN_HAS_CBC
2691     parameters[numberParameters++] =
2692          CbcOrClpParam("nextB!estSolution", "Prints next best saved solution to file",
2693                        CLP_PARAM_ACTION_NEXTBESTSOLUTION);
2694     parameters[numberParameters-1].setLonghelp
2695     (
2696          "To write best solution, just use solution.  This prints next best (if exists) \
2697 and then deletes it. \
2698 This will write a primitive solution file to the given file name.  It will use the default\
2699 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2700 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
2701     );
2702     parameters[numberParameters++] =
2703          CbcOrClpParam("node!Strategy", "What strategy to use to select nodes",
2704                        "hybrid", CBC_PARAM_STR_NODESTRATEGY);
2705     parameters[numberParameters-1].append("fewest");
2706     parameters[numberParameters-1].append("depth");
2707     parameters[numberParameters-1].append("upfewest");
2708     parameters[numberParameters-1].append("downfewest");
2709     parameters[numberParameters-1].append("updepth");
2710     parameters[numberParameters-1].append("downdepth");
2711     parameters[numberParameters-1].setLonghelp
2712     (
2713          "Normally before a solution the code will choose node with fewest infeasibilities. \
2714You can choose depth as the criterion.  You can also say if up or down branch must \
2715be done first (the up down choice will carry on after solution). \
2716Default has now been changed to hybrid which is breadth first on small depth nodes then fewest."
2717     );
2718     parameters[numberParameters++] =
2719          CbcOrClpParam("numberA!nalyze", "Number of analysis iterations",
2720                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_NUMBERANALYZE, 0);
2721     parameters[numberParameters-1].setLonghelp
2722     (
2723          "This says how many iterations to spend at root node analyzing problem. \
2724This is a first try and will hopefully become more sophisticated."
2725     );
2726#endif
2727     parameters[numberParameters++] =
2728          CbcOrClpParam("objective!Scale", "Scale factor to apply to objective",
2729                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE, 1);
2730     parameters[numberParameters-1].setLonghelp
2731     (
2732          "If the objective function has some very large values, you may wish to scale them\
2733 internally by this amount.  It can also be set by autoscale.  It is applied after scaling.  You are unlikely to need this."
2734     );
2735     parameters[numberParameters-1].setDoubleValue(1.0);
2736#endif
2737#ifdef COIN_HAS_CBC
2738     parameters[numberParameters++] =
2739          CbcOrClpParam("outDup!licates", "takes duplicate rows etc out of integer model",
2740                        CLP_PARAM_ACTION_OUTDUPROWS, 7, 0);
2741#endif
2742     parameters[numberParameters++] =
2743          CbcOrClpParam("output!Format", "Which output format to use",
2744                        1, 6, CLP_PARAM_INT_OUTPUTFORMAT);
2745     parameters[numberParameters-1].setLonghelp
2746     (
2747          "Normally export will be done using normal representation for numbers and two values\
2748 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
2749 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
2750 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
2751 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
2752values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
2753     );
2754#ifdef COIN_HAS_CLP
2755     parameters[numberParameters++] =
2756          CbcOrClpParam("para!metrics", "Import data from file and do parametrics",
2757                        CLP_PARAM_ACTION_PARAMETRICS, 3);
2758     parameters[numberParameters-1].setLonghelp
2759     (
2760          "This will read a file with parametric data from the given file name \
2761and then do parametrics.  It will use the default\
2762 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2763 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2764File is in modified csv format - a line ROWS will be followed by rows data \
2765while a line COLUMNS will be followed by column data.  The last line \
2766should be ENDATA. The ROWS line must exist and is in the format \
2767ROWS, inital theta, final theta, interval theta, n where n is 0 to get \
2768CLPI0062 message at interval or at each change of theta \
2769and 1 to get CLPI0063 message at each iteration.  If interval theta is 0.0 \
2770or >= final theta then no interval reporting.  n may be missed out when it is \
2771taken as 0.  If there is Row data then \
2772there is a headings line with allowed headings - name, number, \
2773lower(rhs change), upper(rhs change), rhs(change).  Either the lower and upper \
2774fields should be given or the rhs field. \
2775The optional COLUMNS line is followed by a headings line with allowed \
2776headings - name, number, objective(change), lower(change), upper(change). \
2777 Exactly one of name and number must be given for either section and \
2778missing ones have value 0.0."
2779     );
2780#endif
2781#ifdef COIN_HAS_CBC
2782     parameters[numberParameters++] =
2783          CbcOrClpParam("passC!uts", "Number of cut passes at root node",
2784                        -9999999, 9999999, CBC_PARAM_INT_CUTPASS);
2785     parameters[numberParameters-1].setLonghelp
2786     (
2787          "The default is 100 passes if less than 500 columns, 100 passes (but \
2788stop if drop small if less than 5000 columns, 20 otherwise"
2789     );
2790     parameters[numberParameters++] =
2791          CbcOrClpParam("passF!easibilityPump", "How many passes in feasibility pump",
2792                        0, 10000, CBC_PARAM_INT_FPUMPITS);
2793     parameters[numberParameters-1].setLonghelp
2794     (
2795          "This fine tunes Feasibility Pump by doing more or fewer passes."
2796     );
2797     parameters[numberParameters-1].setIntValue(20);
2798#endif
2799#ifdef COIN_HAS_CLP
2800     parameters[numberParameters++] =
2801          CbcOrClpParam("passP!resolve", "How many passes in presolve",
2802                        -200, 100, CLP_PARAM_INT_PRESOLVEPASS, 1);
2803     parameters[numberParameters-1].setLonghelp
2804     (
2805          "Normally Presolve does 5 passes but you may want to do less to make it\
2806 more lightweight or do more if improvements are still being made.  As Presolve will return\
2807 if nothing is being taken out, you should not normally need to use this fine tuning."
2808     );
2809#endif
2810#ifdef COIN_HAS_CBC
2811     parameters[numberParameters++] =
2812          CbcOrClpParam("passT!reeCuts", "Number of cut passes in tree",
2813                        -9999999, 9999999, CBC_PARAM_INT_CUTPASSINTREE);
2814     parameters[numberParameters-1].setLonghelp
2815     (
2816          "The default is one pass"
2817     );
2818#endif
2819#ifdef COIN_HAS_CLP
2820     parameters[numberParameters++] =
2821          CbcOrClpParam("pertV!alue", "Method of perturbation",
2822                        -5000, 102, CLP_PARAM_INT_PERTVALUE, 1);
2823     parameters[numberParameters++] =
2824          CbcOrClpParam("perturb!ation", "Whether to perturb problem",
2825                        "on", CLP_PARAM_STR_PERTURBATION);
2826     parameters[numberParameters-1].append("off");
2827     parameters[numberParameters-1].setLonghelp
2828     (
2829          "Perturbation helps to stop cycling, but Clp uses other measures for this.\
2830  However large problems and especially ones with unit elements and unit rhs or costs\
2831 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
2832  The Clp library has this off by default.  This program has it on by default."
2833     );
2834     parameters[numberParameters++] =
2835          CbcOrClpParam("PFI", "Whether to use Product Form of Inverse in simplex",
2836                        "off", CLP_PARAM_STR_PFI, 7, 0);
2837     parameters[numberParameters-1].append("on");
2838     parameters[numberParameters-1].setLonghelp
2839     (
2840          "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
2841     );
2842#endif
2843#ifdef COIN_HAS_CBC
2844     parameters[numberParameters++] =
2845          CbcOrClpParam("pivotAndC!omplement", "Whether to try Pivot and Complement heuristic",
2846                        "off", CBC_PARAM_STR_PIVOTANDCOMPLEMENT);
2847     parameters[numberParameters-1].append("on");
2848     parameters[numberParameters-1].append("both");
2849     parameters[numberParameters-1].append("before");
2850     parameters[numberParameters-1].setLonghelp
2851     (
2852          "stuff needed. \
2853Doh option does heuristic before preprocessing"     );
2854     parameters[numberParameters++] =
2855          CbcOrClpParam("pivotAndF!ix", "Whether to try Pivot and Fix heuristic",
2856                        "off", CBC_PARAM_STR_PIVOTANDFIX);
2857     parameters[numberParameters-1].append("on");
2858     parameters[numberParameters-1].append("both");
2859     parameters[numberParameters-1].append("before");
2860     parameters[numberParameters-1].setLonghelp
2861     (
2862          "stuff needed. \
2863Doh option does heuristic before preprocessing"     );
2864#endif
2865#ifdef COIN_HAS_CLP
2866     parameters[numberParameters++] =
2867          CbcOrClpParam("plus!Minus", "Tries to make +- 1 matrix",
2868                        CLP_PARAM_ACTION_PLUSMINUS, 7, 0);
2869     parameters[numberParameters-1].setLonghelp
2870     (
2871          "Clp will go slightly faster if the matrix can be converted so that the elements are\
2872 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
2873 see if it can convert the problem so you should not need to use this."
2874     );
2875     parameters[numberParameters++] =
2876          CbcOrClpParam("pO!ptions", "Dubious print options",
2877                        0, COIN_INT_MAX, CLP_PARAM_INT_PRINTOPTIONS, 1);
2878     parameters[numberParameters-1].setIntValue(0);
2879     parameters[numberParameters-1].setLonghelp
2880     (
2881          "If this is > 0 then presolve will give more information and branch and cut will give statistics"
2882     );
2883     parameters[numberParameters++] =
2884          CbcOrClpParam("preO!pt", "Presolve options",
2885                        0, COIN_INT_MAX, CLP_PARAM_INT_PRESOLVEOPTIONS, 0);
2886#endif
2887     parameters[numberParameters++] =
2888          CbcOrClpParam("presolve", "Whether to presolve problem",
2889                        "on", CLP_PARAM_STR_PRESOLVE);
2890     parameters[numberParameters-1].append("off");
2891     parameters[numberParameters-1].append("more");
2892     parameters[numberParameters-1].append("file");
2893     parameters[numberParameters-1].setLonghelp
2894     (
2895          "Presolve analyzes the model to find such things as redundant equations, equations\
2896 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
2897 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
2898on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
2899to write the original to file using 'file'."
2900     );
2901#ifdef COIN_HAS_CBC
2902     parameters[numberParameters++] =
2903          CbcOrClpParam("preprocess", "Whether to use integer preprocessing",
2904                        "off", CBC_PARAM_STR_PREPROCESS);
2905     parameters[numberParameters-1].append("on");
2906     parameters[numberParameters-1].append("save");
2907     parameters[numberParameters-1].append("equal");
2908     parameters[numberParameters-1].append("sos");
2909     parameters[numberParameters-1].append("trysos");
2910     parameters[numberParameters-1].append("equalall");
2911     parameters[numberParameters-1].append("strategy");
2912     parameters[numberParameters-1].append("aggregate");
2913     parameters[numberParameters-1].append("forcesos");
2914     parameters[numberParameters-1].setLonghelp
2915     (
2916          "This tries to reduce size of model in a similar way to presolve and \
2917it also tries to strengthen the model - this can be very useful and is worth trying. \
2918 Save option saves on file presolved.mps.  equal will turn <= cliques into \
2919==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
2920and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
2921valid inequalities into equalities with integer slacks.  strategy is as \
2922on but uses CbcStrategy."
2923     );
2924#endif
2925#ifdef COIN_HAS_CLP
2926     parameters[numberParameters++] =
2927          CbcOrClpParam("preT!olerance", "Tolerance to use in presolve",
2928                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRESOLVETOLERANCE);
2929     parameters[numberParameters-1].setLonghelp
2930     (
2931          "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
2932infeasible and you have awkward numbers and you are sure the problem is really feasible."
2933     );
2934     parameters[numberParameters++] =
2935          CbcOrClpParam("primalP!ivot", "Primal pivot choice algorithm",
2936                        "auto!matic", CLP_PARAM_STR_PRIMALPIVOT, 7, 1);
2937     parameters[numberParameters-1].append("exa!ct");
2938     parameters[numberParameters-1].append("dant!zig");
2939     parameters[numberParameters-1].append("part!ial");
2940     parameters[numberParameters-1].append("steep!est");
2941     parameters[numberParameters-1].append("change");
2942     parameters[numberParameters-1].append("sprint");
2943     parameters[numberParameters-1].setLonghelp
2944     (
2945          "Clp can use any pivot selection algorithm which the user codes as long as it\
2946 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
2947 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
2948 are two variants which keep all weights updated but only scan a subset each iteration.\
2949 Partial switches this on while change initially does dantzig until the factorization\
2950 becomes denser.  This is still a work in progress."
2951     );
2952     parameters[numberParameters++] =
2953          CbcOrClpParam("primalS!implex", "Do primal simplex algorithm",
2954                        CLP_PARAM_ACTION_PRIMALSIMPLEX);
2955     parameters[numberParameters-1].setLonghelp
2956     (
2957          "This command solves the current model using the primal algorithm.\
2958  The default is to use exact devex.\
2959 The time and iterations may be affected by settings such as presolve, scaling, crash\
2960 and also by column selection  method, infeasibility weight and dual and primal tolerances."
2961     );
2962#endif
2963     parameters[numberParameters++] =
2964          CbcOrClpParam("primalT!olerance", "For an optimal solution \
2965no primal infeasibility may exceed this value",
2966                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRIMALTOLERANCE);
2967     parameters[numberParameters-1].setLonghelp
2968     (
2969          "Normally the default tolerance is fine, but you may want to increase it a\
2970 bit if a primal run seems to be having a hard time"
2971     );
2972#ifdef COIN_HAS_CLP
2973     parameters[numberParameters++] =
2974          CbcOrClpParam("primalW!eight", "Initially algorithm acts as if it \
2975costs this much to be infeasible",
2976                        1.0e-20, 1.0e20, CLP_PARAM_DBL_PRIMALWEIGHT);
2977     parameters[numberParameters-1].setLonghelp
2978     (
2979          "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
2980 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
2981 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
2982  Too high a value may mean more iterations, while too low a bound means\
2983 the code may go all the way and then have to increase the weight in order to get feasible.\
2984  OSL had a heuristic to\
2985 adjust bounds, maybe we need that here."
2986     );
2987#endif
2988     parameters[numberParameters++] =
2989          CbcOrClpParam("printi!ngOptions", "Print options",
2990                        "normal", CLP_PARAM_STR_INTPRINT, 3);
2991     parameters[numberParameters-1].append("integer");
2992     parameters[numberParameters-1].append("special");
2993     parameters[numberParameters-1].append("rows");
2994     parameters[numberParameters-1].append("all");
2995     parameters[numberParameters-1].append("csv");
2996     parameters[numberParameters-1].append("bound!ranging");
2997     parameters[numberParameters-1].append("rhs!ranging");
2998     parameters[numberParameters-1].append("objective!ranging");
2999     parameters[numberParameters-1].append("stats");
3000     parameters[numberParameters-1].setLonghelp
3001     (
3002          "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
3003integer - nonzero integer column variables\n\
3004special - in format suitable for OsiRowCutDebugger\n\
3005rows - nonzero column variables and row activities\n\
3006all - all column variables and row activities.\n\
3007\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
3008Also see printMask for controlling output."
3009     );
3010     parameters[numberParameters++] =
3011          CbcOrClpParam("printM!ask", "Control printing of solution on a  mask",
3012                        CLP_PARAM_ACTION_PRINTMASK, 3);
3013     parameters[numberParameters-1].setLonghelp
3014     (
3015          "If set then only those names which match mask are printed in a solution. \
3016'?' matches any character and '*' matches any set of characters. \
3017 The default is '' i.e. unset so all variables are printed. \
3018This is only active if model has names."
3019     );
3020#ifdef COIN_HAS_CBC
3021     parameters[numberParameters++] =
3022          CbcOrClpParam("prio!rityIn", "Import priorities etc from file",
3023                        CBC_PARAM_ACTION_PRIORITYIN, 3);
3024     parameters[numberParameters-1].setLonghelp
3025     (
3026          "This will read a file with priorities from the given file name.  It will use the default\
3027 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3028 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
3029File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
3030 name and number must be given."
3031     );
3032     parameters[numberParameters++] =
3033          CbcOrClpParam("probing!Cuts", "Whether to use Probing cuts",
3034                        "off", CBC_PARAM_STR_PROBINGCUTS);
3035     parameters[numberParameters-1].append("on");
3036     parameters[numberParameters-1].append("root");
3037     parameters[numberParameters-1].append("ifmove");
3038     parameters[numberParameters-1].append("forceOn");
3039     parameters[numberParameters-1].append("onglobal");
3040     parameters[numberParameters-1].append("forceonglobal");
3041     parameters[numberParameters-1].append("forceOnBut");
3042     parameters[numberParameters-1].append("forceOnStrong");
3043     parameters[numberParameters-1].append("forceOnButStrong");
3044     parameters[numberParameters-1].append("strongRoot");
3045     parameters[numberParameters-1].setLonghelp
3046     (
3047          "This switches on probing cuts (either at root or in entire tree) \
3048See branchAndCut for information on options. \
3049but strong options do more probing"
3050     );
3051     parameters[numberParameters++] =
3052          CbcOrClpParam("proximity!Search", "Whether to do proximity search heuristic",
3053                        "off", CBC_PARAM_STR_PROXIMITY);
3054     parameters[numberParameters-1].append("on");
3055     parameters[numberParameters-1].append("both");
3056     parameters[numberParameters-1].append("before");
3057     parameters[numberParameters-1].append("10");
3058     parameters[numberParameters-1].append("100");
3059     parameters[numberParameters-1].append("300");
3060     parameters[numberParameters-1].setLonghelp
3061     (
3062          "This switches on a heuristic which looks for a solution close \
3063to incumbent solution (Fischetti and Monaci). \
3064See Rounding for meaning of on,both,before. \
3065The ones at end have different maxNode settings (and are 'on'(on==30))."
3066     );
3067     parameters[numberParameters++] =
3068          CbcOrClpParam("pumpC!utoff", "Fake cutoff for use in feasibility pump",
3069                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKECUTOFF);
3070     parameters[numberParameters-1].setDoubleValue(0.0);
3071     parameters[numberParameters-1].setLonghelp
3072     (
3073          "0.0 off - otherwise add a constraint forcing objective below this value\
3074 in feasibility pump"
3075     );
3076     parameters[numberParameters++] =
3077          CbcOrClpParam("pumpI!ncrement", "Fake increment for use in feasibility pump",
3078                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKEINCREMENT, 1);
3079     parameters[numberParameters-1].setDoubleValue(0.0);
3080     parameters[numberParameters-1].setLonghelp
3081     (
3082          "0.0 off - otherwise use as absolute increment to cutoff \
3083when solution found in feasibility pump"
3084     );
3085     parameters[numberParameters++] =
3086          CbcOrClpParam("pumpT!une", "Dubious ideas for feasibility pump",
3087                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE);
3088     parameters[numberParameters-1].setLonghelp
3089     (
3090          "This fine tunes Feasibility Pump \n\
3091\t>=10000000 use as objective weight switch\n\
3092\t>=1000000 use as accumulate switch\n\
3093\t>=1000 use index+1 as number of large loops\n\
3094\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\
3095\t%100 == 10,20 affects how each solve is done\n\
3096\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \
3097If accumulate is on then after a major pass, variables which have not moved \
3098are fixed and a small branch and bound is tried."
3099     );
3100     parameters[numberParameters-1].setIntValue(0);
3101#endif
3102     parameters[numberParameters++] =
3103          CbcOrClpParam("quit", "Stops clp execution",
3104                        CLP_PARAM_ACTION_EXIT);
3105     parameters[numberParameters-1].setLonghelp
3106     (
3107          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3108     );
3109#ifdef COIN_HAS_CBC
3110     parameters[numberParameters++] =
3111          CbcOrClpParam("randomC!bcSeed", "Random seed for Cbc",
3112                        -1, COIN_INT_MAX, CBC_PARAM_INT_RANDOMSEED);
3113     parameters[numberParameters-1].setLonghelp
3114     (
3115          "This sets a random seed for Cbc \
3116- 0 says use time of day, -1 is as now."
3117     );
3118     parameters[numberParameters-1].setIntValue(-1);
3119     parameters[numberParameters++] =
3120          CbcOrClpParam("randomi!zedRounding", "Whether to try randomized rounding heuristic",
3121                        "off", CBC_PARAM_STR_RANDROUND);
3122     parameters[numberParameters-1].append("on");
3123     parameters[numberParameters-1].append("both");
3124     parameters[numberParameters-1].append("before");
3125     parameters[numberParameters-1].setLonghelp
3126     (
3127          "stuff needed. \
3128Doh option does heuristic before preprocessing"     );
3129#endif
3130#ifdef COIN_HAS_CLP
3131     parameters[numberParameters++] =
3132          CbcOrClpParam("randomS!eed", "Random seed for Clp",
3133                        0, COIN_INT_MAX, CLP_PARAM_INT_RANDOMSEED);
3134     parameters[numberParameters-1].setLonghelp
3135     (
3136          "This sets a random seed for Clp \
3137- 0 says use time of day."
3138     );
3139     parameters[numberParameters-1].setIntValue(1234567);
3140#endif
3141#ifdef COIN_HAS_CBC
3142     parameters[numberParameters++] =
3143          CbcOrClpParam("ratio!Gap", "Stop when gap between best possible and \
3144best less than this fraction of larger of two",
3145                        0.0, 1.0e20, CBC_PARAM_DBL_GAPRATIO);
3146     parameters[numberParameters-1].setDoubleValue(0.0);
3147     parameters[numberParameters-1].setLonghelp
3148     (
3149          "If the gap between best solution and best possible solution is less than this fraction \
3150of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
3151way of using absolute value rather than fraction."
3152     );
3153     parameters[numberParameters++] =
3154          CbcOrClpParam("readS!tored", "Import stored cuts from file",
3155                        CLP_PARAM_ACTION_STOREDFILE, 3, 0);
3156#endif
3157#ifdef COIN_HAS_CLP
3158     parameters[numberParameters++] =
3159          CbcOrClpParam("reallyO!bjectiveScale", "Scale factor to apply to objective in place",
3160                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE2, 0);
3161     parameters[numberParameters-1].setLonghelp
3162     (
3163          "You can set this to -1.0 to test maximization or other to stress code"
3164     );
3165     parameters[numberParameters-1].setDoubleValue(1.0);
3166     parameters[numberParameters++] =
3167          CbcOrClpParam("reallyS!cale", "Scales model in place",
3168                        CLP_PARAM_ACTION_REALLY_SCALE, 7, 0);
3169#endif
3170#ifdef COIN_HAS_CBC
3171     parameters[numberParameters++] =
3172          CbcOrClpParam("reduce!AndSplitCuts", "Whether to use Reduce-and-Split cuts",
3173                        "off", CBC_PARAM_STR_REDSPLITCUTS);
3174     parameters[numberParameters-1].append("on");
3175     parameters[numberParameters-1].append("root");
3176     parameters[numberParameters-1].append("ifmove");
3177     parameters[numberParameters-1].append("forceOn");
3178     parameters[numberParameters-1].setLonghelp
3179     (
3180          "This switches on reduce and split  cuts (either at root or in entire tree). \
3181May be slow \
3182See branchAndCut for information on options."
3183     );
3184      parameters[numberParameters++] =
3185          CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2",
3186                        "off", CBC_PARAM_STR_REDSPLIT2CUTS);
3187     parameters[numberParameters-1].append("on");
3188     parameters[numberParameters-1].append("root");
3189     parameters[numberParameters-1].append("longOn");
3190     parameters[numberParameters-1].append("longRoot");
3191     parameters[numberParameters-1].setLonghelp
3192     (
3193          "This switches on reduce and split  cuts (either at root or in entire tree) \
3194This version is by Giacomo Nannicini based on Francois Margot's version \
3195Standard setting only uses rows in tableau <=256, long uses all \
3196May be slow \
3197See branchAndCut for information on options."
3198     );
3199     parameters[numberParameters++] =
3200          CbcOrClpParam("residual!CapacityCuts", "Whether to use Residual Capacity cuts",
3201                        "off", CBC_PARAM_STR_RESIDCUTS);
3202     parameters[numberParameters-1].append("on");
3203     parameters[numberParameters-1].append("root");
3204     parameters[numberParameters-1].append("ifmove");
3205     parameters[numberParameters-1].append("forceOn");
3206     parameters[numberParameters-1].setLonghelp
3207     (
3208          "Residual capacity cuts. \
3209See branchAndCut for information on options."
3210     );
3211#endif
3212#ifdef COIN_HAS_CLP
3213     parameters[numberParameters++] =
3214          CbcOrClpParam("restore!Model", "Restore model from binary file",
3215                        CLP_PARAM_ACTION_RESTORE, 7, 1);
3216     parameters[numberParameters-1].setLonghelp
3217     (
3218          "This reads data save by saveModel from the given file.  It will use the default\
3219 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3220 is initialized to 'default.prob'."
3221     );
3222     parameters[numberParameters++] =
3223          CbcOrClpParam("reverse", "Reverses sign of objective",
3224                        CLP_PARAM_ACTION_REVERSE, 7, 0);
3225     parameters[numberParameters-1].setLonghelp
3226     (
3227          "Useful for testing if maximization works correctly"
3228     );
3229     parameters[numberParameters++] =
3230          CbcOrClpParam("rhs!Scale", "Scale factor to apply to rhs and bounds",
3231                        -1.0e20, 1.0e20, CLP_PARAM_DBL_RHSSCALE, 0);
3232     parameters[numberParameters-1].setLonghelp
3233     (
3234          "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
3235 internally by this amount.  It can also be set by autoscale.  This should not be needed."
3236     );
3237     parameters[numberParameters-1].setDoubleValue(1.0);
3238#endif
3239#ifdef COIN_HAS_CBC
3240     parameters[numberParameters++] =
3241          CbcOrClpParam("Rens", "Whether to try Relaxation Enforced Neighborhood Search",
3242                        "off", CBC_PARAM_STR_RENS);
3243     parameters[numberParameters-1].append("on");
3244     parameters[numberParameters-1].append("both");
3245     parameters[numberParameters-1].append("before");
3246     parameters[numberParameters-1].append("200");
3247     parameters[numberParameters-1].append("1000");
3248     parameters[numberParameters-1].append("10000");
3249     parameters[numberParameters-1].append("dj");
3250     parameters[numberParameters-1].append("djbefore");
3251     parameters[numberParameters-1].setLonghelp
3252     (
3253          "This switches on Relaxation enforced neighborhood Search. \
3254on just does 50 nodes \
3255200 or 1000 does that many nodes. \
3256Doh option does heuristic before preprocessing"     );
3257     parameters[numberParameters++] =
3258          CbcOrClpParam("Rins", "Whether to try Relaxed Induced Neighborhood Search",
3259                        "off", CBC_PARAM_STR_RINS);
3260     parameters[numberParameters-1].append("on");
3261     parameters[numberParameters-1].append("both");
3262     parameters[numberParameters-1].append("before");
3263     parameters[numberParameters-1].append("often");
3264     parameters[numberParameters-1].setLonghelp
3265     (
3266          "This switches on Relaxed induced neighborhood Search. \
3267Doh option does heuristic before preprocessing"     );
3268     parameters[numberParameters++] =
3269          CbcOrClpParam("round!ingHeuristic", "Whether to use Rounding heuristic",
3270                        "off", CBC_PARAM_STR_ROUNDING);
3271     parameters[numberParameters-1].append("on");
3272     parameters[numberParameters-1].append("both");
3273     parameters[numberParameters-1].append("before");
3274     parameters[numberParameters-1].setLonghelp
3275     (
3276          "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
3277On means do in solve i.e. after preprocessing, \
3278Before means do if doHeuristics used, off otherwise, \
3279and both means do if doHeuristics and in solve."
3280     );
3281
3282#endif
3283     parameters[numberParameters++] =
3284          CbcOrClpParam("saveM!odel", "Save model to binary file",
3285                        CLP_PARAM_ACTION_SAVE, 7, 1);
3286     parameters[numberParameters-1].setLonghelp
3287     (
3288          "This will save the problem to the given file name for future use\
3289 by restoreModel.  It will use the default\
3290 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3291 is initialized to 'default.prob'."
3292     );
3293     parameters[numberParameters++] =
3294          CbcOrClpParam("saveS!olution", "saves solution to file",
3295                        CLP_PARAM_ACTION_SAVESOL);
3296     parameters[numberParameters-1].setLonghelp
3297     (
3298          "This will write a binary solution file to the given file name.  It will use the default\
3299 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3300 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
3301and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
3302activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
3303If name contains '_fix_read_' then does not write but reads and will fix all variables"
3304     );
3305     parameters[numberParameters++] =
3306          CbcOrClpParam("scal!ing", "Whether to scale problem",
3307                        "off", CLP_PARAM_STR_SCALING);
3308     parameters[numberParameters-1].append("equi!librium");
3309     parameters[numberParameters-1].append("geo!metric");
3310     parameters[numberParameters-1].append("auto!matic");
3311     parameters[numberParameters-1].append("dynamic");
3312     parameters[numberParameters-1].append("rows!only");
3313     parameters[numberParameters-1].setLonghelp
3314     (
3315          "Scaling can help in solving problems which might otherwise fail because of lack of\
3316 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
3317 of elements is small.  When unscaled it is possible that there may be small primal and/or\
3318 infeasibilities."
3319     );
3320     parameters[numberParameters-1].setCurrentOption(3); // say auto
3321#ifndef COIN_HAS_CBC
3322     parameters[numberParameters++] =
3323          CbcOrClpParam("sec!onds", "Maximum seconds",
3324                        -1.0, 1.0e12, CLP_PARAM_DBL_TIMELIMIT);
3325     parameters[numberParameters-1].setLonghelp
3326     (
3327          "After this many seconds clp will act as if maximum iterations had been reached \
3328(if value >=0)."
3329     );
3330#else
3331     parameters[numberParameters++] =
3332          CbcOrClpParam("sec!onds", "maximum seconds",
3333                        -1.0, 1.0e12, CBC_PARAM_DBL_TIMELIMIT_BAB);
3334     parameters[numberParameters-1].setLonghelp
3335     (
3336          "After this many seconds coin solver will act as if maximum nodes had been reached."
3337     );
3338#endif
3339     parameters[numberParameters++] =
3340          CbcOrClpParam("sleep", "for debug",
3341                        CLP_PARAM_ACTION_DUMMY, 7, 0);
3342     parameters[numberParameters-1].setLonghelp
3343     (
3344          "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
3345     );
3346#ifdef COIN_HAS_CBC
3347#ifdef CBC_AFTER_2_9
3348     parameters[numberParameters++] =
3349          CbcOrClpParam("slow!cutpasses", "Maximum number of tries for slower cuts",
3350                        -1, COIN_INT_MAX, CBC_PARAM_INT_MAX_SLOW_CUTS);
3351     parameters[numberParameters-1].setLonghelp
3352     (
3353          "Some cut generators are fairly slow - this limits the number of times they are tried."
3354     );
3355     parameters[numberParameters-1].setIntValue(10);
3356#endif
3357#endif
3358#ifdef COIN_HAS_CLP
3359     parameters[numberParameters++] =
3360          CbcOrClpParam("slp!Value", "Number of slp passes before primal",
3361                        -1, 50000, CLP_PARAM_INT_SLPVALUE, 1);
3362     parameters[numberParameters-1].setLonghelp
3363     (
3364          "If you are solving a quadratic problem using primal then it may be helpful to do some \
3365sequential Lps to get a good approximate solution."
3366     );
3367#if CLP_MULTIPLE_FACTORIZATIONS > 0
3368     parameters[numberParameters++] =
3369          CbcOrClpParam("small!Factorization", "Whether to use small factorization",
3370                        -1, 10000, CBC_PARAM_INT_SMALLFACT, 1);
3371     parameters[numberParameters-1].setLonghelp
3372     (
3373          "If processed problem <= this use small factorization"
3374     );
3375     parameters[numberParameters-1].setIntValue(-1);
3376#endif
3377#endif
3378     parameters[numberParameters++] =
3379          CbcOrClpParam("solu!tion", "Prints solution to file",
3380                        CLP_PARAM_ACTION_SOLUTION);
3381     parameters[numberParameters-1].setLonghelp
3382     (
3383          "This will write a primitive solution file to the given file name.  It will use the default\
3384 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3385 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
3386     );
3387#ifdef COIN_HAS_CLP
3388#ifdef COIN_HAS_CBC
3389     parameters[numberParameters++] =
3390          CbcOrClpParam("solv!e", "Solve problem",
3391                        CBC_PARAM_ACTION_BAB);
3392     parameters[numberParameters-1].setLonghelp
3393     (
3394          "If there are no integer variables then this just solves LP.  If there are integer variables \
3395this does branch and cut."
3396     );
3397     parameters[numberParameters++] =
3398          CbcOrClpParam("sos!Options", "Whether to use SOS from AMPL",
3399                        "off", CBC_PARAM_STR_SOS);
3400     parameters[numberParameters-1].append("on");
3401     parameters[numberParameters-1].setCurrentOption("on");
3402     parameters[numberParameters-1].setLonghelp
3403     (
3404          "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
3405 be turned off - this does so."
3406     );
3407     parameters[numberParameters++] =
3408          CbcOrClpParam("slog!Level", "Level of detail in (LP) Solver output",
3409                        -1, 63, CLP_PARAM_INT_SOLVERLOGLEVEL);
3410     parameters[numberParameters-1].setLonghelp
3411     (
3412          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
3413 value for most uses, while 2 and 3 give more information.  This parameter is only used inside MIP - for Clp use 'log'"
3414     );
3415#else
3416     // allow solve as synonym for possible dual
3417     parameters[numberParameters++] =
3418       CbcOrClpParam("solv!e", "Solve problem using dual simplex (probably)",
3419                        CLP_PARAM_ACTION_EITHERSIMPLEX);
3420     parameters[numberParameters-1].setLonghelp
3421     (
3422          "Just so can use solve for clp as well as in cbc"
3423     );
3424#endif
3425#endif
3426#ifdef COIN_HAS_CLP
3427     parameters[numberParameters++] =
3428          CbcOrClpParam("spars!eFactor", "Whether factorization treated as sparse",
3429                        "on", CLP_PARAM_STR_SPARSEFACTOR, 7, 0);
3430     parameters[numberParameters-1].append("off");
3431     parameters[numberParameters++] =
3432          CbcOrClpParam("special!Options", "Dubious options for Simplex - see ClpSimplex.hpp",
3433                        0, COIN_INT_MAX, CLP_PARAM_INT_SPECIALOPTIONS, 0);
3434     parameters[numberParameters++] =
3435          CbcOrClpParam("sprint!Crash", "Whether to try sprint crash",
3436                        -1, 5000000, CLP_PARAM_INT_SPRINT);
3437     parameters[numberParameters-1].setLonghelp
3438     (
3439          "For long and thin problems this program may solve a series of small problems\
3440 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
3441 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
3442  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
3443     );
3444     parameters[numberParameters++] =
3445          CbcOrClpParam("stat!istics", "Print some statistics",
3446                        CLP_PARAM_ACTION_STATISTICS);
3447     parameters[numberParameters-1].setLonghelp
3448     (
3449          "This command prints some statistics for the current model.\
3450 If log level >1 then more is printed.\
3451 These are for presolved model if presolve on (and unscaled)."
3452     );
3453#endif
3454     parameters[numberParameters++] =
3455          CbcOrClpParam("stop", "Stops clp execution",
3456                        CLP_PARAM_ACTION_EXIT);
3457     parameters[numberParameters-1].setLonghelp
3458     (
3459          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3460     );
3461#ifdef COIN_HAS_CBC
3462     parameters[numberParameters++] =
3463          CbcOrClpParam("strat!egy", "Switches on groups of features",
3464                        0, 2, CBC_PARAM_INT_STRATEGY);
3465     parameters[numberParameters-1].setLonghelp
3466     (
3467          "This turns on newer features. \
3468Use 0 for easy problems, 1 is default, 2 is aggressive. \
34691 uses Gomory cuts using tolerance of 0.01 at root, \
3470does a possible restart after 100 nodes if can fix many \
3471and activates a diving and RINS heuristic and makes feasibility pump \
3472more aggressive. \
3473This does not apply to unit tests (where 'experiment' may have similar effects)."
3474     );
3475     parameters[numberParameters-1].setIntValue(1);
3476#ifdef CBC_KEEP_DEPRECATED
3477     parameters[numberParameters++] =
3478          CbcOrClpParam("strengthen", "Create strengthened problem",
3479                        CBC_PARAM_ACTION_STRENGTHEN, 3);
3480     parameters[numberParameters-1].setLonghelp
3481     (
3482          "This creates a new problem by applying the root node cuts.  All tight constraints \
3483will be in resulting problem"
3484     );
3485#endif
3486     parameters[numberParameters++] =
3487          CbcOrClpParam("strong!Branching", "Number of variables to look at in strong branching",
3488                        0, COIN_INT_MAX, CBC_PARAM_INT_STRONGBRANCHING);
3489     parameters[numberParameters-1].setLonghelp
3490     (
3491          "In order to decide which variable to branch on, the code will choose up to this number \
3492of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
3493If a variable is branched on many times then the previous average up and down costs may be used - \
3494see number before trust."
3495     );
3496#endif
3497#ifdef COIN_HAS_CLP
3498     parameters[numberParameters++] =
3499          CbcOrClpParam("subs!titution", "How long a column to substitute for in presolve",
3500                        0, 10000, CLP_PARAM_INT_SUBSTITUTION, 0);
3501     parameters[numberParameters-1].setLonghelp
3502     (
3503          "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
3504 variables in column.  If you increase this the number of rows may decrease but number of \
3505 elements may increase."
3506     );
3507#endif
3508#ifdef COIN_HAS_CBC
3509     parameters[numberParameters++] =
3510          CbcOrClpParam("testO!si", "Test OsiObject stuff",
3511                        -1, COIN_INT_MAX, CBC_PARAM_INT_TESTOSI, 0);
3512#endif
3513#ifdef CBC_THREAD
3514     parameters[numberParameters++] =
3515          CbcOrClpParam("thread!s", "Number of threads to try and use",
3516                        -100, 100000, CBC_PARAM_INT_THREADS, 1);
3517     parameters[numberParameters-1].setLonghelp
3518     (
3519          "To use multiple threads, set threads to number wanted.  It may be better \
3520to use one or two more than number of cpus available.  If 100+n then n threads and \
3521search is repeatable (maybe be somewhat slower), \
3522if 200+n use threads for root cuts, 400+n threads used in sub-trees."
3523     );
3524#endif
3525#ifdef COIN_HAS_CBC
3526     parameters[numberParameters++] =
3527          CbcOrClpParam("tighten!Factor", "Tighten bounds using this times largest \
3528activity at continuous solution",
3529                        1.0e-3, 1.0e20, CBC_PARAM_DBL_TIGHTENFACTOR, 0);
3530     parameters[numberParameters-1].setLonghelp
3531     (
3532          "This sleazy trick can help on some problems."
3533     );
3534#endif
3535#ifdef COIN_HAS_CLP
3536     parameters[numberParameters++] =
3537          CbcOrClpParam("tightLP", "Poor person's preSolve for now",
3538                        CLP_PARAM_ACTION_TIGHTEN, 7, 0);
3539#endif
3540     parameters[numberParameters++] =
3541          CbcOrClpParam("timeM!ode", "Whether to use CPU or elapsed time",
3542                        "cpu", CLP_PARAM_STR_TIME_MODE);
3543     parameters[numberParameters-1].append("elapsed");
3544     parameters[numberParameters-1].setLonghelp
3545     (
3546          "cpu uses CPU time for stopping, while elapsed uses elapsed time. \
3547(On Windows, elapsed time is always used)."
3548     );
3549#ifdef COIN_HAS_CBC
3550     parameters[numberParameters++] =
3551          CbcOrClpParam("trust!PseudoCosts", "Number of branches before we trust pseudocosts",
3552                        -3, 2000000000, CBC_PARAM_INT_NUMBERBEFORE);
3553     parameters[numberParameters-1].setLonghelp
3554     (
3555          "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
3556trust the pseudo costs and do not do any more strong branching."
3557     );
3558#endif
3559#ifdef COIN_HAS_CBC
3560     parameters[numberParameters++] =
3561          CbcOrClpParam("tune!PreProcess", "Dubious tuning parameters",
3562                        0, 20000000, CLP_PARAM_INT_PROCESSTUNE, 1);
3563     parameters[numberParameters-1].setLonghelp
3564     (
3565          "For making equality cliques this is minimumsize.  Also for adding \
3566integer slacks.  May be used for more later \
3567If <10000 that is what it does.  If <1000000 - numberPasses is (value/10000)-1 and tune is tune %10000. \
3568If >= 1000000! - numberPasses is (value/1000000)-1 and tune is tune %1000000.  In this case if tune is now still >=10000 \
3569numberPassesPerInnerLoop is changed from 10 to (tune-10000)-1 and tune becomes tune % 10000!!!!! - happy? - \
3570so to keep normal limit on cliques of 5, do 3 major passes (include presolves) but only doing one tightening pass per major pass - \
3571you would use 3010005 (I think)"
3572     );
3573     parameters[numberParameters++] =
3574          CbcOrClpParam("two!MirCuts", "Whether to use Two phase Mixed Integer Rounding cuts",
3575                        "off", CBC_PARAM_STR_TWOMIRCUTS);
3576     parameters[numberParameters-1].append("on");
3577     parameters[numberParameters-1].append("root");
3578     parameters[numberParameters-1].append("ifmove");
3579     parameters[numberParameters-1].append("forceOn");
3580     parameters[numberParameters-1].append("onglobal");
3581     parameters[numberParameters-1].append("forceandglobal");
3582     parameters[numberParameters-1].append("forceLongOn");
3583     parameters[numberParameters-1].setLonghelp
3584     (
3585          "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
3586See branchAndCut for information on options."
3587     );
3588#endif
3589     parameters[numberParameters++] =
3590          CbcOrClpParam("unitTest", "Do unit test",
3591                        CLP_PARAM_ACTION_UNITTEST, 3, 1);
3592     parameters[numberParameters-1].setLonghelp
3593     (
3594          "This exercises the unit test for clp"
3595     );
3596     parameters[numberParameters++] =
3597          CbcOrClpParam("userClp", "Hand coded Clp stuff",
3598                        CLP_PARAM_ACTION_USERCLP, 0, 0);
3599     parameters[numberParameters-1].setLonghelp
3600     (
3601          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3602Look for USERCLP in main driver and modify sample code."
3603     );
3604#ifdef COIN_HAS_CBC
3605     parameters[numberParameters++] =
3606          CbcOrClpParam("userCbc", "Hand coded Cbc stuff",
3607                        CBC_PARAM_ACTION_USERCBC, 0, 0);
3608     parameters[numberParameters-1].setLonghelp
3609     (
3610          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3611Look for USERCBC in main driver and modify sample code. \
3612It is possible you can get same effect by using example driver4.cpp."
3613     );
3614     parameters[numberParameters++] =
3615          CbcOrClpParam("Vnd!VariableNeighborhoodSearch", "Whether to try Variable Neighborhood Search",
3616                        "off", CBC_PARAM_STR_VND);
3617     parameters[numberParameters-1].append("on");
3618     parameters[numberParameters-1].append("both");
3619     parameters[numberParameters-1].append("before");
3620     parameters[numberParameters-1].append("intree");
3621     parameters[numberParameters-1].setLonghelp
3622     (
3623          "This switches on variable neighborhood Search. \
3624Doh option does heuristic before preprocessing"     );
3625#endif
3626     parameters[numberParameters++] =
3627          CbcOrClpParam("vector", "Whether to use vector? Form of matrix in simplex",
3628                        "off", CLP_PARAM_STR_VECTOR, 7, 0);
3629     parameters[numberParameters-1].append("on");
3630     parameters[numberParameters-1].setLonghelp
3631     (
3632          "If this is on ClpPackedMatrix uses extra column copy in odd format."
3633     );
3634     parameters[numberParameters++] =
3635          CbcOrClpParam("verbose", "Switches on longer help on single ?",
3636                        0, 31, CLP_PARAM_INT_VERBOSE, 0);
3637     parameters[numberParameters-1].setLonghelp
3638     (
3639          "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
3640     );
3641     parameters[numberParameters-1].setIntValue(0);
3642#ifdef COIN_HAS_CBC
3643     parameters[numberParameters++] =
3644          CbcOrClpParam("vub!heuristic", "Type of vub heuristic",
3645                        -2, 20, CBC_PARAM_INT_VUBTRY, 0);
3646     parameters[numberParameters-1].setLonghelp
3647     (
3648          "If set will try and fix some integer variables"
3649     );
3650     parameters[numberParameters-1].setIntValue(-1);
3651     parameters[numberParameters++] =
3652          CbcOrClpParam("zero!HalfCuts", "Whether to use zero half cuts",
3653                        "off", CBC_PARAM_STR_ZEROHALFCUTS);
3654     parameters[numberParameters-1].append("on");
3655     parameters[numberParameters-1].append("root");
3656     parameters[numberParameters-1].append("ifmove");
3657     parameters[numberParameters-1].append("forceOn");
3658     parameters[numberParameters-1].append("onglobal");
3659     parameters[numberParameters-1].setLonghelp
3660     (
3661          "This switches on zero-half cuts (either at root or in entire tree) \
3662See branchAndCut for information on options.  This implementation was written by \
3663Alberto Caprara."
3664     );
3665#endif
3666     parameters[numberParameters++] =
3667          CbcOrClpParam("zeroT!olerance", "Kill all coefficients \
3668whose absolute value is less than this value",
3669                        1.0e-100, 1.0e-5, CLP_PARAM_DBL_ZEROTOLERANCE);
3670     parameters[numberParameters-1].setLonghelp
3671     (
3672          "This applies to reading mps files (and also lp files \
3673if KILL_ZERO_READLP defined)"
3674     );
3675     parameters[numberParameters-1].setDoubleValue(1.0e-20);
3676     assert(numberParameters < CBCMAXPARAMETERS);
3677}
3678// Given a parameter type - returns its number in list
3679int whichParam (CbcOrClpParameterType name,
3680                int numberParameters, CbcOrClpParam *const parameters)
3681{
3682     int i;
3683     for (i = 0; i < numberParameters; i++) {
3684          if (parameters[i].type() == name)
3685               break;
3686     }
3687     assert (i < numberParameters);
3688     return i;
3689}
3690#ifdef COIN_HAS_CLP
3691/* Restore a solution from file.
3692   mode 0 normal, 1 swap rows and columns and primal and dual
3693   if 2 set then also change signs
3694*/
3695void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode)
3696{
3697     FILE * fp = fopen(fileName.c_str(), "rb");
3698     if (fp) {
3699          int numberRows = lpSolver->numberRows();
3700          int numberColumns = lpSolver->numberColumns();
3701          int numberRowsFile;
3702          int numberColumnsFile;
3703          double objectiveValue;
3704          size_t nRead;
3705          nRead = fread(&numberRowsFile, sizeof(int), 1, fp);
3706          if (nRead != 1)
3707               throw("Error in fread");
3708          nRead = fread(&numberColumnsFile, sizeof(int), 1, fp);
3709          if (nRead != 1)
3710               throw("Error in fread");
3711          nRead = fread(&objectiveValue, sizeof(double), 1, fp);
3712          if (nRead != 1)
3713               throw("Error in fread");
3714          double * dualRowSolution = lpSolver->dualRowSolution();
3715          double * primalRowSolution = lpSolver->primalRowSolution();
3716          double * dualColumnSolution = lpSolver->dualColumnSolution();
3717          double * primalColumnSolution = lpSolver->primalColumnSolution();
3718          if (mode) {
3719               // swap
3720               int k = numberRows;
3721               numberRows = numberColumns;
3722               numberColumns = k;
3723               double * temp;
3724               temp = dualRowSolution;
3725               dualRowSolution = primalColumnSolution;
3726               primalColumnSolution = temp;
3727               temp = dualColumnSolution;
3728               dualColumnSolution = primalRowSolution;
3729               primalRowSolution = temp;
3730          }
3731          if (numberRows > numberRowsFile || numberColumns > numberColumnsFile) {
3732               std::cout << "Mismatch on rows and/or columns - giving up" << std::endl;
3733          } else {
3734               lpSolver->setObjectiveValue(objectiveValue);
3735               if (numberRows == numberRowsFile && numberColumns == numberColumnsFile) {
3736                    nRead = fread(primalRowSolution, sizeof(double), numberRows, fp);
3737                    if (nRead != static_cast<size_t>(numberRows))
3738                         throw("Error in fread");
3739                    nRead = fread(dualRowSolution, sizeof(double), numberRows, fp);
3740                    if (nRead != static_cast<size_t>(numberRows))
3741                         throw("Error in fread");
3742                    nRead = fread(primalColumnSolution, sizeof(double), numberColumns, fp);
3743                    if (nRead != static_cast<size_t>(numberColumns))
3744                         throw("Error in fread");
3745                    nRead = fread(dualColumnSolution, sizeof(double), numberColumns, fp);
3746                    if (nRead != static_cast<size_t>(numberColumns))
3747                         throw("Error in fread");
3748               } else {
3749                    std::cout << "Mismatch on rows and/or columns - truncating" << std::endl;
3750                    double * temp = new double [CoinMax(numberRowsFile, numberColumnsFile)];
3751                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
3752                    if (nRead != static_cast<size_t>(numberRowsFile))
3753                         throw("Error in fread");
3754                    CoinMemcpyN(temp, numberRows, primalRowSolution);
3755                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
3756                    if (nRead != static_cast<size_t>(numberRowsFile))
3757                         throw("Error in fread");
3758                    CoinMemcpyN(temp, numberRows, dualRowSolution);
3759                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
3760                    if (nRead != static_cast<size_t>(numberColumnsFile))
3761                         throw("Error in fread");
3762                    CoinMemcpyN(temp, numberColumns, primalColumnSolution);
3763                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
3764                    if (nRead != static_cast<size_t>(numberColumnsFile))
3765                         throw("Error in fread");
3766                    CoinMemcpyN(temp, numberColumns, dualColumnSolution);
3767                    delete [] temp;
3768                           }
3769               if (mode == 3) {
3770                    int i;
3771                    for (i = 0; i < numberRows; i++) {
3772                         primalRowSolution[i] = -primalRowSolution[i];
3773                         dualRowSolution[i] = -dualRowSolution[i];
3774                    }
3775                    for (i = 0; i < numberColumns; i++) {
3776                         primalColumnSolution[i] = -primalColumnSolution[i];
3777                         dualColumnSolution[i] = -dualColumnSolution[i];
3778                    }
3779               }
3780          }
3781          fclose(fp);
3782     } else {
3783          std::cout << "Unable to open file " << fileName << std::endl;
3784     }
3785}
3786// Dump a solution to file
3787void saveSolution(const ClpSimplex * lpSolver, std::string fileName)
3788{
3789     if (strstr(fileName.c_str(), "_fix_read_")) {
3790          FILE * fp = fopen(fileName.c_str(), "rb");
3791          if (fp) {
3792               ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
3793               restoreSolution(solver, fileName, 0);
3794               // fix all
3795               int logLevel = solver->logLevel();
3796               int iColumn;
3797               int numberColumns = solver->numberColumns();
3798               double * primalColumnSolution =
3799                    solver->primalColumnSolution();
3800               double * columnLower = solver->columnLower();
3801               double * columnUpper = solver->columnUpper();
3802               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3803                    double value = primalColumnSolution[iColumn];
3804                    if (value > columnUpper[iColumn]) {
3805                         if (value > columnUpper[iColumn] + 1.0e-6 && logLevel > 1)
3806                              printf("%d value of %g - bounds %g %g\n",
3807                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
3808                         value = columnUpper[iColumn];
3809                    } else if (value < columnLower[iColumn]) {
3810                         if (value < columnLower[iColumn] - 1.0e-6 && logLevel > 1)
3811                              printf("%d value of %g - bounds %g %g\n",
3812                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
3813                         value = columnLower[iColumn];
3814                    }
3815                    columnLower[iColumn] = value;
3816                    columnUpper[iColumn] = value;
3817               }
3818               return;
3819          }
3820     }
3821     FILE * fp = fopen(fileName.c_str(), "wb");
3822     if (fp) {
3823          int numberRows = lpSolver->numberRows();
3824          int numberColumns = lpSolver->numberColumns();
3825          double objectiveValue = lpSolver->objectiveValue();
3826          size_t nWrite;
3827          nWrite = fwrite(&numberRows, sizeof(int), 1, fp);
3828          if (nWrite != 1)
3829               throw("Error in fwrite");
3830          nWrite = fwrite(&numberColumns, sizeof(int), 1, fp);
3831          if (nWrite != 1)
3832               throw("Error in fwrite");
3833          nWrite = fwrite(&objectiveValue, sizeof(double), 1, fp);
3834          if (nWrite != 1)
3835               throw("Error in fwrite");
3836          double * dualRowSolution = lpSolver->dualRowSolution();
3837          double * primalRowSolution = lpSolver->primalRowSolution();
3838          nWrite = fwrite(primalRowSolution, sizeof(double), numberRows, fp);
3839          if (nWrite != static_cast<size_t>(numberRows))
3840               throw("Error in fwrite");
3841          nWrite = fwrite(dualRowSolution, sizeof(double), numberRows, fp);
3842          if (nWrite != static_cast<size_t>(numberRows))
3843               throw("Error in fwrite");
3844          double * dualColumnSolution = lpSolver->dualColumnSolution();
3845          double * primalColumnSolution = lpSolver->primalColumnSolution();
3846          nWrite = fwrite(primalColumnSolution, sizeof(double), numberColumns, fp);
3847          if (nWrite != static_cast<size_t>(numberColumns))
3848               throw("Error in fwrite");
3849          nWrite = fwrite(dualColumnSolution, sizeof(double), numberColumns, fp);
3850          if (nWrite != static_cast<size_t>(numberColumns))
3851               throw("Error in fwrite");
3852          fclose(fp);
3853     } else {
3854          std::cout << "Unable to open file " << fileName << std::endl;
3855     }
3856}
3857#endif
Note: See TracBrowser for help on using the repository browser.