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

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

changes to allow more options and stop on feasible (and a few other things)

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