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

Last change on this file since 1973 was 1973, checked in by forrest, 6 years ago

try and trap bad primal bases

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