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

Last change on this file since 2385 was 2385, checked in by unxusr, 4 months ago

formatting

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