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

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

modify help for diveoption

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