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

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

weird compiler error

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