source: stable/1.15/Clp/src/CbcOrClpParam.cpp @ 2011

Last change on this file since 2011 was 2011, checked in by forrest, 5 years ago

fix for odd case of COIN_INT_MAX being 0

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