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

Last change on this file since 1665 was 1665, checked in by lou, 9 years ago

Add EPL license notice in src.

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