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

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

changes to diving heuristics

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 170.8 KB
Line 
1/* $Id: CbcOrClpParam.cpp 2069 2014-11-06 15:50:00Z forrest $ */
2// Copyright (C) 2002, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#include "CoinPragma.hpp"
7#include "CoinTime.hpp"
8#include "CbcOrClpParam.hpp"
9
10#include <string>
11#include <iostream>
12#include <cassert>
13
14#ifdef COIN_HAS_CBC
15#ifdef COIN_HAS_CLP
16#include "OsiClpSolverInterface.hpp"
17#include "ClpSimplex.hpp"
18#endif
19#include "CbcModel.hpp"
20#endif
21#include "CoinHelperFunctions.hpp"
22#ifdef COIN_HAS_CLP
23#include "ClpSimplex.hpp"
24#include "ClpFactorization.hpp"
25#endif
26#ifdef COIN_HAS_READLINE
27#include <readline/readline.h>
28#include <readline/history.h>
29#endif
30#ifdef COIN_HAS_CBC
31// from CoinSolve
32static char coin_prompt[] = "Coin:";
33#else
34static char coin_prompt[] = "Clp:";
35#endif
36#ifdef CLP_CILK
37#ifndef CBC_THREAD
38#define CBC_THREAD
39#endif
40#endif
41#if defined(COIN_HAS_WSMP) && ! defined(USE_EKKWSSMP)
42#ifndef CBC_THREAD
43#define CBC_THREAD
44#endif
45#endif
46#include "ClpConfig.h"
47#ifdef CLP_HAS_ABC
48#include "AbcCommon.hpp"
49#endif
50static bool doPrinting = true;
51std::string afterEquals = "";
52static char printArray[200];
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=0;
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].append("variable");
1670     parameters[numberParameters-1].append("forcevariable");
1671     parameters[numberParameters-1].setLonghelp
1672     (
1673          "This adds the objective as a constraint with best solution as RHS"
1674     );
1675     parameters[numberParameters++] =
1676          CbcOrClpParam("cost!Strategy", "How to use costs as priorities",
1677                        "off", CBC_PARAM_STR_COSTSTRATEGY);
1678     parameters[numberParameters-1].append("pri!orities");
1679     parameters[numberParameters-1].append("column!Order?");
1680     parameters[numberParameters-1].append("01f!irst?");
1681     parameters[numberParameters-1].append("01l!ast?");
1682     parameters[numberParameters-1].append("length!?");
1683     parameters[numberParameters-1].append("singletons");
1684     parameters[numberParameters-1].append("nonzero");
1685     parameters[numberParameters-1].append("general!Force?");
1686     parameters[numberParameters-1].setLonghelp
1687     (
1688          "This orders the variables in order of their absolute costs - with largest cost ones being branched on \
1689first.  This primitive strategy can be surprsingly effective.  The column order\
1690 option is obviously not on costs but easy to code here."
1691     );
1692     parameters[numberParameters++] =
1693          CbcOrClpParam("cplex!Use", "Whether to use Cplex!",
1694                        "off", CBC_PARAM_STR_CPX);
1695     parameters[numberParameters-1].append("on");
1696     parameters[numberParameters-1].setLonghelp
1697     (
1698          " If the user has Cplex, but wants to use some of Cbc's heuristics \
1699then you can!  If this is on, then Cbc will get to the root node and then \
1700hand over to Cplex.  If heuristics find a solution this can be significantly \
1701quicker.  You will probably want to switch off Cbc's cuts as Cplex thinks \
1702they are genuine constraints.  It is also probable that you want to switch \
1703off preprocessing, although for difficult problems it is worth trying \
1704both."
1705     );
1706#endif
1707     parameters[numberParameters++] =
1708          CbcOrClpParam("cpp!Generate", "Generates C++ code",
1709                        -1, 50000, CLP_PARAM_INT_CPP, 1);
1710     parameters[numberParameters-1].setLonghelp
1711     (
1712          "Once you like what the stand-alone solver does then this allows \
1713you to generate user_driver.cpp which approximates the code.  \
17140 gives simplest driver, 1 generates saves and restores, 2 \
1715generates saves and restores even for variables at default value. \
17164 bit in cbc generates size dependent code rather than computed values.  \
1717This is now deprecated as you can call stand-alone solver - see \
1718Cbc/examples/driver4.cpp."
1719     );
1720#ifdef COIN_HAS_CLP
1721     parameters[numberParameters++] =
1722          CbcOrClpParam("crash", "Whether to create basis for problem",
1723                        "off", CLP_PARAM_STR_CRASH);
1724     parameters[numberParameters-1].append("on");
1725     parameters[numberParameters-1].append("so!low_halim");
1726     parameters[numberParameters-1].append("lots");
1727#ifdef ABC_INHERIT
1728     parameters[numberParameters-1].append("dual");
1729     parameters[numberParameters-1].append("dw");
1730     parameters[numberParameters-1].append("idiot");
1731#endif
1732     parameters[numberParameters-1].setLonghelp
1733     (
1734          "If crash is set on and there is an all slack basis then Clp will flip or put structural\
1735 variables into basis with the aim of getting dual feasible.  On the whole dual seems to be\
1736 better without it and there are alternative types of 'crash' for primal e.g. 'idiot' or 'sprint'. \
1737I have also added a variant due to Solow and Halim which is as on but just flip.");
1738     parameters[numberParameters++] =
1739          CbcOrClpParam("cross!over", "Whether to get a basic solution after barrier",
1740                        "on", CLP_PARAM_STR_CROSSOVER);
1741     parameters[numberParameters-1].append("off");
1742     parameters[numberParameters-1].append("maybe");
1743     parameters[numberParameters-1].append("presolve");
1744     parameters[numberParameters-1].setLonghelp
1745     (
1746          "Interior point algorithms do not obtain a basic solution (and \
1747the feasibility criterion is a bit suspect (JJF)).  This option will crossover \
1748to a basic solution suitable for ranging or branch and cut.  With the current state \
1749of quadratic it may be a good idea to switch off crossover for quadratic (and maybe \
1750presolve as well) - the option maybe does this."
1751     );
1752#endif
1753#ifdef COIN_HAS_CBC
1754     parameters[numberParameters++] =
1755          CbcOrClpParam("csv!Statistics", "Create one line of statistics",
1756                        CLP_PARAM_ACTION_CSVSTATISTICS, 2, 1);
1757     parameters[numberParameters-1].setLonghelp
1758     (
1759          "This appends statistics to given file name.  It will use the default\
1760 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1761 is initialized to '', i.e. it must be set.  Adds header if file empty or does not exist."
1762     );
1763     parameters[numberParameters++] =
1764          CbcOrClpParam("cutD!epth", "Depth in tree at which to do cuts",
1765                        -1, 999999, CBC_PARAM_INT_CUTDEPTH);
1766     parameters[numberParameters-1].setLonghelp
1767     (
1768          "Cut generators may be - off, on only at root, on if they look possible \
1769and on.  If they are done every node then that is that, but it may be worth doing them \
1770every so often.  The original method was every so many nodes but it is more logical \
1771to do it whenever depth in tree is a multiple of K.  This option does that and defaults \
1772to -1 (off -> code decides)."
1773     );
1774     parameters[numberParameters-1].setIntValue(-1);
1775     parameters[numberParameters++] =
1776          CbcOrClpParam("cutL!ength", "Length of a cut",
1777                        -1, COIN_INT_MAX, CBC_PARAM_INT_CUTLENGTH);
1778     parameters[numberParameters-1].setLonghelp
1779     (
1780          "At present this only applies to Gomory cuts. -1 (default) leaves as is. \
1781Any value >0 says that all cuts <= this length can be generated both at \
1782root node and in tree. 0 says to use some dynamic lengths.  If value >=10,000,000 \
1783then the length in tree is value%10000000 - so 10000100 means unlimited length \
1784at root and 100 in tree."
1785     );
1786     parameters[numberParameters-1].setIntValue(-1);
1787     parameters[numberParameters++] =
1788          CbcOrClpParam("cuto!ff", "All solutions must be better than this",
1789                        -1.0e60, 1.0e60, CBC_PARAM_DBL_CUTOFF);
1790     parameters[numberParameters-1].setDoubleValue(1.0e50);
1791     parameters[numberParameters-1].setLonghelp
1792     (
1793          "All solutions must be better than this value (in a minimization sense).  \
1794This is also set by code whenever it obtains a solution and is set to value of \
1795objective for solution minus cutoff increment."
1796     );
1797     parameters[numberParameters++] =
1798          CbcOrClpParam("cuts!OnOff", "Switches all cuts on or off",
1799                        "off", CBC_PARAM_STR_CUTSSTRATEGY);
1800     parameters[numberParameters-1].append("on");
1801     parameters[numberParameters-1].append("root");
1802     parameters[numberParameters-1].append("ifmove");
1803     parameters[numberParameters-1].append("forceOn");
1804     parameters[numberParameters-1].setLonghelp
1805     (
1806          "This can be used to switch on or off all cuts (apart from Reduce and Split).  Then you can do \
1807individual ones off or on \
1808See branchAndCut for information on options."
1809     );
1810     parameters[numberParameters++] =
1811          CbcOrClpParam("debug!In", "read valid solution from file",
1812                        CLP_PARAM_ACTION_DEBUG, 7, 1);
1813     parameters[numberParameters-1].setLonghelp
1814     (
1815          "This will read a solution file from the given file name.  It will use the default\
1816 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
1817 is initialized to '', i.e. it must be set.\n\n\
1818If set to create it will create a file called debug.file  after search.\n\n\
1819The idea is that if you suspect a bad cut generator \
1820you can do a good run with debug set to 'create' and then switch on the cuts you suspect and \
1821re-run with debug set to 'debug.file'  The create case has same effect as saveSolution."
1822     );
1823#endif
1824#ifdef COIN_HAS_CLP
1825     parameters[numberParameters++] =
1826          CbcOrClpParam("decomp!ose", "Whether to try decomposition",
1827                        -COIN_INT_MAX, COIN_INT_MAX, CLP_PARAM_INT_DECOMPOSE_BLOCKS, 1);
1828     parameters[numberParameters-1].setLonghelp
1829     (
1830          "0 - off, 1 choose blocks >1 use as blocks \
1831Dantzig Wolfe if primal, Benders if dual \
1832- uses sprint pass for number of passes"
1833     );
1834     parameters[numberParameters-1].setIntValue(0);
1835#if CLP_MULTIPLE_FACTORIZATIONS >0
1836     parameters[numberParameters++] =
1837          CbcOrClpParam("dense!Threshold", "Whether to use dense factorization",
1838                        -1, 10000, CBC_PARAM_INT_DENSE, 1);
1839     parameters[numberParameters-1].setLonghelp
1840     (
1841          "If processed problem <= this use dense factorization"
1842     );
1843     parameters[numberParameters-1].setIntValue(-1);
1844#endif
1845#endif
1846#ifdef COIN_HAS_CBC
1847     parameters[numberParameters++] =
1848          CbcOrClpParam("depth!MiniBab", "Depth at which to try mini BAB",
1849                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_DEPTHMINIBAB);
1850     parameters[numberParameters-1].setIntValue(-1);
1851     parameters[numberParameters-1].setLonghelp
1852     (
1853          "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 \
1854means 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."
1855     );
1856     parameters[numberParameters++] =
1857          CbcOrClpParam("dextra3", "Extra double parameter 3",
1858                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA3, 0);
1859     parameters[numberParameters-1].setDoubleValue(0.0);
1860     parameters[numberParameters++] =
1861          CbcOrClpParam("dextra4", "Extra double parameter 4",
1862                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA4, 0);
1863     parameters[numberParameters-1].setDoubleValue(0.0);
1864     parameters[numberParameters++] =
1865          CbcOrClpParam("dextra5", "Extra double parameter 5",
1866                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_DEXTRA5, 0);
1867     parameters[numberParameters-1].setDoubleValue(0.0);
1868     parameters[numberParameters++] =
1869          CbcOrClpParam("Dins", "Whether to try Distance Induced Neighborhood Search",
1870                        "off", CBC_PARAM_STR_DINS);
1871     parameters[numberParameters-1].append("on");
1872     parameters[numberParameters-1].append("both");
1873     parameters[numberParameters-1].append("before");
1874     parameters[numberParameters-1].append("often");
1875     parameters[numberParameters-1].setLonghelp
1876     (
1877          "This switches on Distance induced neighborhood Search. \
1878See Rounding for meaning of on,both,before"
1879     );
1880#endif
1881     parameters[numberParameters++] =
1882          CbcOrClpParam("direction", "Minimize or Maximize",
1883                        "min!imize", CLP_PARAM_STR_DIRECTION);
1884     parameters[numberParameters-1].append("max!imize");
1885     parameters[numberParameters-1].append("zero");
1886     parameters[numberParameters-1].setLonghelp
1887     (
1888          "The default is minimize - use 'direction maximize' for maximization.\n\
1889You can also use the parameters 'maximize' or 'minimize'."
1890     );
1891     parameters[numberParameters++] =
1892          CbcOrClpParam("directory", "Set Default directory for import etc.",
1893                        CLP_PARAM_ACTION_DIRECTORY);
1894     parameters[numberParameters-1].setLonghelp
1895     (
1896          "This sets the directory which import, export, saveModel, restoreModel etc will use.\
1897  It is initialized to './'"
1898     );
1899     parameters[numberParameters++] =
1900          CbcOrClpParam("dirSample", "Set directory where the COIN-OR sample problems are.",
1901                        CLP_PARAM_ACTION_DIRSAMPLE, 7, 1);
1902     parameters[numberParameters-1].setLonghelp
1903     (
1904          "This sets the directory where the COIN-OR sample problems reside. It is\
1905 used only when -unitTest is passed to clp. clp will pick up the test problems\
1906 from this directory.\
1907 It is initialized to '../../Data/Sample'"
1908     );
1909     parameters[numberParameters++] =
1910          CbcOrClpParam("dirNetlib", "Set directory where the netlib problems are.",
1911                        CLP_PARAM_ACTION_DIRNETLIB, 7, 1);
1912     parameters[numberParameters-1].setLonghelp
1913     (
1914          "This sets the directory where the netlib problems reside. One can get\
1915 the netlib problems from COIN-OR or from the main netlib site. This\
1916 parameter is used only when -netlib is passed to clp. clp will pick up the\
1917 netlib problems from this directory. If clp is built without zlib support\
1918 then the problems must be uncompressed.\
1919 It is initialized to '../../Data/Netlib'"
1920     );
1921     parameters[numberParameters++] =
1922          CbcOrClpParam("dirMiplib", "Set directory where the miplib 2003 problems are.",
1923                        CBC_PARAM_ACTION_DIRMIPLIB, 7, 1);
1924     parameters[numberParameters-1].setLonghelp
1925     (
1926          "This sets the directory where the miplib 2003 problems reside. One can\
1927 get the miplib problems from COIN-OR or from the main miplib site. This\
1928 parameter is used only when -miplib is passed to cbc. cbc will pick up the\
1929 miplib problems from this directory. If cbc is built without zlib support\
1930 then the problems must be uncompressed.\
1931 It is initialized to '../../Data/miplib3'"
1932     );
1933#ifdef COIN_HAS_CBC
1934     parameters[numberParameters++] =
1935          CbcOrClpParam("diveO!pt", "Diving options",
1936                        -1, 200000, CBC_PARAM_INT_DIVEOPT, 1);
1937     parameters[numberParameters-1].setLonghelp
1938     (
1939          "If >2 && <20 then modify diving options - \
1940         \n\t3 only at root and if no solution,  \
1941         \n\t4 only at root and if this heuristic has not got solution, \
1942         \n\t5 decay only if no solution, \
1943         \n\t6 if depth <3 or decay, \
1944         \n\t7 run up to 2 times if solution found 4 otherwise, \
1945         \n\t>10 All only at root (DivingC normal as value-10), \
1946         \n\t>10 All with value-20)."
1947     );
1948     parameters[numberParameters-1].setIntValue(-1);
1949     parameters[numberParameters++] =
1950          CbcOrClpParam("diveS!olves", "Diving solve option",
1951                        -1, 200000, CBC_PARAM_INT_DIVEOPTSOLVES, 1);
1952     parameters[numberParameters-1].setLonghelp
1953     (
1954          "If >0 then do up to this many solves.  Last digit is ignored \
1955and used for extra options - \
1956         \n\t1-3 allow fixing of satisfied integers (but not at bound) \
1957         \n\t1 switch off above for that dive if goes infeasible \
1958         \n\t2 switch off above permanenty if goes infeasible"
1959     );
1960     parameters[numberParameters-1].setIntValue(100);
1961     parameters[numberParameters++] =
1962          CbcOrClpParam("DivingS!ome", "Whether to try Diving heuristics",
1963                        "off", CBC_PARAM_STR_DIVINGS);
1964     parameters[numberParameters-1].append("on");
1965     parameters[numberParameters-1].append("both");
1966     parameters[numberParameters-1].append("before");
1967     parameters[numberParameters-1].setLonghelp
1968     (
1969          "This switches on a random diving heuristic at various times. \
1970C - Coefficient, F - Fractional, G - Guided, L - LineSearch, P - PseudoCost, V - VectorLength. \
1971You may prefer to use individual on/off \
1972See Rounding for meaning of on,both,before"
1973     );
1974     parameters[numberParameters++] =
1975          CbcOrClpParam("DivingC!oefficient", "Whether to try DiveCoefficient",
1976                        "off", CBC_PARAM_STR_DIVINGC);
1977     parameters[numberParameters-1].append("on");
1978     parameters[numberParameters-1].append("both");
1979     parameters[numberParameters-1].append("before");
1980     parameters[numberParameters++] =
1981          CbcOrClpParam("DivingF!ractional", "Whether to try DiveFractional",
1982                        "off", CBC_PARAM_STR_DIVINGF);
1983     parameters[numberParameters-1].append("on");
1984     parameters[numberParameters-1].append("both");
1985     parameters[numberParameters-1].append("before");
1986     parameters[numberParameters++] =
1987          CbcOrClpParam("DivingG!uided", "Whether to try DiveGuided",
1988                        "off", CBC_PARAM_STR_DIVINGG);
1989     parameters[numberParameters-1].append("on");
1990     parameters[numberParameters-1].append("both");
1991     parameters[numberParameters-1].append("before");
1992     parameters[numberParameters++] =
1993          CbcOrClpParam("DivingL!ineSearch", "Whether to try DiveLineSearch",
1994                        "off", CBC_PARAM_STR_DIVINGL);
1995     parameters[numberParameters-1].append("on");
1996     parameters[numberParameters-1].append("both");
1997     parameters[numberParameters-1].append("before");
1998     parameters[numberParameters++] =
1999          CbcOrClpParam("DivingP!seudoCost", "Whether to try DivePseudoCost",
2000                        "off", CBC_PARAM_STR_DIVINGP);
2001     parameters[numberParameters-1].append("on");
2002     parameters[numberParameters-1].append("both");
2003     parameters[numberParameters-1].append("before");
2004     parameters[numberParameters++] =
2005          CbcOrClpParam("DivingV!ectorLength", "Whether to try DiveVectorLength",
2006                        "off", CBC_PARAM_STR_DIVINGV);
2007     parameters[numberParameters-1].append("on");
2008     parameters[numberParameters-1].append("both");
2009     parameters[numberParameters-1].append("before");
2010     parameters[numberParameters++] =
2011          CbcOrClpParam("doH!euristic", "Do heuristics before any preprocessing",
2012                        CBC_PARAM_ACTION_DOHEURISTIC, 3);
2013     parameters[numberParameters-1].setLonghelp
2014     (
2015          "Normally heuristics are done in branch and bound.  It may be useful to do them outside. \
2016Only those heuristics with 'both' or 'before' set will run.  \
2017Doing this may also set cutoff, which can help with preprocessing."
2018     );
2019#endif
2020#ifdef COIN_HAS_CLP
2021     parameters[numberParameters++] =
2022          CbcOrClpParam("dualB!ound", "Initially algorithm acts as if no \
2023gap between bounds exceeds this value",
2024                        1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALBOUND);
2025     parameters[numberParameters-1].setLonghelp
2026     (
2027          "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
2028 algorithm where you first get feasible then optimal.  If a problem has both upper and\
2029 lower bounds then it is trivial to get dual feasible by setting non basic variables\
2030 to correct bound.  If the gap between the upper and lower bounds of a variable is more\
2031 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
2032 dual feasible.  This has the same effect as a composite objective function in the\
2033 primal algorithm.  Too high a value may mean more iterations, while too low a bound means\
2034 the code may go all the way and then have to increase the bounds.  OSL had a heuristic to\
2035 adjust bounds, maybe we need that here."
2036     );
2037     parameters[numberParameters++] =
2038          CbcOrClpParam("dualize", "Solves dual reformulation",
2039                        0, 4, CLP_PARAM_INT_DUALIZE, 1);
2040     parameters[numberParameters-1].setLonghelp
2041     (
2042          "Don't even think about it."
2043     );
2044     parameters[numberParameters++] =
2045          CbcOrClpParam("dualP!ivot", "Dual pivot choice algorithm",
2046                        "auto!matic", CLP_PARAM_STR_DUALPIVOT, 7, 1);
2047     parameters[numberParameters-1].append("dant!zig");
2048     parameters[numberParameters-1].append("partial");
2049     parameters[numberParameters-1].append("steep!est");
2050     parameters[numberParameters-1].setLonghelp
2051     (
2052          "Clp can use any pivot selection algorithm which the user codes as long as it\
2053 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
2054 to show a simple method but its use is deprecated.  Steepest is the method of choice and there\
2055 are two variants which keep all weights updated but only scan a subset each iteration.\
2056 Partial switches this on while automatic decides at each iteration based on information\
2057 about the factorization."
2058     );
2059     parameters[numberParameters++] =
2060          CbcOrClpParam("dualS!implex", "Do dual simplex algorithm",
2061                        CLP_PARAM_ACTION_DUALSIMPLEX);
2062     parameters[numberParameters-1].setLonghelp
2063     (
2064          "This command solves the continuous relaxation of the current model using the dual steepest edge algorithm.\
2065The time and iterations may be affected by settings such as presolve, scaling, crash\
2066 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
2067     );
2068#endif
2069     parameters[numberParameters++] =
2070          CbcOrClpParam("dualT!olerance", "For an optimal solution \
2071no dual infeasibility may exceed this value",
2072                        1.0e-20, 1.0e12, CLP_PARAM_DBL_DUALTOLERANCE);
2073     parameters[numberParameters-1].setLonghelp
2074     (
2075          "Normally the default tolerance is fine, but you may want to increase it a\
2076 bit if a dual run seems to be having a hard time.  One method which can be faster is \
2077to use a large tolerance e.g. 1.0e-4 and dual and then clean up problem using primal and the \
2078correct tolerance (remembering to switch off presolve for this final short clean up phase)."
2079     );
2080#ifdef COIN_HAS_CBC
2081     parameters[numberParameters++] =
2082          CbcOrClpParam("dw!Heuristic", "Whether to try DW heuristic",
2083                        "off", CBC_PARAM_STR_DW);
2084     parameters[numberParameters-1].append("on");
2085     parameters[numberParameters-1].append("both");
2086     parameters[numberParameters-1].append("before");
2087     parameters[numberParameters-1].setLonghelp
2088     (
2089      "See Rounding for meaning of on,both,before"
2090     );
2091#endif
2092#ifdef COIN_HAS_CLP
2093     parameters[numberParameters++] =
2094          CbcOrClpParam("either!Simplex", "Do dual or primal simplex algorithm",
2095                        CLP_PARAM_ACTION_EITHERSIMPLEX);
2096     parameters[numberParameters-1].setLonghelp
2097     (
2098          "This command solves the continuous relaxation of the current model using the dual or primal algorithm,\
2099 based on a dubious analysis of model."
2100     );
2101#endif
2102     parameters[numberParameters++] =
2103          CbcOrClpParam("end", "Stops clp execution",
2104                        CLP_PARAM_ACTION_EXIT);
2105     parameters[numberParameters-1].setLonghelp
2106     (
2107          "This stops execution ; end, exit, quit and stop are synonyms"
2108     );
2109     parameters[numberParameters++] =
2110          CbcOrClpParam("environ!ment", "Read commands from environment",
2111                        CLP_PARAM_ACTION_ENVIRONMENT, 7, 0);
2112     parameters[numberParameters-1].setLonghelp
2113     (
2114          "This starts reading from environment variable CBC_CLP_ENVIRONMENT."
2115     );
2116     parameters[numberParameters++] =
2117          CbcOrClpParam("error!sAllowed", "Whether to allow import errors",
2118                        "off", CLP_PARAM_STR_ERRORSALLOWED, 3);
2119     parameters[numberParameters-1].append("on");
2120     parameters[numberParameters-1].setLonghelp
2121     (
2122          "The default is not to use any model which had errors when reading the mps file.\
2123  Setting this to 'on' will allow all errors from which the code can recover\
2124 simply by ignoring the error.  There are some errors from which the code can not recover \
2125e.g. no ENDATA.  This has to be set before import i.e. -errorsAllowed on -import xxxxxx.mps."
2126     );
2127     parameters[numberParameters++] =
2128          CbcOrClpParam("exit", "Stops clp execution",
2129                        CLP_PARAM_ACTION_EXIT);
2130     parameters[numberParameters-1].setLonghelp
2131     (
2132          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
2133     );
2134#ifdef COIN_HAS_CBC
2135     parameters[numberParameters++] =
2136          CbcOrClpParam("exper!iment", "Whether to use testing features",
2137                        -1, 200, CBC_PARAM_INT_EXPERIMENT, 0);
2138     parameters[numberParameters-1].setLonghelp
2139     (
2140          "Defines how adventurous you want to be in using new ideas. \
21410 then no new ideas, 1 fairly sensible, 2 a bit dubious, 3 you are on your own!"
2142     );
2143     parameters[numberParameters-1].setIntValue(0);
2144     parameters[numberParameters++] =
2145          CbcOrClpParam("expensive!Strong", "Whether to do even more strong branching",
2146                        0, COIN_INT_MAX, CBC_PARAM_INT_STRONG_STRATEGY, 0);
2147     parameters[numberParameters-1].setLonghelp
2148     (
2149      "Strategy for extra strong branching \n\
2150\n\t0 - normal\n\
2151\n\twhen to do all fractional\n\
2152\n\t1 - root node\n\
2153\n\t2 - depth less than modifier\n\
2154\n\t4 - if objective == best possible\n\
2155\n\t6 - as 2+4\n\
2156\n\twhen to do all including satisfied\n\
2157\n\t10 - root node etc.\n\
2158\n\tIf >=100 then do when depth <= strategy/100 (otherwise 5)"
2159     );
2160     parameters[numberParameters-1].setIntValue(0);
2161#endif
2162     parameters[numberParameters++] =
2163          CbcOrClpParam("export", "Export model as mps file",
2164                        CLP_PARAM_ACTION_EXPORT);
2165     parameters[numberParameters-1].setLonghelp
2166     (
2167          "This will write an MPS format file to the given file name.  It will use the default\
2168 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2169 is initialized to 'default.mps'.  \
2170It 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."
2171     );
2172#ifdef COIN_HAS_CBC
2173     parameters[numberParameters++] =
2174          CbcOrClpParam("extra1", "Extra integer parameter 1",
2175                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA1, 0);
2176     parameters[numberParameters-1].setIntValue(-1);
2177     parameters[numberParameters++] =
2178          CbcOrClpParam("extra2", "Extra integer parameter 2",
2179                        -100, COIN_INT_MAX, CBC_PARAM_INT_EXTRA2, 0);
2180     parameters[numberParameters-1].setIntValue(-1);
2181     parameters[numberParameters++] =
2182          CbcOrClpParam("extra3", "Extra integer parameter 3",
2183                        -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA3, 0);
2184     parameters[numberParameters-1].setIntValue(-1);
2185     parameters[numberParameters++] =
2186          CbcOrClpParam("extra4", "Extra integer parameter 4",
2187                        -1, COIN_INT_MAX, CBC_PARAM_INT_EXTRA4, 0);
2188     parameters[numberParameters-1].setIntValue(-1);
2189     parameters[numberParameters-1].setLonghelp
2190     (
2191          "This switches on yet more special options!! \
2192The bottom digit is a strategy when to used shadow price stuff e.g. 3 \
2193means use until a solution is found.  The next two digits say what sort \
2194of dual information to use.  After that it goes back to powers of 2 so -\n\
2195\n\t1000 - switches on experimental hotstart\n\
2196\n\t2,4,6000 - switches on experimental methods of stopping cuts\n\
2197\n\t8000 - increase minimum drop gradually\n\
2198\n\t16000 - switches on alternate gomory criterion"
2199     );
2200     parameters[numberParameters++] =
2201       CbcOrClpParam("extraV!ariables", "Allow creation of extra integer variables",
2202                     -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_EXTRA_VARIABLES, 0);
2203     parameters[numberParameters-1].setIntValue(0);
2204     parameters[numberParameters-1].setLonghelp
2205     (
2206          "This switches on creation of extra integer variables \
2207to gather all variables with same cost."
2208     );
2209#endif
2210#ifdef COIN_HAS_CLP
2211     parameters[numberParameters++] =
2212          CbcOrClpParam("fact!orization", "Which factorization to use",
2213                        "normal", CLP_PARAM_STR_FACTORIZATION);
2214     parameters[numberParameters-1].append("dense");
2215     parameters[numberParameters-1].append("simple");
2216     parameters[numberParameters-1].append("osl");
2217     parameters[numberParameters-1].setLonghelp
2218     (
2219#ifndef ABC_INHERIT
2220          "The default is to use the normal CoinFactorization, but \
2221other choices are a dense one, osl's or one designed for small problems."
2222#else
2223          "Normally the default is to use the normal CoinFactorization, but \
2224other choices are a dense one, osl's or one designed for small problems. \
2225However if at Aboca then the default is CoinAbcFactorization and other choices are \
2226a dense one, one designed for small problems or if enabled a long factorization."
2227#endif
2228     );
2229     parameters[numberParameters++] =
2230          CbcOrClpParam("fakeB!ound", "All bounds <= this value - DEBUG",
2231                        1.0, 1.0e15, CLP_PARAM_ACTION_FAKEBOUND, 0);
2232#ifdef COIN_HAS_CBC
2233     parameters[numberParameters++] =
2234          CbcOrClpParam("feas!ibilityPump", "Whether to try Feasibility Pump",
2235                        "off", CBC_PARAM_STR_FPUMP);
2236     parameters[numberParameters-1].append("on");
2237     parameters[numberParameters-1].append("both");
2238     parameters[numberParameters-1].append("before");
2239     parameters[numberParameters-1].setLonghelp
2240     (
2241          "This switches on feasibility pump heuristic at root. This is due to Fischetti, Lodi and Glover \
2242and uses a sequence of Lps to try and get an integer feasible solution. \
2243Some fine tuning is available by passFeasibilityPump and also pumpTune. \
2244See Rounding for meaning of on,both,before"
2245     );
2246     parameters[numberParameters++] =
2247          CbcOrClpParam("fix!OnDj", "Try heuristic based on fixing variables with \
2248reduced costs greater than this",
2249                        -1.0e20, 1.0e20, CBC_PARAM_DBL_DJFIX, 1);
2250     parameters[numberParameters-1].setLonghelp
2251     (
2252          "If this is set integer variables with reduced costs greater than this will be fixed \
2253before branch and bound - use with extreme caution!"
2254     );
2255     parameters[numberParameters++] =
2256          CbcOrClpParam("flow!CoverCuts", "Whether to use Flow Cover cuts",
2257                        "off", CBC_PARAM_STR_FLOWCUTS);
2258     parameters[numberParameters-1].append("on");
2259     parameters[numberParameters-1].append("root");
2260     parameters[numberParameters-1].append("ifmove");
2261     parameters[numberParameters-1].append("forceOn");
2262     parameters[numberParameters-1].append("onglobal");
2263     parameters[numberParameters-1].setFakeKeyWord(3);
2264     parameters[numberParameters-1].setLonghelp
2265     (
2266          "This switches on flow cover cuts (either at root or in entire tree) \
2267See branchAndCut for information on options. \
2268Can also enter testing values by plusnn (==ifmove)"
2269     );
2270     parameters[numberParameters++] =
2271          CbcOrClpParam("force!Solution", "Whether to use given solution as crash for BAB",
2272                        -1, 20000000, CLP_PARAM_INT_USESOLUTION);
2273     parameters[numberParameters-1].setIntValue(-1);
2274     parameters[numberParameters-1].setLonghelp
2275     (
2276          "-1 off.  If 1 then tries to branch to solution given by AMPL or priorities file. \
2277If 0 then just tries to set as best solution \
2278If >1 then also does that many nodes on fixed problem."
2279     );
2280     parameters[numberParameters++] =
2281          CbcOrClpParam("fraction!forBAB", "Fraction in feasibility pump",
2282                        1.0e-5, 1.1, CBC_PARAM_DBL_SMALLBAB, 1);
2283     parameters[numberParameters-1].setDoubleValue(0.5);
2284     parameters[numberParameters-1].setLonghelp
2285     (
2286          "After a pass in feasibility pump, variables which have not moved \
2287about are fixed and if the preprocessed model is small enough a few nodes \
2288of branch and bound are done on reduced problem.  Small problem has to be less than this fraction of original."
2289     );
2290#endif
2291     parameters[numberParameters++] =
2292          CbcOrClpParam("gamma!(Delta)", "Whether to regularize barrier",
2293                        "off", CLP_PARAM_STR_GAMMA, 7, 1);
2294     parameters[numberParameters-1].append("on");
2295     parameters[numberParameters-1].append("gamma");
2296     parameters[numberParameters-1].append("delta");
2297     parameters[numberParameters-1].append("onstrong");
2298     parameters[numberParameters-1].append("gammastrong");
2299     parameters[numberParameters-1].append("deltastrong");
2300#endif
2301#ifdef COIN_HAS_CBC
2302      parameters[numberParameters++] =
2303          CbcOrClpParam("GMI!Cuts", "Whether to use alternative Gomory cuts",
2304                        "off", CBC_PARAM_STR_GMICUTS);
2305     parameters[numberParameters-1].append("on");
2306     parameters[numberParameters-1].append("root");
2307     parameters[numberParameters-1].append("ifmove");
2308     parameters[numberParameters-1].append("forceOn");
2309     parameters[numberParameters-1].append("endonly");
2310     parameters[numberParameters-1].append("long");
2311     parameters[numberParameters-1].append("longroot");
2312     parameters[numberParameters-1].append("longifmove");
2313     parameters[numberParameters-1].append("forceLongOn");
2314     parameters[numberParameters-1].append("longendonly");
2315     parameters[numberParameters-1].setLonghelp
2316     (
2317          "This switches on an alternative Gomory cut generator (either at root or in entire tree) \
2318This version is by Giacomo Nannicini and may be more robust \
2319See branchAndCut for information on options."
2320     );
2321     parameters[numberParameters++] =
2322          CbcOrClpParam("gomory!Cuts", "Whether to use Gomory cuts",
2323                        "off", CBC_PARAM_STR_GOMORYCUTS);
2324     parameters[numberParameters-1].append("on");
2325     parameters[numberParameters-1].append("root");
2326     parameters[numberParameters-1].append("ifmove");
2327     parameters[numberParameters-1].append("forceOn");
2328     parameters[numberParameters-1].append("onglobal");
2329     parameters[numberParameters-1].append("forceandglobal");
2330     parameters[numberParameters-1].append("forceLongOn");
2331     parameters[numberParameters-1].append("long");
2332     parameters[numberParameters-1].setLonghelp
2333     (
2334          "The original cuts - beware of imitations!  Having gone out of favor, they are now more \
2335fashionable as LP solvers are more robust and they interact well with other cuts.  They will almost always \
2336give cuts (although in this executable they are limited as to number of variables in cut).  \
2337However the cuts may be dense so it is worth experimenting (Long allows any length). \
2338See branchAndCut for information on options."
2339     );
2340     parameters[numberParameters++] =
2341          CbcOrClpParam("greedy!Heuristic", "Whether to use a greedy heuristic",
2342                        "off", CBC_PARAM_STR_GREEDY);
2343     parameters[numberParameters-1].append("on");
2344     parameters[numberParameters-1].append("both");
2345     parameters[numberParameters-1].append("before");
2346     //parameters[numberParameters-1].append("root");
2347     parameters[numberParameters-1].setLonghelp
2348     (
2349          "Switches on a greedy heuristic which will try and obtain a solution.  It may just fix a \
2350percentage of variables and then try a small branch and cut run. \
2351See Rounding for meaning of on,both,before"
2352     );
2353#endif
2354     parameters[numberParameters++] =
2355          CbcOrClpParam("gsolu!tion", "Puts glpk solution to file",
2356                        CLP_PARAM_ACTION_GMPL_SOLUTION);
2357     parameters[numberParameters-1].setLonghelp
2358     (
2359          "Will write a glpk solution file to the given file name.  It will use the default\
2360 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2361 is initialized to 'stdout' (this defaults to ordinary solution if stdout). \
2362If problem created from gmpl model - will do any reports."
2363     );
2364#ifdef COIN_HAS_CBC
2365     parameters[numberParameters++] =
2366          CbcOrClpParam("heur!isticsOnOff", "Switches most heuristics on or off",
2367                        "off", CBC_PARAM_STR_HEURISTICSTRATEGY);
2368     parameters[numberParameters-1].append("on");
2369     parameters[numberParameters-1].setLonghelp
2370     (
2371          "This can be used to switch on or off all heuristics.  Then you can do \
2372individual ones off or on.  CbcTreeLocal is not included as it dramatically \
2373alters search."
2374     );
2375#endif
2376     parameters[numberParameters++] =
2377          CbcOrClpParam("help", "Print out version, non-standard options and some help",
2378                        CLP_PARAM_ACTION_HELP, 3);
2379     parameters[numberParameters-1].setLonghelp
2380     (
2381          "This prints out some help to get user started.  If you have printed this then \
2382you should be past that stage:-)"
2383     );
2384#ifdef COIN_HAS_CBC
2385     parameters[numberParameters++] =
2386          CbcOrClpParam("hOp!tions", "Heuristic options",
2387                        -9999999, 9999999, CBC_PARAM_INT_HOPTIONS, 1);
2388     parameters[numberParameters-1].setLonghelp
2389     (
2390          "1 says stop heuristic immediately allowable gap reached. \
2391Others are for feasibility pump - \
23922 says do exact number of passes given, \
23934 only applies if initial cutoff given and says relax after 50 passes, \
2394while 8 will adapt cutoff rhs after first solution if it looks as if code is stalling."
2395     );
2396     parameters[numberParameters-1].setIntValue(0);
2397     parameters[numberParameters++] =
2398          CbcOrClpParam("hot!StartMaxIts", "Maximum iterations on hot start",
2399                        0, COIN_INT_MAX, CBC_PARAM_INT_MAXHOTITS);
2400#endif
2401#ifdef COIN_HAS_CLP
2402     parameters[numberParameters++] =
2403          CbcOrClpParam("idiot!Crash", "Whether to try idiot crash",
2404                        -1, 99999999, CLP_PARAM_INT_IDIOT);
2405     parameters[numberParameters-1].setLonghelp
2406     (
2407          "This is a type of 'crash' which works well on some homogeneous problems.\
2408 It works best on problems with unit elements and rhs but will do something to any model.  It should only be\
2409 used before primal.  It can be set to -1 when the code decides for itself whether to use it,\
2410 0 to switch off or n > 0 to do n passes."
2411     );
2412#endif
2413     parameters[numberParameters++] =
2414          CbcOrClpParam("import", "Import model from mps file",
2415                        CLP_PARAM_ACTION_IMPORT, 3);
2416     parameters[numberParameters-1].setLonghelp
2417     (
2418          "This will read an MPS format file from the given file name.  It will use the default\
2419 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2420 is initialized to '', i.e. it must be set.  If you have libgz then it can read compressed\
2421 files 'xxxxxxxx.gz' or 'xxxxxxxx.bz2'.  \
2422If 'keepnames' is off, then names are dropped -> Rnnnnnnn and Cnnnnnnn."
2423     );
2424#ifdef COIN_HAS_CBC
2425     parameters[numberParameters++] =
2426          CbcOrClpParam("inc!rement", "A valid solution must be at least this \
2427much better than last integer solution",
2428                        -1.0e20, 1.0e20, CBC_PARAM_DBL_INCREMENT);
2429     parameters[numberParameters-1].setLonghelp
2430     (
2431          "Whenever a solution is found the bound on solutions is set to solution (in a minimization\
2432sense) plus this.  If it is not set then the code will try and work one out e.g. if \
2433all objective coefficients are multiples of 0.01 and only integer variables have entries in \
2434objective then this can be set to 0.01.  Be careful if you set this negative!"
2435     );
2436     parameters[numberParameters++] =
2437          CbcOrClpParam("inf!easibilityWeight", "Each integer infeasibility is expected \
2438to cost this much",
2439                        0.0, 1.0e20, CBC_PARAM_DBL_INFEASIBILITYWEIGHT, 1);
2440     parameters[numberParameters-1].setLonghelp
2441     (
2442          "A primitive way of deciding which node to explore next.  Satisfying each integer infeasibility is \
2443expected to cost this much."
2444     );
2445     parameters[numberParameters++] =
2446          CbcOrClpParam("initialS!olve", "Solve to continuous",
2447                        CLP_PARAM_ACTION_SOLVECONTINUOUS);
2448     parameters[numberParameters-1].setLonghelp
2449     (
2450          "This just solves the problem to continuous - without adding any cuts"
2451     );
2452     parameters[numberParameters++] =
2453          CbcOrClpParam("integerT!olerance", "For an optimal solution \
2454no integer variable may be this away from an integer value",
2455                        1.0e-20, 0.5, CBC_PARAM_DBL_INTEGERTOLERANCE);
2456     parameters[numberParameters-1].setLonghelp
2457     (
2458          "Beware of setting this smaller than the primal tolerance."
2459     );
2460#endif
2461#ifdef COIN_HAS_CLP
2462     parameters[numberParameters++] =
2463          CbcOrClpParam("keepN!ames", "Whether to keep names from import",
2464                        "on", CLP_PARAM_STR_KEEPNAMES);
2465     parameters[numberParameters-1].append("off");
2466     parameters[numberParameters-1].setLonghelp
2467     (
2468          "It saves space to get rid of names so if you need to you can set this to off.  \
2469This needs to be set before the import of model - so -keepnames off -import xxxxx.mps."
2470     );
2471     parameters[numberParameters++] =
2472          CbcOrClpParam("KKT", "Whether to use KKT factorization",
2473                        "off", CLP_PARAM_STR_KKT, 7, 1);
2474     parameters[numberParameters-1].append("on");
2475#endif
2476#ifdef COIN_HAS_CBC
2477     parameters[numberParameters++] =
2478          CbcOrClpParam("knapsack!Cuts", "Whether to use Knapsack cuts",
2479                        "off", CBC_PARAM_STR_KNAPSACKCUTS);
2480     parameters[numberParameters-1].append("on");
2481     parameters[numberParameters-1].append("root");
2482     parameters[numberParameters-1].append("ifmove");
2483     parameters[numberParameters-1].append("forceOn");
2484     parameters[numberParameters-1].append("onglobal");
2485     parameters[numberParameters-1].append("forceandglobal");
2486     parameters[numberParameters-1].setLonghelp
2487     (
2488          "This switches on knapsack cuts (either at root or in entire tree) \
2489See branchAndCut for information on options."
2490     );
2491     parameters[numberParameters++] =
2492          CbcOrClpParam("lagomory!Cuts", "Whether to use Lagrangean Gomory cuts",
2493                        "off", CBC_PARAM_STR_LAGOMORYCUTS);
2494     parameters[numberParameters-1].append("endonlyroot");
2495     parameters[numberParameters-1].append("endcleanroot");
2496     parameters[numberParameters-1].append("endbothroot");
2497     parameters[numberParameters-1].append("endonly");
2498     parameters[numberParameters-1].append("endclean");
2499     parameters[numberParameters-1].append("endboth");
2500     parameters[numberParameters-1].append("onlyaswell");
2501     parameters[numberParameters-1].append("cleanaswell");
2502     parameters[numberParameters-1].append("bothaswell");
2503     parameters[numberParameters-1].append("onlyinstead");
2504     parameters[numberParameters-1].append("cleaninstead");
2505     parameters[numberParameters-1].append("bothinstead");
2506     parameters[numberParameters-1].append("onlyaswellroot");
2507     parameters[numberParameters-1].append("cleanaswellroot");
2508     parameters[numberParameters-1].append("bothaswellroot");
2509     parameters[numberParameters-1].setLonghelp
2510     (
2511          "This is a gross simplification of 'A Relax-and-Cut Framework for Gomory's Mixed-Integer Cuts' \
2512by Matteo Fischetti & Domenico Salvagnin.  This simplification \
2513just uses original constraints while modifying objective using other cuts. \
2514So you don't use messy constraints generated by Gomory etc. \
2515A variant is to allow non messy cuts e.g. clique cuts. \
2516So 'only' does this while clean also allows integral valued cuts.  \
2517'End' is recommended which waits until other cuts have finished and then \
2518does a few passes. \
2519The length options for gomory cuts are used."
2520     );
2521     parameters[numberParameters++] =
2522          CbcOrClpParam("latwomir!Cuts", "Whether to use Lagrangean TwoMir cuts",
2523                        "off", CBC_PARAM_STR_LATWOMIRCUTS);
2524     parameters[numberParameters-1].append("endonlyroot");
2525     parameters[numberParameters-1].append("endcleanroot");
2526     parameters[numberParameters-1].append("endbothroot");
2527     parameters[numberParameters-1].append("endonly");
2528     parameters[numberParameters-1].append("endclean");
2529     parameters[numberParameters-1].append("endboth");
2530     parameters[numberParameters-1].append("onlyaswell");
2531     parameters[numberParameters-1].append("cleanaswell");
2532     parameters[numberParameters-1].append("bothaswell");
2533     parameters[numberParameters-1].append("onlyinstead");
2534     parameters[numberParameters-1].append("cleaninstead");
2535     parameters[numberParameters-1].append("bothinstead");
2536     parameters[numberParameters-1].setLonghelp
2537     (
2538          "This is a lagrangean relaxation for TwoMir cuts.  See \
2539lagomoryCuts for description of options."
2540     );
2541     parameters[numberParameters++] =
2542          CbcOrClpParam("lift!AndProjectCuts", "Whether to use Lift and Project cuts",
2543                        "off", CBC_PARAM_STR_LANDPCUTS);
2544     parameters[numberParameters-1].append("on");
2545     parameters[numberParameters-1].append("root");
2546     parameters[numberParameters-1].append("ifmove");
2547     parameters[numberParameters-1].append("forceOn");
2548     parameters[numberParameters-1].setLonghelp
2549     (
2550          "Lift and project cuts. \
2551May be slow \
2552See branchAndCut for information on options."
2553     );
2554     parameters[numberParameters++] =
2555          CbcOrClpParam("local!TreeSearch", "Whether to use local treesearch",
2556                        "off", CBC_PARAM_STR_LOCALTREE);
2557     parameters[numberParameters-1].append("on");
2558     parameters[numberParameters-1].setLonghelp
2559     (
2560          "This switches on a local search algorithm when a solution is found.  This is from \
2561Fischetti and Lodi and is not really a heuristic although it can be used as one. \
2562When used from Coin solve it has limited functionality.  It is not switched on when \
2563heuristics are switched on."
2564     );
2565#endif
2566#ifndef COIN_HAS_CBC
2567     parameters[numberParameters++] =
2568          CbcOrClpParam("log!Level", "Level of detail in Solver output",
2569                        -1, 999999, CLP_PARAM_INT_SOLVERLOGLEVEL);
2570#else
2571     parameters[numberParameters++] =
2572          CbcOrClpParam("log!Level", "Level of detail in Coin branch and Cut output",
2573                        -63, 63, CLP_PARAM_INT_LOGLEVEL);
2574     parameters[numberParameters-1].setIntValue(1);
2575#endif
2576     parameters[numberParameters-1].setLonghelp
2577     (
2578          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
2579 value for most uses, while 2 and 3 give more information."
2580     );
2581     parameters[numberParameters++] =
2582          CbcOrClpParam("max!imize", "Set optimization direction to maximize",
2583                        CLP_PARAM_ACTION_MAXIMIZE, 7);
2584     parameters[numberParameters-1].setLonghelp
2585     (
2586          "The default is minimize - use 'maximize' for maximization.\n\
2587You can also use the parameters 'direction maximize'."
2588     );
2589#ifdef COIN_HAS_CLP
2590     parameters[numberParameters++] =
2591          CbcOrClpParam("maxF!actor", "Maximum number of iterations between \
2592refactorizations",
2593                        1, 999999, CLP_PARAM_INT_MAXFACTOR);
2594     parameters[numberParameters-1].setLonghelp
2595     (
2596          "If this is at its initial value of 200 then in this executable clp will guess at a\
2597 value to use.  Otherwise the user can set a value.  The code may decide to re-factorize\
2598 earlier for accuracy."
2599     );
2600     parameters[numberParameters++] =
2601          CbcOrClpParam("maxIt!erations", "Maximum number of iterations before \
2602stopping",
2603                        0, 2147483647, CLP_PARAM_INT_MAXITERATION);
2604     parameters[numberParameters-1].setLonghelp
2605     (
2606          "This can be used for testing purposes.  The corresponding library call\n\
2607      \tsetMaximumIterations(value)\n can be useful.  If the code stops on\
2608 seconds or by an interrupt this will be treated as stopping on maximum iterations.  This is ignored in branchAndCut - use maxN!odes."
2609     );
2610#endif
2611#ifdef COIN_HAS_CBC
2612     parameters[numberParameters++] =
2613          CbcOrClpParam("maxN!odes", "Maximum number of nodes to do",
2614                        -1, 2147483647, CBC_PARAM_INT_MAXNODES);
2615     parameters[numberParameters-1].setLonghelp
2616     (
2617          "This is a repeatable way to limit search.  Normally using time is easier \
2618but then the results may not be repeatable."
2619     );
2620     parameters[numberParameters++] =
2621          CbcOrClpParam("maxSaved!Solutions", "Maximum number of solutions to save",
2622                        0, 2147483647, CBC_PARAM_INT_MAXSAVEDSOLS);
2623     parameters[numberParameters-1].setLonghelp
2624     (
2625          "Number of solutions to save."
2626     );
2627     parameters[numberParameters++] =
2628          CbcOrClpParam("maxSo!lutions", "Maximum number of solutions to get",
2629                        1, 2147483647, CBC_PARAM_INT_MAXSOLS);
2630     parameters[numberParameters-1].setLonghelp
2631     (
2632          "You may want to stop after (say) two solutions or an hour.  \
2633This is checked every node in tree, so it is possible to get more solutions from heuristics."
2634     );
2635#endif
2636     parameters[numberParameters++] =
2637          CbcOrClpParam("min!imize", "Set optimization direction to minimize",
2638                        CLP_PARAM_ACTION_MINIMIZE, 7);
2639     parameters[numberParameters-1].setLonghelp
2640     (
2641          "The default is minimize - use 'maximize' for maximization.\n\
2642This should only be necessary if you have previously set maximization \
2643You can also use the parameters 'direction minimize'."
2644     );
2645#ifdef COIN_HAS_CBC
2646     parameters[numberParameters++] =
2647          CbcOrClpParam("mipO!ptions", "Dubious options for mip",
2648                        0, COIN_INT_MAX, CBC_PARAM_INT_MIPOPTIONS, 0);
2649     parameters[numberParameters++] =
2650          CbcOrClpParam("more!MipOptions", "More dubious options for mip",
2651                        -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMIPOPTIONS, 0);
2652     parameters[numberParameters++] =
2653          CbcOrClpParam("more2!MipOptions", "More more dubious options for mip",
2654                        -1, COIN_INT_MAX, CBC_PARAM_INT_MOREMOREMIPOPTIONS, 0);
2655     parameters[numberParameters-1].setIntValue(0);
2656     parameters[numberParameters++] =
2657          CbcOrClpParam("mixed!IntegerRoundingCuts", "Whether to use Mixed Integer Rounding cuts",
2658                        "off", CBC_PARAM_STR_MIXEDCUTS);
2659     parameters[numberParameters-1].append("on");
2660     parameters[numberParameters-1].append("root");
2661     parameters[numberParameters-1].append("ifmove");
2662     parameters[numberParameters-1].append("forceOn");
2663     parameters[numberParameters-1].append("onglobal");
2664     parameters[numberParameters-1].setLonghelp
2665     (
2666          "This switches on mixed integer rounding cuts (either at root or in entire tree) \
2667See branchAndCut for information on options."
2668     );
2669#endif
2670     parameters[numberParameters++] =
2671          CbcOrClpParam("mess!ages", "Controls if Clpnnnn is printed",
2672                        "off", CLP_PARAM_STR_MESSAGES);
2673     parameters[numberParameters-1].append("on");
2674     parameters[numberParameters-1].setLonghelp
2675     ("The default behavior is to put out messages such as:\n\
2676   Clp0005 2261  Objective 109.024 Primal infeas 944413 (758)\n\
2677but this program turns this off to make it look more friendly.  It can be useful\
2678 to turn them back on if you want to be able to 'grep' for particular messages or if\
2679 you intend to override the behavior of a particular message.  This only affects Clp not Cbc."
2680     );
2681     parameters[numberParameters++] =
2682          CbcOrClpParam("miplib", "Do some of miplib test set",
2683                        CBC_PARAM_ACTION_MIPLIB, 3, 1);
2684#ifdef COIN_HAS_CBC
2685      parameters[numberParameters++] =
2686          CbcOrClpParam("mips!tart", "reads an initial feasible solution from file",
2687                        CBC_PARAM_ACTION_MIPSTART);
2688     parameters[numberParameters-1].setLonghelp
2689     ("\
2690The MIPStart allows one to enter an initial integer feasible solution \
2691to CBC. Values of the main decision variables which are active (have \
2692non-zero values) in this solution are specified in a text  file. The \
2693text file format used is the same of the solutions saved by CBC, but \
2694not all fields are required to be filled. First line may contain the \
2695solution status and will be ignored, remaining lines contain column \
2696indexes, names and values as in this example:\n\
2697\n\
2698Stopped on iterations - objective value 57597.00000000\n\
2699      0  x(1,1,2,2)               1 \n\
2700      1  x(3,1,3,2)               1 \n\
2701      5  v(5,1)                   2 \n\
2702      33 x(8,1,5,2)               1 \n\
2703      ...\n\
2704\n\
2705Column indexes are also ignored since pre-processing can change them. \
2706There is no need to include values for continuous or integer auxiliary \
2707variables, since they can be computed based on main decision variables. \
2708Starting CBC with an integer feasible solution can dramatically improve \
2709its performance: several MIP heuristics (e.g. RINS) rely on having at \
2710least one feasible solution available and can start immediately if the \
2711user provides one. Feasibility Pump (FP) is a heuristic which tries to \
2712overcome the problem of taking too long to find feasible solution (or \
2713not finding at all), but it not always succeeds. If you provide one \
2714starting solution you will probably save some time by disabling FP. \
2715\n\n\
2716Knowledge specific to your problem can be considered to write an \
2717external module to quickly produce an initial feasible solution - some \
2718alternatives are the implementation of simple greedy heuristics or the \
2719solution (by CBC for example) of a simpler model created just to find \
2720a feasible solution. \
2721\n\n\
2722Question and suggestions regarding MIPStart can be directed to\n\
2723haroldo.santos@gmail.com.\
2724");
2725#endif
2726     parameters[numberParameters++] =
2727          CbcOrClpParam("moreS!pecialOptions", "Yet more dubious options for Simplex - see ClpSimplex.hpp",
2728                        0, COIN_INT_MAX, CLP_PARAM_INT_MORESPECIALOPTIONS, 0);
2729#ifdef COIN_HAS_CBC
2730     parameters[numberParameters++] =
2731          CbcOrClpParam("moreT!une", "Yet more dubious ideas for feasibility pump",
2732                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE2, 0);
2733     parameters[numberParameters-1].setLonghelp
2734     (
2735          "Yet more ideas for Feasibility Pump \n\
2736\t/100000 == 1 use box constraints and original obj in cleanup\n\
2737\t/1000 == 1 Pump will run twice if no solution found\n\
2738\t/1000 == 2 Pump will only run after root cuts if no solution found\n\
2739\t/1000 >10 as above but even if solution found\n\
2740\t/100 == 1,3.. exact 1.0 for objective values\n\
2741\t/100 == 2,3.. allow more iterations per pass\n\
2742\t n fix if value of variable same for last n iterations."
2743     );
2744     parameters[numberParameters-1].setIntValue(0);
2745     parameters[numberParameters++] =
2746          CbcOrClpParam("multiple!RootPasses", "Do multiple root passes to collect cuts and solutions",
2747                        0, 100000000, CBC_PARAM_INT_MULTIPLEROOTS, 0);
2748     parameters[numberParameters-1].setIntValue(0);
2749     parameters[numberParameters-1].setLonghelp
2750     (
2751          "Do (in parallel if threads enabled) the root phase this number of times \
2752 and collect all solutions and cuts generated.  The actual format is aabbcc \
2753where aa is number of extra passes, if bb is non zero \
2754then it is number of threads to use (otherwise uses threads setting) and \
2755cc is number of times to do root phase.  Yet another one from the Italian idea factory \
2756(This time - Andrea Lodi , Matteo Fischetti , Michele Monaci , Domenico Salvagnin , \
2757and Andrea Tramontani). \
2758The solvers do not interact with each other.  However if extra passes are specified \
2759then cuts are collected and used in later passes - so there is interaction there." 
2760     );
2761     parameters[numberParameters++] =
2762          CbcOrClpParam("naive!Heuristics", "Whether to try some stupid heuristic",
2763                        "off", CBC_PARAM_STR_NAIVE, 7, 1);
2764     parameters[numberParameters-1].append("on");
2765     parameters[numberParameters-1].append("both");
2766     parameters[numberParameters-1].append("before");
2767     parameters[numberParameters-1].setLonghelp
2768     (
2769          "Really silly stuff e.g. fix all integers with costs to zero!. \
2770Doh option does heuristic before preprocessing"     );
2771#endif
2772#ifdef COIN_HAS_CLP
2773     parameters[numberParameters++] =
2774          CbcOrClpParam("netlib", "Solve entire netlib test set",
2775                        CLP_PARAM_ACTION_NETLIB_EITHER, 3, 1);
2776     parameters[numberParameters-1].setLonghelp
2777     (
2778          "This exercises the unit test for clp and then solves the netlib test set using dual or primal.\
2779The user can set options before e.g. clp -presolve off -netlib"
2780     );
2781     parameters[numberParameters++] =
2782          CbcOrClpParam("netlibB!arrier", "Solve entire netlib test set with barrier",
2783                        CLP_PARAM_ACTION_NETLIB_BARRIER, 3, 1);
2784     parameters[numberParameters-1].setLonghelp
2785     (
2786          "This exercises the unit test for clp and then solves the netlib test set using barrier.\
2787The user can set options before e.g. clp -kkt on -netlib"
2788     );
2789     parameters[numberParameters++] =
2790          CbcOrClpParam("netlibD!ual", "Solve entire netlib test set (dual)",
2791                        CLP_PARAM_ACTION_NETLIB_DUAL, 3, 1);
2792     parameters[numberParameters-1].setLonghelp
2793     (
2794          "This exercises the unit test for clp and then solves the netlib test set using dual.\
2795The user can set options before e.g. clp -presolve off -netlib"
2796     );
2797     parameters[numberParameters++] =
2798          CbcOrClpParam("netlibP!rimal", "Solve entire netlib test set (primal)",
2799                        CLP_PARAM_ACTION_NETLIB_PRIMAL, 3, 1);
2800     parameters[numberParameters-1].setLonghelp
2801     (
2802          "This exercises the unit test for clp and then solves the netlib test set using primal.\
2803The user can set options before e.g. clp -presolve off -netlibp"
2804     );
2805     parameters[numberParameters++] =
2806          CbcOrClpParam("netlibT!une", "Solve entire netlib test set with 'best' algorithm",
2807                        CLP_PARAM_ACTION_NETLIB_TUNE, 3, 1);
2808     parameters[numberParameters-1].setLonghelp
2809     (
2810          "This exercises the unit test for clp and then solves the netlib test set using whatever \
2811works best.  I know this is cheating but it also stresses the code better by doing a \
2812mixture of stuff.  The best algorithm was chosen on a Linux ThinkPad using native cholesky \
2813with University of Florida ordering."
2814     );
2815     parameters[numberParameters++] =
2816          CbcOrClpParam("network", "Tries to make network matrix",
2817                        CLP_PARAM_ACTION_NETWORK, 7, 0);
2818     parameters[numberParameters-1].setLonghelp
2819     (
2820          "Clp will go faster if the matrix can be converted to a network.  The matrix\
2821 operations may be a bit faster with more efficient storage, but the main advantage\
2822 comes from using a network factorization.  It will probably not be as fast as a \
2823specialized network code."
2824     );
2825#ifdef COIN_HAS_CBC
2826     parameters[numberParameters++] =
2827          CbcOrClpParam("nextB!estSolution", "Prints next best saved solution to file",
2828                        CLP_PARAM_ACTION_NEXTBESTSOLUTION);
2829     parameters[numberParameters-1].setLonghelp
2830     (
2831          "To write best solution, just use solution.  This prints next best (if exists) \
2832 and then deletes it. \
2833 This will write a primitive solution file to the given file name.  It will use the default\
2834 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2835 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
2836     );
2837     parameters[numberParameters++] =
2838          CbcOrClpParam("node!Strategy", "What strategy to use to select nodes",
2839                        "hybrid", CBC_PARAM_STR_NODESTRATEGY);
2840     parameters[numberParameters-1].append("fewest");
2841     parameters[numberParameters-1].append("depth");
2842     parameters[numberParameters-1].append("upfewest");
2843     parameters[numberParameters-1].append("downfewest");
2844     parameters[numberParameters-1].append("updepth");
2845     parameters[numberParameters-1].append("downdepth");
2846     parameters[numberParameters-1].setLonghelp
2847     (
2848          "Normally before a solution the code will choose node with fewest infeasibilities. \
2849You can choose depth as the criterion.  You can also say if up or down branch must \
2850be done first (the up down choice will carry on after solution). \
2851Default has now been changed to hybrid which is breadth first on small depth nodes then fewest."
2852     );
2853     parameters[numberParameters++] =
2854          CbcOrClpParam("numberA!nalyze", "Number of analysis iterations",
2855                        -COIN_INT_MAX, COIN_INT_MAX, CBC_PARAM_INT_NUMBERANALYZE, 0);
2856     parameters[numberParameters-1].setLonghelp
2857     (
2858          "This says how many iterations to spend at root node analyzing problem. \
2859This is a first try and will hopefully become more sophisticated."
2860     );
2861#endif
2862     parameters[numberParameters++] =
2863          CbcOrClpParam("objective!Scale", "Scale factor to apply to objective",
2864                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE, 1);
2865     parameters[numberParameters-1].setLonghelp
2866     (
2867          "If the objective function has some very large values, you may wish to scale them\
2868 internally by this amount.  It can also be set by autoscale.  It is applied after scaling.  You are unlikely to need this."
2869     );
2870     parameters[numberParameters-1].setDoubleValue(1.0);
2871#endif
2872#ifdef COIN_HAS_CBC
2873#ifdef COIN_HAS_NTY
2874     parameters[numberParameters++] =
2875          CbcOrClpParam("Orbit!alBranching", "Whether to try orbital branching",
2876                        "off", CBC_PARAM_STR_ORBITAL);
2877     parameters[numberParameters-1].append("on");
2878     parameters[numberParameters-1].append("strong");
2879     parameters[numberParameters-1].append("force");
2880     parameters[numberParameters-1].setLonghelp
2881     (
2882          "This switches on Orbital branching. \
2883On just adds orbital, strong tries extra fixing in strong branching");
2884#endif
2885     parameters[numberParameters++] =
2886          CbcOrClpParam("outDup!licates", "takes duplicate rows etc out of integer model",
2887                        CLP_PARAM_ACTION_OUTDUPROWS, 7, 0);
2888#endif
2889     parameters[numberParameters++] =
2890          CbcOrClpParam("output!Format", "Which output format to use",
2891                        1, 6, CLP_PARAM_INT_OUTPUTFORMAT);
2892     parameters[numberParameters-1].setLonghelp
2893     (
2894          "Normally export will be done using normal representation for numbers and two values\
2895 per line.  You may want to do just one per line (for grep or suchlike) and you may wish\
2896 to save with absolute accuracy using a coded version of the IEEE value. A value of 2 is normal.\
2897 otherwise odd values gives one value per line, even two.  Values 1,2 give normal format, 3,4\
2898 gives greater precision, while 5,6 give IEEE values.  When used for exporting a basis 1 does not save \
2899values, 2 saves values, 3 with greater accuracy and 4 in IEEE."
2900     );
2901#ifdef COIN_HAS_CLP
2902     parameters[numberParameters++] =
2903          CbcOrClpParam("para!metrics", "Import data from file and do parametrics",
2904                        CLP_PARAM_ACTION_PARAMETRICS, 3);
2905     parameters[numberParameters-1].setLonghelp
2906     (
2907          "This will read a file with parametric data from the given file name \
2908and then do parametrics.  It will use the default\
2909 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
2910 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
2911File is in modified csv format - a line ROWS will be followed by rows data \
2912while a line COLUMNS will be followed by column data.  The last line \
2913should be ENDATA. The ROWS line must exist and is in the format \
2914ROWS, inital theta, final theta, interval theta, n where n is 0 to get \
2915CLPI0062 message at interval or at each change of theta \
2916and 1 to get CLPI0063 message at each iteration.  If interval theta is 0.0 \
2917or >= final theta then no interval reporting.  n may be missed out when it is \
2918taken as 0.  If there is Row data then \
2919there is a headings line with allowed headings - name, number, \
2920lower(rhs change), upper(rhs change), rhs(change).  Either the lower and upper \
2921fields should be given or the rhs field. \
2922The optional COLUMNS line is followed by a headings line with allowed \
2923headings - name, number, objective(change), lower(change), upper(change). \
2924 Exactly one of name and number must be given for either section and \
2925missing ones have value 0.0."
2926     );
2927#endif
2928#ifdef COIN_HAS_CBC
2929     parameters[numberParameters++] =
2930          CbcOrClpParam("passC!uts", "Number of cut passes at root node",
2931                        -9999999, 9999999, CBC_PARAM_INT_CUTPASS);
2932     parameters[numberParameters-1].setLonghelp
2933     (
2934          "The default is 100 passes if less than 500 columns, 100 passes (but \
2935stop if drop small if less than 5000 columns, 20 otherwise"
2936     );
2937     parameters[numberParameters++] =
2938          CbcOrClpParam("passF!easibilityPump", "How many passes in feasibility pump",
2939                        0, 10000, CBC_PARAM_INT_FPUMPITS);
2940     parameters[numberParameters-1].setLonghelp
2941     (
2942          "This fine tunes Feasibility Pump by doing more or fewer passes."
2943     );
2944     parameters[numberParameters-1].setIntValue(20);
2945#endif
2946#ifdef COIN_HAS_CLP
2947     parameters[numberParameters++] =
2948          CbcOrClpParam("passP!resolve", "How many passes in presolve",
2949                        -200, 100, CLP_PARAM_INT_PRESOLVEPASS, 1);
2950     parameters[numberParameters-1].setLonghelp
2951     (
2952          "Normally Presolve does 5 passes but you may want to do less to make it\
2953 more lightweight or do more if improvements are still being made.  As Presolve will return\
2954 if nothing is being taken out, you should not normally need to use this fine tuning."
2955     );
2956#endif
2957#ifdef COIN_HAS_CBC
2958     parameters[numberParameters++] =
2959          CbcOrClpParam("passT!reeCuts", "Number of cut passes in tree",
2960                        -9999999, 9999999, CBC_PARAM_INT_CUTPASSINTREE);
2961     parameters[numberParameters-1].setLonghelp
2962     (
2963          "The default is one pass"
2964     );
2965#endif
2966#ifdef COIN_HAS_CLP
2967     parameters[numberParameters++] =
2968          CbcOrClpParam("pertV!alue", "Method of perturbation",
2969                        -5000, 102, CLP_PARAM_INT_PERTVALUE, 1);
2970     parameters[numberParameters++] =
2971          CbcOrClpParam("perturb!ation", "Whether to perturb problem",
2972                        "on", CLP_PARAM_STR_PERTURBATION);
2973     parameters[numberParameters-1].append("off");
2974     parameters[numberParameters-1].setLonghelp
2975     (
2976          "Perturbation helps to stop cycling, but Clp uses other measures for this.\
2977  However large problems and especially ones with unit elements and unit rhs or costs\
2978 benefit from perturbation.  Normally Clp tries to be intelligent, but you can switch this off.\
2979  The Clp library has this off by default.  This program has it on by default."
2980     );
2981     parameters[numberParameters++] =
2982          CbcOrClpParam("PFI", "Whether to use Product Form of Inverse in simplex",
2983                        "off", CLP_PARAM_STR_PFI, 7, 0);
2984     parameters[numberParameters-1].append("on");
2985     parameters[numberParameters-1].setLonghelp
2986     (
2987          "By default clp uses Forrest-Tomlin L-U update.  If you are masochistic you can switch it off."
2988     );
2989#endif
2990#ifdef COIN_HAS_CBC
2991     parameters[numberParameters++] =
2992          CbcOrClpParam("pivotAndC!omplement", "Whether to try Pivot and Complement heuristic",
2993                        "off", CBC_PARAM_STR_PIVOTANDCOMPLEMENT);
2994     parameters[numberParameters-1].append("on");
2995     parameters[numberParameters-1].append("both");
2996     parameters[numberParameters-1].append("before");
2997     parameters[numberParameters-1].setLonghelp
2998     (
2999          "stuff needed. \
3000Doh option does heuristic before preprocessing"     );
3001     parameters[numberParameters++] =
3002          CbcOrClpParam("pivotAndF!ix", "Whether to try Pivot and Fix heuristic",
3003                        "off", CBC_PARAM_STR_PIVOTANDFIX);
3004     parameters[numberParameters-1].append("on");
3005     parameters[numberParameters-1].append("both");
3006     parameters[numberParameters-1].append("before");
3007     parameters[numberParameters-1].setLonghelp
3008     (
3009          "stuff needed. \
3010Doh option does heuristic before preprocessing"     );
3011#endif
3012#ifdef COIN_HAS_CLP
3013     parameters[numberParameters++] =
3014          CbcOrClpParam("plus!Minus", "Tries to make +- 1 matrix",
3015                        CLP_PARAM_ACTION_PLUSMINUS, 7, 0);
3016     parameters[numberParameters-1].setLonghelp
3017     (
3018          "Clp will go slightly faster if the matrix can be converted so that the elements are\
3019 not stored and are known to be unit.  The main advantage is memory use.  Clp may automatically\
3020 see if it can convert the problem so you should not need to use this."
3021     );
3022     parameters[numberParameters++] =
3023          CbcOrClpParam("pO!ptions", "Dubious print options",
3024                        0, COIN_INT_MAX, CLP_PARAM_INT_PRINTOPTIONS, 1);
3025     parameters[numberParameters-1].setIntValue(0);
3026     parameters[numberParameters-1].setLonghelp
3027     (
3028          "If this is > 0 then presolve will give more information and branch and cut will give statistics"
3029     );
3030     parameters[numberParameters++] =
3031          CbcOrClpParam("preO!pt", "Presolve options",
3032                        0, COIN_INT_MAX, CLP_PARAM_INT_PRESOLVEOPTIONS, 0);
3033#endif
3034     parameters[numberParameters++] =
3035          CbcOrClpParam("presolve", "Whether to presolve problem",
3036                        "on", CLP_PARAM_STR_PRESOLVE);
3037     parameters[numberParameters-1].append("off");
3038     parameters[numberParameters-1].append("more");
3039     parameters[numberParameters-1].append("file");
3040     parameters[numberParameters-1].setLonghelp
3041     (
3042          "Presolve analyzes the model to find such things as redundant equations, equations\
3043 which fix some variables, equations which can be transformed into bounds etc etc.  For the\
3044 initial solve of any problem this is worth doing unless you know that it will have no effect.  \
3045on will normally do 5 passes while using 'more' will do 10.  If the problem is very large you may need \
3046to write the original to file using 'file'."
3047     );
3048#ifdef COIN_HAS_CBC
3049     parameters[numberParameters++] =
3050          CbcOrClpParam("preprocess", "Whether to use integer preprocessing",
3051                        "off", CBC_PARAM_STR_PREPROCESS);
3052     parameters[numberParameters-1].append("on");
3053     parameters[numberParameters-1].append("save");
3054     parameters[numberParameters-1].append("equal");
3055     parameters[numberParameters-1].append("sos");
3056     parameters[numberParameters-1].append("trysos");
3057     parameters[numberParameters-1].append("equalall");
3058     parameters[numberParameters-1].append("strategy");
3059     parameters[numberParameters-1].append("aggregate");
3060     parameters[numberParameters-1].append("forcesos");
3061     parameters[numberParameters-1].setLonghelp
3062     (
3063          "This tries to reduce size of model in a similar way to presolve and \
3064it also tries to strengthen the model - this can be very useful and is worth trying. \
3065 Save option saves on file presolved.mps.  equal will turn <= cliques into \
3066==.  sos will create sos sets if all 0-1 in sets (well one extra is allowed) \
3067and no overlaps.  trysos is same but allows any number extra.  equalall will turn all \
3068valid inequalities into equalities with integer slacks.  strategy is as \
3069on but uses CbcStrategy."
3070     );
3071#endif
3072#ifdef COIN_HAS_CLP
3073     parameters[numberParameters++] =
3074          CbcOrClpParam("preT!olerance", "Tolerance to use in presolve",
3075                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRESOLVETOLERANCE);
3076     parameters[numberParameters-1].setLonghelp
3077     (
3078          "The default is 1.0e-8 - you may wish to try 1.0e-7 if presolve says the problem is \
3079infeasible and you have awkward numbers and you are sure the problem is really feasible."
3080     );
3081     parameters[numberParameters++] =
3082          CbcOrClpParam("primalP!ivot", "Primal pivot choice algorithm",
3083                        "auto!matic", CLP_PARAM_STR_PRIMALPIVOT, 7, 1);
3084     parameters[numberParameters-1].append("exa!ct");
3085     parameters[numberParameters-1].append("dant!zig");
3086     parameters[numberParameters-1].append("part!ial");
3087     parameters[numberParameters-1].append("steep!est");
3088     parameters[numberParameters-1].append("change");
3089     parameters[numberParameters-1].append("sprint");
3090     parameters[numberParameters-1].setLonghelp
3091     (
3092          "Clp can use any pivot selection algorithm which the user codes as long as it\
3093 implements the features in the abstract pivot base class.  The Dantzig method is implemented\
3094 to show a simple method but its use is deprecated.  Exact devex is the method of choice and there\
3095 are two variants which keep all weights updated but only scan a subset each iteration.\
3096 Partial switches this on while change initially does dantzig until the factorization\
3097 becomes denser.  This is still a work in progress."
3098     );
3099     parameters[numberParameters++] =
3100          CbcOrClpParam("primalS!implex", "Do primal simplex algorithm",
3101                        CLP_PARAM_ACTION_PRIMALSIMPLEX);
3102     parameters[numberParameters-1].setLonghelp
3103     (
3104          "This command solves the continuous relaxation of the current model using the primal algorithm.\
3105  The default is to use exact devex.\
3106 The time and iterations may be affected by settings such as presolve, scaling, crash\
3107 and also by column selection  method, infeasibility weight and dual and primal tolerances."
3108     );
3109#endif
3110     parameters[numberParameters++] =
3111          CbcOrClpParam("primalT!olerance", "For an optimal solution \
3112no primal infeasibility may exceed this value",
3113                        1.0e-20, 1.0e12, CLP_PARAM_DBL_PRIMALTOLERANCE);
3114     parameters[numberParameters-1].setLonghelp
3115     (
3116          "Normally the default tolerance is fine, but you may want to increase it a\
3117 bit if a primal run seems to be having a hard time"
3118     );
3119#ifdef COIN_HAS_CLP
3120     parameters[numberParameters++] =
3121          CbcOrClpParam("primalW!eight", "Initially algorithm acts as if it \
3122costs this much to be infeasible",
3123                        1.0e-20, 1.0e20, CLP_PARAM_DBL_PRIMALWEIGHT);
3124     parameters[numberParameters-1].setLonghelp
3125     (
3126          "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
3127 algorithm where you first get feasible then optimal.  So Clp is minimizing this weight times\
3128 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
3129  Too high a value may mean more iterations, while too low a bound means\
3130 the code may go all the way and then have to increase the weight in order to get feasible.\
3131  OSL had a heuristic to\
3132 adjust bounds, maybe we need that here."
3133     );
3134#endif
3135     parameters[numberParameters++] =
3136          CbcOrClpParam("printi!ngOptions", "Print options",
3137                        "normal", CLP_PARAM_STR_INTPRINT, 3);
3138     parameters[numberParameters-1].append("integer");
3139     parameters[numberParameters-1].append("special");
3140     parameters[numberParameters-1].append("rows");
3141     parameters[numberParameters-1].append("all");
3142     parameters[numberParameters-1].append("csv");
3143     parameters[numberParameters-1].append("bound!ranging");
3144     parameters[numberParameters-1].append("rhs!ranging");
3145     parameters[numberParameters-1].append("objective!ranging");
3146     parameters[numberParameters-1].append("stats");
3147     parameters[numberParameters-1].append("boundsint");
3148     parameters[numberParameters-1].append("boundsall");
3149     parameters[numberParameters-1].setLonghelp
3150     (
3151          "This changes the amount and format of printing a solution:\nnormal - nonzero column variables \n\
3152integer - nonzero integer column variables\n\
3153special - in format suitable for OsiRowCutDebugger\n\
3154rows - nonzero column variables and row activities\n\
3155all - all column variables and row activities.\n\
3156\nFor non-integer problems 'integer' and 'special' act like 'normal'.  \
3157Also see printMask for controlling output."
3158     );
3159     parameters[numberParameters++] =
3160          CbcOrClpParam("printM!ask", "Control printing of solution on a  mask",
3161                        CLP_PARAM_ACTION_PRINTMASK, 3);
3162     parameters[numberParameters-1].setLonghelp
3163     (
3164          "If set then only those names which match mask are printed in a solution. \
3165'?' matches any character and '*' matches any set of characters. \
3166 The default is '' i.e. unset so all variables are printed. \
3167This is only active if model has names."
3168     );
3169#ifdef COIN_HAS_CBC
3170     parameters[numberParameters++] =
3171          CbcOrClpParam("prio!rityIn", "Import priorities etc from file",
3172                        CBC_PARAM_ACTION_PRIORITYIN, 3);
3173     parameters[numberParameters-1].setLonghelp
3174     (
3175          "This will read a file with priorities from the given file name.  It will use the default\
3176 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3177 is initialized to '', i.e. it must be set.  This can not read from compressed files. \
3178File is in csv format with allowed headings - name, number, priority, direction, up, down, solution.  Exactly one of\
3179 name and number must be given."
3180     );
3181     parameters[numberParameters++] =
3182          CbcOrClpParam("probing!Cuts", "Whether to use Probing cuts",
3183                        "off", CBC_PARAM_STR_PROBINGCUTS);
3184     parameters[numberParameters-1].append("on");
3185     parameters[numberParameters-1].append("root");
3186     parameters[numberParameters-1].append("ifmove");
3187     parameters[numberParameters-1].append("forceOn");
3188     parameters[numberParameters-1].append("onglobal");
3189     parameters[numberParameters-1].append("forceonglobal");
3190     parameters[numberParameters-1].append("forceOnBut");
3191     parameters[numberParameters-1].append("forceOnStrong");
3192     parameters[numberParameters-1].append("forceOnButStrong");
3193     parameters[numberParameters-1].append("strongRoot");
3194     parameters[numberParameters-1].setLonghelp
3195     (
3196          "This switches on probing cuts (either at root or in entire tree) \
3197See branchAndCut for information on options. \
3198but strong options do more probing"
3199     );
3200     parameters[numberParameters++] =
3201          CbcOrClpParam("proximity!Search", "Whether to do proximity search heuristic",
3202                        "off", CBC_PARAM_STR_PROXIMITY);
3203     parameters[numberParameters-1].append("on");
3204     parameters[numberParameters-1].append("both");
3205     parameters[numberParameters-1].append("before");
3206     parameters[numberParameters-1].append("10");
3207     parameters[numberParameters-1].append("100");
3208     parameters[numberParameters-1].append("300");
3209     // but allow numbers after this (returning 1)
3210     parameters[numberParameters-1].setFakeKeyWord(1);
3211     parameters[numberParameters-1].setLonghelp
3212     (
3213          "This switches on a heuristic which looks for a solution close \
3214to incumbent solution (Fischetti and Monaci). \
3215See Rounding for meaning of on,both,before. \
3216Can also set different maxNode settings by plusnnnn (and are 'on'(on==30))."
3217     );
3218     parameters[numberParameters++] =
3219          CbcOrClpParam("pumpC!utoff", "Fake cutoff for use in feasibility pump",
3220                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKECUTOFF);
3221     parameters[numberParameters-1].setDoubleValue(0.0);
3222     parameters[numberParameters-1].setLonghelp
3223     (
3224          "0.0 off - otherwise add a constraint forcing objective below this value\
3225 in feasibility pump"
3226     );
3227     parameters[numberParameters++] =
3228          CbcOrClpParam("pumpI!ncrement", "Fake increment for use in feasibility pump",
3229                        -COIN_DBL_MAX, COIN_DBL_MAX, CBC_PARAM_DBL_FAKEINCREMENT, 1);
3230     parameters[numberParameters-1].setDoubleValue(0.0);
3231     parameters[numberParameters-1].setLonghelp
3232     (
3233          "0.0 off - otherwise use as absolute increment to cutoff \
3234when solution found in feasibility pump"
3235     );
3236     parameters[numberParameters++] =
3237          CbcOrClpParam("pumpT!une", "Dubious ideas for feasibility pump",
3238                        0, 100000000, CBC_PARAM_INT_FPUMPTUNE);
3239     parameters[numberParameters-1].setLonghelp
3240     (
3241          "This fine tunes Feasibility Pump \n\
3242\t>=10000000 use as objective weight switch\n\
3243\t>=1000000 use as accumulate switch\n\
3244\t>=1000 use index+1 as number of large loops\n\
3245\t==100 use objvalue +0.05*fabs(objvalue) as cutoff OR fakeCutoff if set\n\
3246\t%100 == 10,20 affects how each solve is done\n\
3247\t1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds. \
3248If accumulate is on then after a major pass, variables which have not moved \
3249are fixed and a small branch and bound is tried."
3250     );
3251     parameters[numberParameters-1].setIntValue(0);
3252#endif
3253     parameters[numberParameters++] =
3254          CbcOrClpParam("quit", "Stops clp execution",
3255                        CLP_PARAM_ACTION_EXIT);
3256     parameters[numberParameters-1].setLonghelp
3257     (
3258          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3259     );
3260#ifdef COIN_HAS_CBC
3261     parameters[numberParameters++] =
3262          CbcOrClpParam("randomC!bcSeed", "Random seed for Cbc",
3263                        -1, COIN_INT_MAX, CBC_PARAM_INT_RANDOMSEED);
3264     parameters[numberParameters-1].setLonghelp
3265     (
3266          "This sets a random seed for Cbc \
3267- 0 says use time of day, -1 is as now."
3268     );
3269     parameters[numberParameters-1].setIntValue(-1);
3270     parameters[numberParameters++] =
3271          CbcOrClpParam("randomi!zedRounding", "Whether to try randomized rounding heuristic",
3272                        "off", CBC_PARAM_STR_RANDROUND);
3273     parameters[numberParameters-1].append("on");
3274     parameters[numberParameters-1].append("both");
3275     parameters[numberParameters-1].append("before");
3276     parameters[numberParameters-1].setLonghelp
3277     (
3278          "stuff needed. \
3279Doh option does heuristic before preprocessing"     );
3280#endif
3281#ifdef COIN_HAS_CLP
3282     parameters[numberParameters++] =
3283          CbcOrClpParam("randomS!eed", "Random seed for Clp",
3284                        0, COIN_INT_MAX, CLP_PARAM_INT_RANDOMSEED);
3285     parameters[numberParameters-1].setLonghelp
3286     (
3287          "This sets a random seed for Clp \
3288- 0 says use time of day."
3289     );
3290     parameters[numberParameters-1].setIntValue(1234567);
3291#endif
3292#ifdef COIN_HAS_CBC
3293     parameters[numberParameters++] =
3294          CbcOrClpParam("ratio!Gap", "Stop when gap between best possible and \
3295best less than this fraction of larger of two",
3296                        0.0, 1.0e20, CBC_PARAM_DBL_GAPRATIO);
3297     parameters[numberParameters-1].setDoubleValue(0.0);
3298     parameters[numberParameters-1].setLonghelp
3299     (
3300          "If the gap between best solution and best possible solution is less than this fraction \
3301of the objective value at the root node then the search will terminate.  See 'allowableGap' for a \
3302way of using absolute value rather than fraction."
3303     );
3304#endif
3305     parameters[numberParameters++] =
3306          CbcOrClpParam("restoreS!olution", "reads solution from file",
3307                        CLP_PARAM_ACTION_RESTORESOL);
3308     parameters[numberParameters-1].setLonghelp
3309     (
3310          "This will read a binary solution file from the given file name.  It will use the default\
3311 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3312 is initialized to 'solution.file'.  This reads in a file from saveSolution"
3313     );
3314#ifdef COIN_HAS_CBC
3315     parameters[numberParameters++] =
3316          CbcOrClpParam("readSt!ored", "Import stored cuts from file",
3317                        CLP_PARAM_ACTION_STOREDFILE, 3, 0);
3318#endif
3319#ifdef COIN_HAS_CLP
3320     parameters[numberParameters++] =
3321          CbcOrClpParam("reallyO!bjectiveScale", "Scale factor to apply to objective in place",
3322                        -1.0e20, 1.0e20, CLP_PARAM_DBL_OBJSCALE2, 0);
3323     parameters[numberParameters-1].setLonghelp
3324     (
3325          "You can set this to -1.0 to test maximization or other to stress code"
3326     );
3327     parameters[numberParameters-1].setDoubleValue(1.0);
3328     parameters[numberParameters++] =
3329          CbcOrClpParam("reallyS!cale", "Scales model in place",
3330                        CLP_PARAM_ACTION_REALLY_SCALE, 7, 0);
3331#endif
3332#ifdef COIN_HAS_CBC
3333     parameters[numberParameters++] =
3334          CbcOrClpParam("reduce!AndSplitCuts", "Whether to use Reduce-and-Split cuts",
3335                        "off", CBC_PARAM_STR_REDSPLITCUTS);
3336     parameters[numberParameters-1].append("on");
3337     parameters[numberParameters-1].append("root");
3338     parameters[numberParameters-1].append("ifmove");
3339     parameters[numberParameters-1].append("forceOn");
3340     parameters[numberParameters-1].setLonghelp
3341     (
3342          "This switches on reduce and split  cuts (either at root or in entire tree). \
3343May be slow \
3344See branchAndCut for information on options."
3345     );
3346      parameters[numberParameters++] =
3347          CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2",
3348                        "off", CBC_PARAM_STR_REDSPLIT2CUTS);
3349     parameters[numberParameters-1].append("on");
3350     parameters[numberParameters-1].append("root");
3351     parameters[numberParameters-1].append("longOn");
3352     parameters[numberParameters-1].append("longRoot");
3353     parameters[numberParameters-1].setLonghelp
3354     (
3355          "This switches on reduce and split  cuts (either at root or in entire tree) \
3356This version is by Giacomo Nannicini based on Francois Margot's version \
3357Standard setting only uses rows in tableau <=256, long uses all \
3358May be slow \
3359See branchAndCut for information on options."
3360     );
3361     parameters[numberParameters++] =
3362          CbcOrClpParam("reduce2!AndSplitCuts", "Whether to use Reduce-and-Split cuts - style 2",
3363                        "off", CBC_PARAM_STR_REDSPLIT2CUTS);
3364     parameters[numberParameters-1].append("on");
3365     parameters[numberParameters-1].append("root");
3366     parameters[numberParameters-1].append("longOn");
3367     parameters[numberParameters-1].append("longRoot");
3368     parameters[numberParameters-1].setLonghelp
3369     (
3370          "This switches on reduce and split  cuts (either at root or in entire tree) \
3371This version is by Giacomo Nannicini based on Francois Margot's version \
3372Standard setting only uses rows in tableau <=256, long uses all \
3373See branchAndCut for information on options."
3374     );
3375     parameters[numberParameters++] =
3376          CbcOrClpParam("residual!CapacityCuts", "Whether to use Residual Capacity cuts",
3377                        "off", CBC_PARAM_STR_RESIDCUTS);
3378     parameters[numberParameters-1].append("on");
3379     parameters[numberParameters-1].append("root");
3380     parameters[numberParameters-1].append("ifmove");
3381     parameters[numberParameters-1].append("forceOn");
3382     parameters[numberParameters-1].setLonghelp
3383     (
3384          "Residual capacity cuts. \
3385See branchAndCut for information on options."
3386     );
3387#endif
3388#ifdef COIN_HAS_CLP
3389     parameters[numberParameters++] =
3390          CbcOrClpParam("restore!Model", "Restore model from binary file",
3391                        CLP_PARAM_ACTION_RESTORE, 7, 1);
3392     parameters[numberParameters-1].setLonghelp
3393     (
3394          "This reads data save by saveModel from the given file.  It will use the default\
3395 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3396 is initialized to 'default.prob'."
3397     );
3398     parameters[numberParameters++] =
3399          CbcOrClpParam("reverse", "Reverses sign of objective",
3400                        CLP_PARAM_ACTION_REVERSE, 7, 0);
3401     parameters[numberParameters-1].setLonghelp
3402     (
3403          "Useful for testing if maximization works correctly"
3404     );
3405     parameters[numberParameters++] =
3406          CbcOrClpParam("rhs!Scale", "Scale factor to apply to rhs and bounds",
3407                        -1.0e20, 1.0e20, CLP_PARAM_DBL_RHSSCALE, 0);
3408     parameters[numberParameters-1].setLonghelp
3409     (
3410          "If the rhs or bounds have some very large meaningful values, you may wish to scale them\
3411 internally by this amount.  It can also be set by autoscale.  This should not be needed."
3412     );
3413     parameters[numberParameters-1].setDoubleValue(1.0);
3414#endif
3415#ifdef COIN_HAS_CBC
3416     parameters[numberParameters++] =
3417          CbcOrClpParam("Rens", "Whether to try Relaxation Enforced Neighborhood Search",
3418                        "off", CBC_PARAM_STR_RENS);
3419     parameters[numberParameters-1].append("on");
3420     parameters[numberParameters-1].append("both");
3421     parameters[numberParameters-1].append("before");
3422     parameters[numberParameters-1].append("200");
3423     parameters[numberParameters-1].append("1000");
3424     parameters[numberParameters-1].append("10000");
3425     parameters[numberParameters-1].append("dj");
3426     parameters[numberParameters-1].append("djbefore");
3427     parameters[numberParameters-1].setLonghelp
3428     (
3429          "This switches on Relaxation enforced neighborhood Search. \
3430on just does 50 nodes \
3431200 or 1000 does that many nodes. \
3432Doh option does heuristic before preprocessing"     );
3433     parameters[numberParameters++] =
3434          CbcOrClpParam("Rins", "Whether to try Relaxed Induced Neighborhood Search",
3435                        "off", CBC_PARAM_STR_RINS);
3436     parameters[numberParameters-1].append("on");
3437     parameters[numberParameters-1].append("both");
3438     parameters[numberParameters-1].append("before");
3439     parameters[numberParameters-1].append("often");
3440     parameters[numberParameters-1].setLonghelp
3441     (
3442          "This switches on Relaxed induced neighborhood Search. \
3443Doh option does heuristic before preprocessing"     );
3444     parameters[numberParameters++] =
3445          CbcOrClpParam("round!ingHeuristic", "Whether to use Rounding heuristic",
3446                        "off", CBC_PARAM_STR_ROUNDING);
3447     parameters[numberParameters-1].append("on");
3448     parameters[numberParameters-1].append("both");
3449     parameters[numberParameters-1].append("before");
3450     parameters[numberParameters-1].setLonghelp
3451     (
3452          "This switches on a simple (but effective) rounding heuristic at each node of tree.  \
3453On means do in solve i.e. after preprocessing, \
3454Before means do if doHeuristics used, off otherwise, \
3455and both means do if doHeuristics and in solve."
3456     );
3457
3458#endif
3459     parameters[numberParameters++] =
3460          CbcOrClpParam("saveM!odel", "Save model to binary file",
3461                        CLP_PARAM_ACTION_SAVE, 7, 1);
3462     parameters[numberParameters-1].setLonghelp
3463     (
3464          "This will save the problem to the given file name for future use\
3465 by restoreModel.  It will use the default\
3466 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3467 is initialized to 'default.prob'."
3468     );
3469     parameters[numberParameters++] =
3470          CbcOrClpParam("saveS!olution", "saves solution to file",
3471                        CLP_PARAM_ACTION_SAVESOL);
3472     parameters[numberParameters-1].setLonghelp
3473     (
3474          "This will write a binary solution file to the given file name.  It will use the default\
3475 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3476 is initialized to 'solution.file'.  To read the file use fread(int) twice to pick up number of rows \
3477and columns, then fread(double) to pick up objective value, then pick up row activities, row duals, column \
3478activities and reduced costs - see bottom of CbcOrClpParam.cpp for code that reads or writes file. \
3479If name contains '_fix_read_' then does not write but reads and will fix all variables"
3480     );
3481     parameters[numberParameters++] =
3482          CbcOrClpParam("scal!ing", "Whether to scale problem",
3483                        "off", CLP_PARAM_STR_SCALING);
3484     parameters[numberParameters-1].append("equi!librium");
3485     parameters[numberParameters-1].append("geo!metric");
3486     parameters[numberParameters-1].append("auto!matic");
3487     parameters[numberParameters-1].append("dynamic");
3488     parameters[numberParameters-1].append("rows!only");
3489     parameters[numberParameters-1].setLonghelp
3490     (
3491          "Scaling can help in solving problems which might otherwise fail because of lack of\
3492 accuracy.  It can also reduce the number of iterations.  It is not applied if the range\
3493 of elements is small.  When unscaled it is possible that there may be small primal and/or\
3494 infeasibilities."
3495     );
3496     parameters[numberParameters-1].setCurrentOption(3); // say auto
3497#ifndef COIN_HAS_CBC
3498     parameters[numberParameters++] =
3499          CbcOrClpParam("sec!onds", "Maximum seconds",
3500                        -1.0, 1.0e12, CLP_PARAM_DBL_TIMELIMIT);
3501     parameters[numberParameters-1].setLonghelp
3502     (
3503          "After this many seconds clp will act as if maximum iterations had been reached \
3504(if value >=0)."
3505     );
3506#else
3507     parameters[numberParameters++] =
3508          CbcOrClpParam("sec!onds", "maximum seconds",
3509                        -1.0, 1.0e12, CBC_PARAM_DBL_TIMELIMIT_BAB);
3510     parameters[numberParameters-1].setLonghelp
3511     (
3512          "After this many seconds coin solver will act as if maximum nodes had been reached."
3513     );
3514#endif
3515     parameters[numberParameters++] =
3516          CbcOrClpParam("sleep", "for debug",
3517                        CLP_PARAM_ACTION_DUMMY, 7, 0);
3518     parameters[numberParameters-1].setLonghelp
3519     (
3520          "If passed to solver fom ampl, then ampl will wait so that you can copy .nl file for debug."
3521     );
3522#ifdef COIN_HAS_CBC
3523     parameters[numberParameters++] =
3524          CbcOrClpParam("slow!cutpasses", "Maximum number of tries for slower cuts",
3525                        -1, COIN_INT_MAX, CBC_PARAM_INT_MAX_SLOW_CUTS);
3526     parameters[numberParameters-1].setLonghelp
3527     (
3528          "Some cut generators are fairly slow - this limits the number of times they are tried."
3529     );
3530     parameters[numberParameters-1].setIntValue(10);
3531#endif
3532#ifdef COIN_HAS_CLP
3533     parameters[numberParameters++] =
3534          CbcOrClpParam("slp!Value", "Number of slp passes before primal",
3535                        -50000, 50000, CLP_PARAM_INT_SLPVALUE, 1);
3536     parameters[numberParameters-1].setLonghelp
3537     (
3538          "If you are solving a quadratic problem using primal then it may be helpful to do some \
3539sequential Lps to get a good approximate solution."
3540     );
3541#if CLP_MULTIPLE_FACTORIZATIONS > 0
3542     parameters[numberParameters++] =
3543          CbcOrClpParam("small!Factorization", "Whether to use small factorization",
3544                        -1, 10000, CBC_PARAM_INT_SMALLFACT, 1);
3545     parameters[numberParameters-1].setLonghelp
3546     (
3547          "If processed problem <= this use small factorization"
3548     );
3549     parameters[numberParameters-1].setIntValue(-1);
3550#endif
3551#endif
3552     parameters[numberParameters++] =
3553          CbcOrClpParam("solu!tion", "Prints solution to file",
3554                        CLP_PARAM_ACTION_SOLUTION);
3555     parameters[numberParameters-1].setLonghelp
3556     (
3557          "This will write a primitive solution file to the given file name.  It will use the default\
3558 directory given by 'directory'.  A name of '$' will use the previous value for the name.  This\
3559 is initialized to 'stdout'.  The amount of output can be varied using printi!ngOptions or printMask."
3560     );
3561#ifdef COIN_HAS_CLP
3562#ifdef COIN_HAS_CBC
3563     parameters[numberParameters++] =
3564          CbcOrClpParam("solv!e", "Solve problem",
3565                        CBC_PARAM_ACTION_BAB);
3566     parameters[numberParameters-1].setLonghelp
3567     (
3568          "If there are no integer variables then this just solves LP.  If there are integer variables \
3569this does branch and cut."
3570     );
3571     parameters[numberParameters++] =
3572          CbcOrClpParam("sos!Options", "Whether to use SOS from AMPL",
3573                        "off", CBC_PARAM_STR_SOS);
3574     parameters[numberParameters-1].append("on");
3575     parameters[numberParameters-1].setCurrentOption("on");
3576     parameters[numberParameters-1].setLonghelp
3577     (
3578          "Normally if AMPL says there are SOS variables they should be used, but sometime sthey should\
3579 be turned off - this does so."
3580     );
3581     parameters[numberParameters++] =
3582          CbcOrClpParam("slog!Level", "Level of detail in (LP) Solver output",
3583                        -1, 63, CLP_PARAM_INT_SOLVERLOGLEVEL);
3584     parameters[numberParameters-1].setLonghelp
3585     (
3586          "If 0 then there should be no output in normal circumstances.  1 is probably the best\
3587 value for most uses, while 2 and 3 give more information.  This parameter is only used inside MIP - for Clp use 'log'"
3588     );
3589#else
3590     // allow solve as synonym for possible dual
3591     parameters[numberParameters++] =
3592       CbcOrClpParam("solv!e", "Solve problem using dual simplex (probably)",
3593                        CLP_PARAM_ACTION_EITHERSIMPLEX);
3594     parameters[numberParameters-1].setLonghelp
3595     (
3596          "Just so can use solve for clp as well as in cbc"
3597     );
3598#endif
3599#endif
3600#ifdef COIN_HAS_CLP
3601     parameters[numberParameters++] =
3602          CbcOrClpParam("spars!eFactor", "Whether factorization treated as sparse",
3603                        "on", CLP_PARAM_STR_SPARSEFACTOR, 7, 0);
3604     parameters[numberParameters-1].append("off");
3605     parameters[numberParameters++] =
3606          CbcOrClpParam("special!Options", "Dubious options for Simplex - see ClpSimplex.hpp",
3607                        0, COIN_INT_MAX, CLP_PARAM_INT_SPECIALOPTIONS, 0);
3608     parameters[numberParameters++] =
3609          CbcOrClpParam("sprint!Crash", "Whether to try sprint crash",
3610                        -1, 5000000, CLP_PARAM_INT_SPRINT);
3611     parameters[numberParameters-1].setLonghelp
3612     (
3613          "For long and thin problems this program may solve a series of small problems\
3614 created by taking a subset of the columns.  I introduced the idea as 'Sprint' after\
3615 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
3616  Cplex calls it 'sifting'.  -1 is automatic choice, 0 is off, n is number of passes"
3617     );
3618     parameters[numberParameters++] =
3619          CbcOrClpParam("stat!istics", "Print some statistics",
3620                        CLP_PARAM_ACTION_STATISTICS);
3621     parameters[numberParameters-1].setLonghelp
3622     (
3623          "This command prints some statistics for the current model.\
3624 If log level >1 then more is printed.\
3625 These are for presolved model if presolve on (and unscaled)."
3626     );
3627#endif
3628     parameters[numberParameters++] =
3629          CbcOrClpParam("stop", "Stops clp execution",
3630                        CLP_PARAM_ACTION_EXIT);
3631     parameters[numberParameters-1].setLonghelp
3632     (
3633          "This stops the execution of Clp, end, exit, quit and stop are synonyms"
3634     );
3635#ifdef COIN_HAS_CBC
3636     parameters[numberParameters++] =
3637          CbcOrClpParam("strat!egy", "Switches on groups of features",
3638                        0, 2, CBC_PARAM_INT_STRATEGY);
3639     parameters[numberParameters-1].setLonghelp
3640     (
3641          "This turns on newer features. \
3642Use 0 for easy problems, 1 is default, 2 is aggressive. \
36431 uses Gomory cuts using tolerance of 0.01 at root, \
3644does a possible restart after 100 nodes if can fix many \
3645and activates a diving and RINS heuristic and makes feasibility pump \
3646more aggressive. \
3647This does not apply to unit tests (where 'experiment' may have similar effects)."
3648     );
3649     parameters[numberParameters-1].setIntValue(1);
3650#ifdef CBC_KEEP_DEPRECATED
3651     parameters[numberParameters++] =
3652          CbcOrClpParam("strengthen", "Create strengthened problem",
3653                        CBC_PARAM_ACTION_STRENGTHEN, 3);
3654     parameters[numberParameters-1].setLonghelp
3655     (
3656          "This creates a new problem by applying the root node cuts.  All tight constraints \
3657will be in resulting problem"
3658     );
3659#endif
3660     parameters[numberParameters++] =
3661          CbcOrClpParam("strong!Branching", "Number of variables to look at in strong branching",
3662                        0, COIN_INT_MAX, CBC_PARAM_INT_STRONGBRANCHING);
3663     parameters[numberParameters-1].setLonghelp
3664     (
3665          "In order to decide which variable to branch on, the code will choose up to this number \
3666of unsatisfied variables to do mini up and down branches on.  Then the most effective one is chosen. \
3667If a variable is branched on many times then the previous average up and down costs may be used - \
3668see number before trust."
3669     );
3670#endif
3671#ifdef COIN_HAS_CLP
3672     parameters[numberParameters++] =
3673          CbcOrClpParam("subs!titution", "How long a column to substitute for in presolve",
3674                        0, 10000, CLP_PARAM_INT_SUBSTITUTION, 0);
3675     parameters[numberParameters-1].setLonghelp
3676     (
3677          "Normally Presolve gets rid of 'free' variables when there are no more than 3 \
3678 variables in column.  If you increase this the number of rows may decrease but number of \
3679 elements may increase."
3680     );
3681#endif
3682#ifdef COIN_HAS_CBC
3683     parameters[numberParameters++] =
3684          CbcOrClpParam("testO!si", "Test OsiObject stuff",
3685                        -1, COIN_INT_MAX, CBC_PARAM_INT_TESTOSI, 0);
3686#endif
3687#ifdef CBC_THREAD
3688     parameters[numberParameters++] =
3689          CbcOrClpParam("thread!s", "Number of threads to try and use",
3690                        -100, 100000, CBC_PARAM_INT_THREADS, 1);
3691     parameters[numberParameters-1].setLonghelp
3692     (
3693          "To use multiple threads, set threads to number wanted.  It may be better \
3694to use one or two more than number of cpus available.  If 100+n then n threads and \
3695search is repeatable (maybe be somewhat slower), \
3696if 200+n use threads for root cuts, 400+n threads used in sub-trees."
3697     );
3698#endif
3699#ifdef COIN_HAS_CBC
3700     parameters[numberParameters++] =
3701          CbcOrClpParam("tighten!Factor", "Tighten bounds using this times largest \
3702activity at continuous solution",
3703                        1.0e-3, 1.0e20, CBC_PARAM_DBL_TIGHTENFACTOR, 0);
3704     parameters[numberParameters-1].setLonghelp
3705     (
3706          "This sleazy trick can help on some problems."
3707     );
3708#endif
3709#ifdef COIN_HAS_CLP
3710     parameters[numberParameters++] =
3711          CbcOrClpParam("tightLP", "Poor person's preSolve for now",
3712                        CLP_PARAM_ACTION_TIGHTEN, 7, 0);
3713#endif
3714     parameters[numberParameters++] =
3715          CbcOrClpParam("timeM!ode", "Whether to use CPU or elapsed time",
3716                        "cpu", CLP_PARAM_STR_TIME_MODE);
3717     parameters[numberParameters-1].append("elapsed");
3718     parameters[numberParameters-1].setLonghelp
3719     (
3720          "cpu uses CPU time for stopping, while elapsed uses elapsed time. \
3721(On Windows, elapsed time is always used)."
3722     );
3723#ifdef COIN_HAS_CBC
3724     parameters[numberParameters++] =
3725          CbcOrClpParam("trust!PseudoCosts", "Number of branches before we trust pseudocosts",
3726                        -3, 2000000000, CBC_PARAM_INT_NUMBERBEFORE);
3727     parameters[numberParameters-1].setLonghelp
3728     (
3729          "Using strong branching computes pseudo-costs.  After this many times for a variable we just \
3730trust the pseudo costs and do not do any more strong branching."
3731     );
3732#endif
3733#ifdef COIN_HAS_CBC
3734     parameters[numberParameters++] =
3735          CbcOrClpParam("tune!PreProcess", "Dubious tuning parameters",
3736                        0, 2000000000, CLP_PARAM_INT_PROCESSTUNE, 1);
3737     parameters[numberParameters-1].setLonghelp
3738     (
3739          "Format aabbcccc - \n If aa then this is number of major passes (i.e. with presolve) \n \
3740If bb and bb>0 then this is number of minor passes (if unset or 0 then 10) \n \
3741cccc is bit set \n 0 - 1 Heavy probing \n 1 - 2 Make variables integer if possible (if obj value)\n \
37422 - 4 As above but even if zero objective value\n \
37437 - 128 Try and create cliques\n 8 - 256 If all +1 try hard for dominated rows\n \
374410 - 1024 Use a larger feasibility tolerance in presolve\n \
374511 - 2048 Try probing before creating cliques"
3746     );
3747     parameters[numberParameters++] =
3748          CbcOrClpParam("two!MirCuts", "Whether to use Two phase Mixed Integer Rounding cuts",
3749                        "off", CBC_PARAM_STR_TWOMIRCUTS);
3750     parameters[numberParameters-1].append("on");
3751     parameters[numberParameters-1].append("root");
3752     parameters[numberParameters-1].append("ifmove");
3753     parameters[numberParameters-1].append("forceOn");
3754     parameters[numberParameters-1].append("onglobal");
3755     parameters[numberParameters-1].append("forceandglobal");
3756     parameters[numberParameters-1].append("forceLongOn");
3757     parameters[numberParameters-1].setLonghelp
3758     (
3759          "This switches on two phase mixed integer rounding  cuts (either at root or in entire tree) \
3760See branchAndCut for information on options."
3761     );
3762#endif
3763     parameters[numberParameters++] =
3764          CbcOrClpParam("unitTest", "Do unit test",
3765                        CLP_PARAM_ACTION_UNITTEST, 3, 1);
3766     parameters[numberParameters-1].setLonghelp
3767     (
3768          "This exercises the unit test for clp"
3769     );
3770     parameters[numberParameters++] =
3771          CbcOrClpParam("userClp", "Hand coded Clp stuff",
3772                        CLP_PARAM_ACTION_USERCLP, 0, 0);
3773     parameters[numberParameters-1].setLonghelp
3774     (
3775          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3776Look for USERCLP in main driver and modify sample code."
3777     );
3778#ifdef COIN_HAS_CBC
3779     parameters[numberParameters++] =
3780          CbcOrClpParam("userCbc", "Hand coded Cbc stuff",
3781                        CBC_PARAM_ACTION_USERCBC, 0, 0);
3782     parameters[numberParameters-1].setLonghelp
3783     (
3784          "There are times e.g. when using AMPL interface when you may wish to do something unusual.  \
3785Look for USERCBC in main driver and modify sample code. \
3786It is possible you can get same effect by using example driver4.cpp."
3787     );
3788     parameters[numberParameters++] =
3789          CbcOrClpParam("Vnd!VariableNeighborhoodSearch", "Whether to try Variable Neighborhood Search",
3790                        "off", CBC_PARAM_STR_VND);
3791     parameters[numberParameters-1].append("on");
3792     parameters[numberParameters-1].append("both");
3793     parameters[numberParameters-1].append("before");
3794     parameters[numberParameters-1].append("intree");
3795     parameters[numberParameters-1].setLonghelp
3796     (
3797          "This switches on variable neighborhood Search. \
3798Doh option does heuristic before preprocessing"     );
3799#endif
3800     parameters[numberParameters++] =
3801          CbcOrClpParam("vector", "Whether to use vector? Form of matrix in simplex",
3802                        "off", CLP_PARAM_STR_VECTOR, 7, 0);
3803     parameters[numberParameters-1].append("on");
3804     parameters[numberParameters-1].setLonghelp
3805     (
3806          "If this is on ClpPackedMatrix uses extra column copy in odd format."
3807     );
3808     parameters[numberParameters++] =
3809          CbcOrClpParam("verbose", "Switches on longer help on single ?",
3810                        0, 31, CLP_PARAM_INT_VERBOSE, 0);
3811     parameters[numberParameters-1].setLonghelp
3812     (
3813          "Set to 1 to get short help with ? list, 2 to get long help, 3 for both.  (add 4 to just get ampl ones)."
3814     );
3815     parameters[numberParameters-1].setIntValue(0);
3816#ifdef COIN_HAS_CBC
3817     parameters[numberParameters++] =
3818          CbcOrClpParam("vub!heuristic", "Type of vub heuristic",
3819                        -2, 20, CBC_PARAM_INT_VUBTRY, 0);
3820     parameters[numberParameters-1].setLonghelp
3821     (
3822          "If set will try and fix some integer variables"
3823     );
3824     parameters[numberParameters-1].setIntValue(-1);
3825     parameters[numberParameters++] =
3826          CbcOrClpParam("zero!HalfCuts", "Whether to use zero half cuts",
3827                        "off", CBC_PARAM_STR_ZEROHALFCUTS);
3828     parameters[numberParameters-1].append("on");
3829     parameters[numberParameters-1].append("root");
3830     parameters[numberParameters-1].append("ifmove");
3831     parameters[numberParameters-1].append("forceOn");
3832     parameters[numberParameters-1].append("onglobal");
3833     parameters[numberParameters-1].setLonghelp
3834     (
3835          "This switches on zero-half cuts (either at root or in entire tree) \
3836See branchAndCut for information on options.  This implementation was written by \
3837Alberto Caprara."
3838     );
3839#endif
3840     parameters[numberParameters++] =
3841          CbcOrClpParam("zeroT!olerance", "Kill all coefficients \
3842whose absolute value is less than this value",
3843                        1.0e-100, 1.0e-5, CLP_PARAM_DBL_ZEROTOLERANCE);
3844     parameters[numberParameters-1].setLonghelp
3845     (
3846          "This applies to reading mps files (and also lp files \
3847if KILL_ZERO_READLP defined)"
3848     );
3849     parameters[numberParameters-1].setDoubleValue(1.0e-20);
3850     assert(numberParameters < CBCMAXPARAMETERS);
3851}
3852// Given a parameter type - returns its number in list
3853int whichParam (CbcOrClpParameterType name,
3854                int numberParameters, CbcOrClpParam *const parameters)
3855{
3856     int i;
3857     for (i = 0; i < numberParameters; i++) {
3858          if (parameters[i].type() == name)
3859               break;
3860     }
3861     assert (i < numberParameters);
3862     return i;
3863}
3864#ifdef COIN_HAS_CLP
3865/* Restore a solution from file.
3866   mode 0 normal, 1 swap rows and columns and primal and dual
3867   if 2 set then also change signs
3868*/
3869void restoreSolution(ClpSimplex * lpSolver, std::string fileName, int mode)
3870{
3871     FILE * fp = fopen(fileName.c_str(), "rb");
3872     if (fp) {
3873          int numberRows = lpSolver->numberRows();
3874          int numberColumns = lpSolver->numberColumns();
3875          int numberRowsFile;
3876          int numberColumnsFile;
3877          double objectiveValue;
3878          size_t nRead;
3879          nRead = fread(&numberRowsFile, sizeof(int), 1, fp);
3880          if (nRead != 1)
3881               throw("Error in fread");
3882          nRead = fread(&numberColumnsFile, sizeof(int), 1, fp);
3883          if (nRead != 1)
3884               throw("Error in fread");
3885          nRead = fread(&objectiveValue, sizeof(double), 1, fp);
3886          if (nRead != 1)
3887               throw("Error in fread");
3888          double * dualRowSolution = lpSolver->dualRowSolution();
3889          double * primalRowSolution = lpSolver->primalRowSolution();
3890          double * dualColumnSolution = lpSolver->dualColumnSolution();
3891          double * primalColumnSolution = lpSolver->primalColumnSolution();
3892          if (mode) {
3893               // swap
3894               int k = numberRows;
3895               numberRows = numberColumns;
3896               numberColumns = k;
3897               double * temp;
3898               temp = dualRowSolution;
3899               dualRowSolution = primalColumnSolution;
3900               primalColumnSolution = temp;
3901               temp = dualColumnSolution;
3902               dualColumnSolution = primalRowSolution;
3903               primalRowSolution = temp;
3904          }
3905          if (numberRows > numberRowsFile || numberColumns > numberColumnsFile) {
3906               std::cout << "Mismatch on rows and/or columns - giving up" << std::endl;
3907          } else {
3908               lpSolver->setObjectiveValue(objectiveValue);
3909               if (numberRows == numberRowsFile && numberColumns == numberColumnsFile) {
3910                    nRead = fread(primalRowSolution, sizeof(double), numberRows, fp);
3911                    if (nRead != static_cast<size_t>(numberRows))
3912                         throw("Error in fread");
3913                    nRead = fread(dualRowSolution, sizeof(double), numberRows, fp);
3914                    if (nRead != static_cast<size_t>(numberRows))
3915                         throw("Error in fread");
3916                    nRead = fread(primalColumnSolution, sizeof(double), numberColumns, fp);
3917                    if (nRead != static_cast<size_t>(numberColumns))
3918                         throw("Error in fread");
3919                    nRead = fread(dualColumnSolution, sizeof(double), numberColumns, fp);
3920                    if (nRead != static_cast<size_t>(numberColumns))
3921                         throw("Error in fread");
3922               } else {
3923                    std::cout << "Mismatch on rows and/or columns - truncating" << std::endl;
3924                    double * temp = new double [CoinMax(numberRowsFile, numberColumnsFile)];
3925                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
3926                    if (nRead != static_cast<size_t>(numberRowsFile))
3927                         throw("Error in fread");
3928                    CoinMemcpyN(temp, numberRows, primalRowSolution);
3929                    nRead = fread(temp, sizeof(double), numberRowsFile, fp);
3930                    if (nRead != static_cast<size_t>(numberRowsFile))
3931                         throw("Error in fread");
3932                    CoinMemcpyN(temp, numberRows, dualRowSolution);
3933                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
3934                    if (nRead != static_cast<size_t>(numberColumnsFile))
3935                         throw("Error in fread");
3936                    CoinMemcpyN(temp, numberColumns, primalColumnSolution);
3937                    nRead = fread(temp, sizeof(double), numberColumnsFile, fp);
3938                    if (nRead != static_cast<size_t>(numberColumnsFile))
3939                         throw("Error in fread");
3940                    CoinMemcpyN(temp, numberColumns, dualColumnSolution);
3941                    delete [] temp;
3942                           }
3943               if (mode == 3) {
3944                    int i;
3945                    for (i = 0; i < numberRows; i++) {
3946                         primalRowSolution[i] = -primalRowSolution[i];
3947                         dualRowSolution[i] = -dualRowSolution[i];
3948                    }
3949                    for (i = 0; i < numberColumns; i++) {
3950                         primalColumnSolution[i] = -primalColumnSolution[i];
3951                         dualColumnSolution[i] = -dualColumnSolution[i];
3952                    }
3953               }
3954          }
3955          fclose(fp);
3956     } else {
3957          std::cout << "Unable to open file " << fileName << std::endl;
3958     }
3959}
3960// Dump a solution to file
3961void saveSolution(const ClpSimplex * lpSolver, std::string fileName)
3962{
3963     if (strstr(fileName.c_str(), "_fix_read_")) {
3964          FILE * fp = fopen(fileName.c_str(), "rb");
3965          if (fp) {
3966               ClpSimplex * solver = const_cast<ClpSimplex *>(lpSolver);
3967               restoreSolution(solver, fileName, 0);
3968               // fix all
3969               int logLevel = solver->logLevel();
3970               int iColumn;
3971               int numberColumns = solver->numberColumns();
3972               double * primalColumnSolution =
3973                    solver->primalColumnSolution();
3974               double * columnLower = solver->columnLower();
3975               double * columnUpper = solver->columnUpper();
3976               for (iColumn = 0; iColumn < numberColumns; iColumn++) {
3977                    double value = primalColumnSolution[iColumn];
3978                    if (value > columnUpper[iColumn]) {
3979                         if (value > columnUpper[iColumn] + 1.0e-6 && logLevel > 1)
3980                              printf("%d value of %g - bounds %g %g\n",
3981                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
3982                         value = columnUpper[iColumn];
3983                    } else if (value < columnLower[iColumn]) {
3984                         if (value < columnLower[iColumn] - 1.0e-6 && logLevel > 1)
3985                              printf("%d value of %g - bounds %g %g\n",
3986                                     iColumn, value, columnLower[iColumn], columnUpper[iColumn]);
3987                         value = columnLower[iColumn];
3988                    }
3989                    columnLower[iColumn] = value;
3990                    columnUpper[iColumn] = value;
3991               }
3992               return;
3993          }
3994     }
3995     FILE * fp = fopen(fileName.c_str(), "wb");
3996     if (fp) {
3997          int numberRows = lpSolver->numberRows();
3998          int numberColumns = lpSolver->numberColumns();
3999          double objectiveValue = lpSolver->objectiveValue();
4000          size_t nWrite;
4001          nWrite = fwrite(&numberRows, sizeof(int), 1, fp);
4002          if (nWrite != 1)
4003               throw("Error in fwrite");
4004          nWrite = fwrite(&numberColumns, sizeof(int), 1, fp);
4005          if (nWrite != 1)
4006               throw("Error in fwrite");
4007          nWrite = fwrite(&objectiveValue, sizeof(double), 1, fp);
4008          if (nWrite != 1)
4009               throw("Error in fwrite");
4010          double * dualRowSolution = lpSolver->dualRowSolution();
4011          double * primalRowSolution = lpSolver->primalRowSolution();
4012          nWrite = fwrite(primalRowSolution, sizeof(double), numberRows, fp);
4013          if (nWrite != static_cast<size_t>(numberRows))
4014               throw("Error in fwrite");
4015          nWrite = fwrite(dualRowSolution, sizeof(double), numberRows, fp);
4016          if (nWrite != static_cast<size_t>(numberRows))
4017               throw("Error in fwrite");
4018          double * dualColumnSolution = lpSolver->dualColumnSolution();
4019          double * primalColumnSolution = lpSolver->primalColumnSolution();
4020          nWrite = fwrite(primalColumnSolution, sizeof(double), numberColumns, fp);
4021          if (nWrite != static_cast<size_t>(numberColumns))
4022               throw("Error in fwrite");
4023          nWrite = fwrite(dualColumnSolution, sizeof(double), numberColumns, fp);
4024          if (nWrite != static_cast<size_t>(numberColumns))
4025               throw("Error in fwrite");
4026          fclose(fp);
4027     } else {
4028          std::cout << "Unable to open file " << fileName << std::endl;
4029     }
4030}
4031#endif
Note: See TracBrowser for help on using the repository browser.