00001
00002
00003
00004 #include "CoinPragma.hpp"
00005
00006 #include <cassert>
00007 #include <cstdio>
00008 #include <cmath>
00009 #include <cfloat>
00010 #include <string>
00011 #include <iostream>
00012
00013
00014 #include "CoinPragma.hpp"
00015 #include "CoinHelperFunctions.hpp"
00016 #define CLPVERSION "0.99.1"
00017
00018 #include "CoinMpsIO.hpp"
00019
00020 #include "ClpFactorization.hpp"
00021 #include "CoinTime.hpp"
00022 #include "ClpSimplex.hpp"
00023 #include "ClpSolve.hpp"
00024 #include "ClpPackedMatrix.hpp"
00025 #include "ClpPlusMinusOneMatrix.hpp"
00026 #include "ClpNetworkMatrix.hpp"
00027 #include "ClpDualRowSteepest.hpp"
00028 #include "ClpDualRowDantzig.hpp"
00029 #include "ClpLinearObjective.hpp"
00030 #include "ClpPrimalColumnSteepest.hpp"
00031 #include "ClpPrimalColumnDantzig.hpp"
00032 #include "ClpPresolve.hpp"
00033
00034
00035
00036
00037
00038
00039
00040 #ifdef DMALLOC
00041 #include "dmalloc.h"
00042 #endif
00043
00044 static double totalTime=0.0;
00045
00046
00047
00048 #ifdef NDEBUG
00049 #undef NDEBUG
00050 #endif
00051
00052 int mainTest (int argc, const char *argv[],bool doDual,
00053 ClpSimplex empty, bool doPresolve,int doIdiot);
00054 enum ClpParameterType {
00055 GENERALQUERY=-100,
00056
00057 DUALTOLERANCE=1,PRIMALTOLERANCE,DUALBOUND,PRIMALWEIGHT,MAXTIME,OBJSCALE,
00058
00059 LOGLEVEL=101,MAXFACTOR,PERTVALUE,MAXITERATION,PRESOLVEPASS,IDIOT,SPRINT,
00060
00061 DIRECTION=201,DUALPIVOT,SCALING,ERRORSALLOWED,KEEPNAMES,SPARSEFACTOR,
00062 PRIMALPIVOT,PRESOLVE,CRASH,BIASLU,PERTURBATION,MESSAGES,
00063
00064 DIRECTORY=301,IMPORT,EXPORT,RESTORE,SAVE,DUALSIMPLEX,PRIMALSIMPLEX,
00065 MAXIMIZE,MINIMIZE,EXIT,STDIN,UNITTEST,NETLIB_DUAL,NETLIB_PRIMAL,SOLUTION,
00066 TIGHTEN,FAKEBOUND,HELP,PLUSMINUS,NETWORK,ALLSLACK,REVERSE,BARRIER,
00067
00068 INVALID=1000
00069 };
00070 static void printit(const char * input)
00071 {
00072 int length =strlen(input);
00073 char temp[101];
00074 int i;
00075 int n=0;
00076 for (i=0;i<length;i++) {
00077 if (input[i]=='\n') {
00078 temp[n]='\0';
00079 std::cout<<temp<<std::endl;
00080 n=0;
00081 } else if (n>=65&&input[i]==' ') {
00082 temp[n]='\0';
00083 std::cout<<temp<<std::endl;
00084 n=0;
00085 } else if (n||input[i]!=' ') {
00086 temp[n++]=input[i];
00087 }
00088 }
00089 if (n) {
00090 temp[n]='\0';
00091 std::cout<<temp<<std::endl;
00092 }
00093 }
00095 class ClpItem {
00096
00097 public:
00098
00101
00102 ClpItem ( );
00103 ClpItem (std::string name, std::string help,
00104 double lower, double upper, ClpParameterType type,bool display=true);
00105 ClpItem (std::string name, std::string help,
00106 int lower, int upper, ClpParameterType type,bool display=true);
00107
00108 ClpItem (std::string name, std::string help, std::string firstValue,
00109 ClpParameterType type,int defaultIndex=0,bool display=true);
00110
00111 ClpItem (std::string name, std::string help,
00112 ClpParameterType type,int indexNumber=-1,bool display=true);
00114 ClpItem(const ClpItem &);
00116 ClpItem & operator=(const ClpItem & rhs);
00118 ~ClpItem ( );
00120
00123
00124 void append(std::string keyWord);
00126 void addHelp(std::string keyWord);
00128 inline std::string name( ) const {
00129 return name_;
00130 };
00132 inline std::string shortHelp( ) const {
00133 return shortHelp_;
00134 };
00136 int setDoubleParameter(ClpSimplex * model, double value) const;
00138 double doubleParameter(ClpSimplex * model) const;
00140 int setIntParameter(ClpSimplex * model, int value) const;
00142 int intParameter(ClpSimplex * model) const;
00144 std::string matchName ( ) const;
00146 int parameterOption ( std::string check ) const;
00148 void printOptions ( ) const;
00150 inline std::string currentOption ( ) const
00151 { return definedKeyWords_[currentKeyWord_]; };
00153 inline void setCurrentOption ( int value )
00154 { currentKeyWord_=value; };
00156 inline void setIntValue ( int value )
00157 { intValue_=value; };
00158 inline int intValue () const
00159 { return intValue_; };
00161 inline void setDoubleValue ( double value )
00162 { doubleValue_=value; };
00163 inline double doubleValue () const
00164 { return doubleValue_; };
00166 inline void setStringValue ( std::string value )
00167 { stringValue_=value; };
00168 inline std::string stringValue () const
00169 { return stringValue_; };
00171 int matches (std::string input) const;
00173 inline ClpParameterType type() const
00174 { return type_;};
00176 inline bool displayThis() const
00177 { return display_;};
00179 inline void setLonghelp(const std::string help)
00180 {longHelp_=help;};
00182 void printLongHelp() const;
00184 void printString() const;
00186 inline int indexNumber() const
00187 { return indexNumber_;};
00188 private:
00190 void gutsOfConstructor();
00192
00193 private:
00194
00199
00200 ClpParameterType type_;
00202 double lowerDoubleValue_;
00203 double upperDoubleValue_;
00205 int lowerIntValue_;
00206 int upperIntValue_;
00207
00208 unsigned int lengthName_;
00209
00210 unsigned int lengthMatch_;
00212 std::vector<std::string> definedKeyWords_;
00214 std::string name_;
00216 std::string shortHelp_;
00218 std::string longHelp_;
00220 ClpParameterType action_;
00222 int currentKeyWord_;
00224 bool display_;
00226 int intValue_;
00228 double doubleValue_;
00230 std::string stringValue_;
00232 int indexNumber_;
00234 };
00235
00236
00237
00238
00239
00240
00241
00242 ClpItem::ClpItem ()
00243 : type_(INVALID),
00244 lowerDoubleValue_(0.0),
00245 upperDoubleValue_(0.0),
00246 lowerIntValue_(0),
00247 upperIntValue_(0),
00248 lengthName_(0),
00249 lengthMatch_(0),
00250 definedKeyWords_(),
00251 name_(),
00252 shortHelp_(),
00253 longHelp_(),
00254 action_(INVALID),
00255 currentKeyWord_(-1),
00256 display_(false),
00257 intValue_(-1),
00258 doubleValue_(-1.0),
00259 stringValue_(""),
00260 indexNumber_(INVALID)
00261 {
00262 }
00263
00264 ClpItem::ClpItem (std::string name, std::string help,
00265 double lower, double upper, ClpParameterType type,bool display)
00266 : type_(type),
00267 lowerIntValue_(0),
00268 upperIntValue_(0),
00269 definedKeyWords_(),
00270 name_(name),
00271 shortHelp_(help),
00272 longHelp_(),
00273 action_(type),
00274 currentKeyWord_(-1),
00275 display_(display),
00276 intValue_(-1),
00277 doubleValue_(-1.0),
00278 stringValue_(""),
00279 indexNumber_(type)
00280 {
00281 lowerDoubleValue_ = lower;
00282 upperDoubleValue_ = upper;
00283 gutsOfConstructor();
00284 }
00285 ClpItem::ClpItem (std::string name, std::string help,
00286 int lower, int upper, ClpParameterType type,bool display)
00287 : type_(type),
00288 lowerDoubleValue_(0.0),
00289 upperDoubleValue_(0.0),
00290 definedKeyWords_(),
00291 name_(name),
00292 shortHelp_(help),
00293 longHelp_(),
00294 action_(type),
00295 currentKeyWord_(-1),
00296 display_(display),
00297 intValue_(-1),
00298 doubleValue_(-1.0),
00299 stringValue_(""),
00300 indexNumber_(type)
00301 {
00302 gutsOfConstructor();
00303 lowerIntValue_ = lower;
00304 upperIntValue_ = upper;
00305 }
00306
00307 ClpItem::ClpItem (std::string name, std::string help,
00308 std::string firstValue,
00309 ClpParameterType type,
00310 int defaultIndex,bool display)
00311 : type_(type),
00312 lowerDoubleValue_(0.0),
00313 upperDoubleValue_(0.0),
00314 lowerIntValue_(0),
00315 upperIntValue_(0),
00316 definedKeyWords_(),
00317 name_(name),
00318 shortHelp_(help),
00319 longHelp_(),
00320 action_(type),
00321 currentKeyWord_(defaultIndex),
00322 display_(display),
00323 intValue_(-1),
00324 doubleValue_(-1.0),
00325 stringValue_(""),
00326 indexNumber_(type)
00327 {
00328 gutsOfConstructor();
00329 definedKeyWords_.push_back(firstValue);
00330 }
00331
00332 ClpItem::ClpItem (std::string name, std::string help,
00333 ClpParameterType type,int indexNumber,bool display)
00334 : type_(type),
00335 lowerDoubleValue_(0.0),
00336 upperDoubleValue_(0.0),
00337 lowerIntValue_(0),
00338 upperIntValue_(0),
00339 definedKeyWords_(),
00340 name_(name),
00341 shortHelp_(help),
00342 longHelp_(),
00343 action_(type),
00344 currentKeyWord_(-1),
00345 display_(display),
00346 intValue_(-1),
00347 doubleValue_(-1.0),
00348 stringValue_("")
00349 {
00350 if (indexNumber<0)
00351 indexNumber_=type;
00352 else
00353 indexNumber_=indexNumber;
00354 gutsOfConstructor();
00355 }
00356
00357
00358
00359
00360 ClpItem::ClpItem (const ClpItem & rhs)
00361 {
00362 type_ = rhs.type_;
00363 lowerDoubleValue_ = rhs.lowerDoubleValue_;
00364 upperDoubleValue_ = rhs.upperDoubleValue_;
00365 lowerIntValue_ = rhs.lowerIntValue_;
00366 upperIntValue_ = rhs.upperIntValue_;
00367 lengthName_ = rhs.lengthName_;
00368 lengthMatch_ = rhs.lengthMatch_;
00369 definedKeyWords_ = rhs.definedKeyWords_;
00370 name_ = rhs.name_;
00371 shortHelp_ = rhs.shortHelp_;
00372 longHelp_ = rhs.longHelp_;
00373 action_ = rhs.action_;
00374 currentKeyWord_ = rhs.currentKeyWord_;
00375 display_=rhs.display_;
00376 intValue_=rhs.intValue_;
00377 doubleValue_=rhs.doubleValue_;
00378 stringValue_=rhs.stringValue_;
00379 indexNumber_=rhs.indexNumber_;
00380 }
00381
00382
00383
00384
00385 ClpItem::~ClpItem ()
00386 {
00387 }
00388
00389
00390
00391
00392 ClpItem &
00393 ClpItem::operator=(const ClpItem& rhs)
00394 {
00395 if (this != &rhs) {
00396 type_ = rhs.type_;
00397 lowerDoubleValue_ = rhs.lowerDoubleValue_;
00398 upperDoubleValue_ = rhs.upperDoubleValue_;
00399 lowerIntValue_ = rhs.lowerIntValue_;
00400 upperIntValue_ = rhs.upperIntValue_;
00401 lengthName_ = rhs.lengthName_;
00402 lengthMatch_ = rhs.lengthMatch_;
00403 definedKeyWords_ = rhs.definedKeyWords_;
00404 name_ = rhs.name_;
00405 shortHelp_ = rhs.shortHelp_;
00406 longHelp_ = rhs.longHelp_;
00407 action_ = rhs.action_;
00408 currentKeyWord_ = rhs.currentKeyWord_;
00409 display_=rhs.display_;
00410 intValue_=rhs.intValue_;
00411 doubleValue_=rhs.doubleValue_;
00412 stringValue_=rhs.stringValue_;
00413 indexNumber_=rhs.indexNumber_;
00414 }
00415 return *this;
00416 }
00417 void
00418 ClpItem::gutsOfConstructor()
00419 {
00420 unsigned int shriekPos = name_.find('!');
00421 lengthName_ = name_.length();
00422 if ( shriekPos==std::string::npos ) {
00423
00424 lengthMatch_= lengthName_;
00425 } else {
00426 lengthMatch_=shriekPos;
00427 name_ = name_.substr(0,shriekPos)+name_.substr(shriekPos+1);
00428 lengthName_--;
00429 }
00430 }
00431
00432 void
00433 ClpItem::append(std::string keyWord)
00434 {
00435 definedKeyWords_.push_back(keyWord);
00436 }
00437
00438 int
00439 ClpItem::matches (std::string input) const
00440 {
00441
00442 if (input.length()>lengthName_) {
00443 return 0;
00444 } else {
00445 unsigned int i;
00446 for (i=0;i<input.length();i++) {
00447 if (tolower(name_[i])!=tolower(input[i]))
00448 break;
00449 }
00450 if (i<input.length()) {
00451 return 0;
00452 } else if (i>=lengthMatch_) {
00453 return 1;
00454 } else {
00455
00456 return 2;
00457 }
00458 }
00459 }
00460
00461 std::string
00462 ClpItem::matchName ( ) const
00463 {
00464 if (lengthMatch_==lengthName_)
00465 return name_;
00466 else
00467 return name_.substr(0,lengthMatch_)+"("+name_.substr(lengthMatch_)+")";
00468 }
00469
00470
00471 int
00472 ClpItem::parameterOption ( std::string check ) const
00473 {
00474 int numberItems = definedKeyWords_.size();
00475 if (!numberItems) {
00476 return -1;
00477 } else {
00478 int whichItem=0;
00479 unsigned int it;
00480 for (it=0;it<definedKeyWords_.size();it++) {
00481 std::string thisOne = definedKeyWords_[it];
00482 unsigned int shriekPos = thisOne.find('!');
00483 unsigned int length1 = thisOne.length();
00484 unsigned int length2 = length1;
00485 if ( shriekPos!=std::string::npos ) {
00486
00487 length2 = shriekPos;
00488 thisOne = thisOne.substr(0,shriekPos)+
00489 thisOne.substr(shriekPos+1);
00490 length1 = thisOne.length();
00491 }
00492 if (check.length()<=length1) {
00493 unsigned int i;
00494 for (i=0;i<check.length();i++) {
00495 if (tolower(thisOne[i])!=tolower(check[i]))
00496 break;
00497 }
00498 if (i<check.length()) {
00499 whichItem++;
00500 } else if (i>=length2) {
00501 break;
00502 }
00503 } else {
00504 whichItem++;
00505 }
00506 }
00507 if (whichItem<numberItems)
00508 return whichItem;
00509 else
00510 return -1;
00511 }
00512 }
00513
00514 void
00515 ClpItem::printOptions ( ) const
00516 {
00517 std::cout<<"Possible options for "<<name_<<" are:"<<std::endl;
00518 unsigned int it;
00519 for (it=0;it<definedKeyWords_.size();it++) {
00520 std::string thisOne = definedKeyWords_[it];
00521 unsigned int shriekPos = thisOne.find('!');
00522 if ( shriekPos!=std::string::npos ) {
00523
00524 thisOne = thisOne.substr(0,shriekPos)+
00525 "("+thisOne.substr(shriekPos+1)+")";
00526 }
00527 std::cout<<thisOne<<std::endl;
00528 }
00529 }
00530
00531 void
00532 ClpItem::printString() const
00533 {
00534 if (name_=="directory")
00535 std::cout<<"Current working directory is "<<stringValue_<<std::endl;
00536 else
00537 std::cout<<"Current default (if $ as parameter) for "<<name_
00538 <<" is "<<stringValue_<<std::endl;
00539 }
00540 int
00541 ClpItem::setDoubleParameter (ClpSimplex * model,double value) const
00542 {
00543 double oldValue = doubleParameter(model);
00544 if (value<lowerDoubleValue_||value>upperDoubleValue_) {
00545 std::cout<<value<<" was provided for "<<name_<<
00546 " - valid range is "<<lowerDoubleValue_<<" to "<<
00547 upperDoubleValue_<<std::endl;
00548 return 1;
00549 } else {
00550 std::cout<<name_<<" was changed from "<<oldValue<<" to "
00551 <<value<<std::endl;
00552 switch(type_) {
00553 case DUALTOLERANCE:
00554 model->setDualTolerance(value);
00555 break;
00556 case PRIMALTOLERANCE:
00557 model->setPrimalTolerance(value);
00558 break;
00559 case DUALBOUND:
00560 model->setDualBound(value);
00561 break;
00562 case PRIMALWEIGHT:
00563 model->setInfeasibilityCost(value);
00564 break;
00565 case MAXTIME:
00566 model->setMaximumSeconds(value);
00567 break;
00568 case OBJSCALE:
00569 model->setOptimizationDirection(value);
00570 break;
00571 default:
00572 abort();
00573 }
00574 return 0;
00575 }
00576 }
00577 double
00578 ClpItem::doubleParameter (ClpSimplex * model) const
00579 {
00580 double value;
00581 switch(type_) {
00582 case DUALTOLERANCE:
00583 value=model->dualTolerance();
00584 break;
00585 case PRIMALTOLERANCE:
00586 value=model->primalTolerance();
00587 break;
00588 case DUALBOUND:
00589 value=model->dualBound();
00590 break;
00591 case PRIMALWEIGHT:
00592 value=model->infeasibilityCost();
00593 break;
00594 case MAXTIME:
00595 value=model->maximumSeconds();
00596 break;
00597 case OBJSCALE:
00598 value=model->optimizationDirection();
00599 break;
00600 default:
00601 abort();
00602 }
00603 return value;
00604 }
00605 int
00606 ClpItem::setIntParameter (ClpSimplex * model,int value) const
00607 {
00608 int oldValue = intParameter(model);
00609 if (value<lowerIntValue_||value>upperIntValue_) {
00610 std::cout<<value<<" was provided for "<<name_<<
00611 " - valid range is "<<lowerIntValue_<<" to "<<
00612 upperIntValue_<<std::endl;
00613 return 1;
00614 } else {
00615 std::cout<<name_<<" was changed from "<<oldValue<<" to "
00616 <<value<<std::endl;
00617 switch(type_) {
00618 case LOGLEVEL:
00619 model->setLogLevel(value);
00620 break;
00621 case MAXFACTOR:
00622 model->factorization()->maximumPivots(value);
00623 break;
00624 case PERTVALUE:
00625 model->setPerturbation(value);
00626 break;
00627 case MAXITERATION:
00628 model->setMaximumIterations(value);
00629 break;
00630 default:
00631 abort();
00632 }
00633 return 0;
00634 }
00635 }
00636 int
00637 ClpItem::intParameter (ClpSimplex * model) const
00638 {
00639 int value;
00640 switch(type_) {
00641 case LOGLEVEL:
00642 value=model->logLevel();
00643 break;
00644 case MAXFACTOR:
00645 value=model->factorization()->maximumPivots();
00646 break;
00647 break;
00648 case PERTVALUE:
00649 value=model->perturbation();
00650 break;
00651 case MAXITERATION:
00652 value=model->maximumIterations();
00653 break;
00654 default:
00655 value=-1;
00656 break;
00657 }
00658 return value;
00659 }
00660
00661 void
00662 ClpItem::printLongHelp() const
00663 {
00664 if (type_>=1&&type_<400) {
00665 if (type_<LOGLEVEL) {
00666 printf("Range of values is %g to %g\n",lowerDoubleValue_,upperDoubleValue_);
00667 } else if (type_<DIRECTION) {
00668 printf("Range of values is %d to %d\n",lowerIntValue_,upperIntValue_);
00669 } else if (type_<DIRECTORY) {
00670 printOptions();
00671 }
00672 printit(longHelp_.c_str());
00673 }
00674 }
00675 #ifdef READLINE
00676 #include <readline/readline.h>
00677 #include <readline/history.h>
00678 #endif
00679
00680 static int read_mode=1;
00681 static char line[1000];
00682 static char * where=NULL;
00683
00684 std::string
00685 nextField()
00686 {
00687 std::string field;
00688 if (!where) {
00689
00690 #ifdef READLINE
00691
00692 where = readline ("Clp:");
00693
00694
00695 if (where) {
00696 if ( *where)
00697 add_history (where);
00698 strcpy(line,where);
00699 }
00700 #else
00701 fprintf(stdout,"Clp:");
00702 fflush(stdout);
00703 where = fgets(line,1000,stdin);
00704 #endif
00705 if (!where)
00706 return field;
00707 where = line;
00708
00709 char * lastNonBlank = line-1;
00710 while ( *where != '\0' ) {
00711 if ( *where != '\t' && *where < ' ' ) {
00712 break;
00713 } else if ( *where != '\t' && *where != ' ') {
00714 lastNonBlank = where;
00715 }
00716 where++;
00717 }
00718 where=line;
00719 *(lastNonBlank+1)='\0';
00720 }
00721
00722 while(*where==' '||*where=='\t')
00723 where++;
00724 char * saveWhere = where;
00725 while (*where!=' '&&*where!='\t'&&*where!='\0')
00726 where++;
00727 if (where!=saveWhere) {
00728 char save = *where;
00729 *where='\0';
00730
00731 field=saveWhere;
00732 *where=save;
00733 } else {
00734 where=NULL;
00735 field="EOL";
00736 }
00737 return field;
00738 }
00739
00740 std::string
00741 getCommand(int argc, const char *argv[])
00742 {
00743 std::string field="EOL";
00744 while (field=="EOL") {
00745 if (read_mode>0) {
00746 if (read_mode<argc) {
00747 field = argv[read_mode++];
00748 if (field=="-") {
00749 std::cout<<"Switching to line mode"<<std::endl;
00750 read_mode=-1;
00751 field=nextField();
00752 } else if (field[0]!='-') {
00753 if (read_mode!=2) {
00754 std::cout<<"skipping non-command "<<field<<std::endl;
00755 field="EOL";
00756 } else {
00757
00758 read_mode--;
00759 field="import";
00760 }
00761 } else {
00762 if (field!="--") {
00763
00764 field = field.substr(1);
00765 } else {
00766
00767 read_mode--;
00768 field="import";
00769 }
00770 }
00771 } else {
00772 field="";
00773 }
00774 } else {
00775 field=nextField();
00776 }
00777 }
00778
00779 return field;
00780 }
00781 std::string
00782 getString(int argc, const char *argv[])
00783 {
00784 std::string field="EOL";
00785 if (read_mode>0) {
00786 if (read_mode<argc) {
00787 if (argv[read_mode][0]!='-') {
00788 field = argv[read_mode++];
00789 } else if (!strcmp(argv[read_mode],"--")) {
00790 field = argv[read_mode++];
00791
00792 field = "-";
00793 }
00794 }
00795 } else {
00796 field=nextField();
00797 }
00798
00799 return field;
00800 }
00801
00802 int
00803 getIntField(int argc, const char *argv[],int * valid)
00804 {
00805 std::string field="EOL";
00806 if (read_mode>0) {
00807 if (read_mode<argc) {
00808
00809 field = argv[read_mode++];
00810 }
00811 } else {
00812 field=nextField();
00813 }
00814 int value=0;
00815
00816 if (field!="EOL") {
00817
00818 value = atoi(field.c_str());
00819 *valid=0;
00820 } else {
00821 *valid=2;
00822 }
00823 return value;
00824 }
00825 double
00826 getDoubleField(int argc, const char *argv[],int * valid)
00827 {
00828 std::string field="EOL";
00829 if (read_mode>0) {
00830 if (read_mode<argc) {
00831
00832 field = argv[read_mode++];
00833 }
00834 } else {
00835 field=nextField();
00836 }
00837 double value=0.0;
00838
00839 if (field!="EOL") {
00840
00841 value = atof(field.c_str());
00842 *valid=0;
00843 } else {
00844 *valid=2;
00845 }
00846 return value;
00847 }
00848 int main (int argc, const char *argv[])
00849 {
00850
00851 {
00852 double time1 = CoinCpuTime(),time2;
00853
00854
00855 ClpSimplex * models = new ClpSimplex[1];
00856
00857
00858 int allowImportErrors=0;
00859 int keepImportNames=1;
00860 int doIdiot=-1;
00861 int doCrash=0;
00862 int doSprint=-1;
00863
00864 int preSolve=5;
00865 models->setPerturbation(50);
00866 models->messageHandler()->setPrefix(false);
00867 std::string directory ="./";
00868 std::string importFile ="";
00869 std::string exportFile ="default.mps";
00870 std::string saveFile ="default.prob";
00871 std::string restoreFile ="default.prob";
00872 std::string solutionFile ="stdout";
00873 #define MAXPARAMETERS 100
00874 ClpItem parameters[MAXPARAMETERS];
00875 int numberParameters=0;
00876 parameters[numberParameters++]=
00877 ClpItem("?","For help",GENERALQUERY,-1,false);
00878 parameters[numberParameters++]=
00879 ClpItem("-","From stdin",
00880 STDIN,299,false);
00881 parameters[numberParameters++]=
00882 ClpItem("allS!lack","Set basis back to all slack",
00883 ALLSLACK,false);
00884 parameters[numberParameters-1].setLonghelp
00885 (
00886 "Useful for playing around"
00887 );
00888 parameters[numberParameters++]=
00889 ClpItem("barr!ier","Solve using primal dual predictor corrector algorithm",
00890 BARRIER);
00891 parameters[numberParameters-1].setLonghelp
00892 (
00893 "This command solves the current model using the primal dual predictor \
00894 corrector algorithm. This is not a sophisticated version just something JJF\
00895 knocked up\
00896 ** another slight drawback (early December) is that it does not work"
00897
00898 );
00899 parameters[numberParameters++]=
00900 ClpItem("biasLU","Whether factorization biased towards U",
00901 "UU",BIASLU,2,false);
00902 parameters[numberParameters-1].append("UX");
00903 parameters[numberParameters-1].append("LX");
00904 parameters[numberParameters-1].append("LL");
00905 parameters[numberParameters++]=
00906 ClpItem("crash","Whether to create basis for problem",
00907 "off",CRASH);
00908 parameters[numberParameters-1].append("on");
00909 parameters[numberParameters-1].setLonghelp
00910 (
00911 "If crash is set on and there is an all slack basis then Clp will put structural\
00912 variables into basis with the aim of getting dual feasible. On the whole dual seems to be\
00913 better without it and there alernative types of 'crash' for primal e.g. 'idiot' or 'sprint'."
00914 );
00915 parameters[numberParameters++]=
00916 ClpItem("direction","Minimize or Maximize",
00917 "min!imize",DIRECTION);
00918 parameters[numberParameters-1].append("max!imize");
00919 parameters[numberParameters-1].append("zero");
00920 parameters[numberParameters-1].setLonghelp
00921 (
00922 "The default is minimize - use 'direction maximize' for maximization.\n\
00923 You can also use the parameters 'maximize' or 'minimize'."
00924 );
00925 parameters[numberParameters++]=
00926 ClpItem("directory","Set Default directory for import etc.",
00927 DIRECTORY,299);
00928 parameters[numberParameters-1].setLonghelp
00929 (
00930 "This sets the directory which import, export, saveModel and restoreModel will use.\
00931 It is initialized to './'"
00932 );
00933 parameters[numberParameters-1].setStringValue(directory);
00934 parameters[numberParameters++]=
00935 ClpItem("dualB!ound","Initially algorithm acts as if no \
00936 gap between bounds exceeds this value",
00937 1.0e-20,1.0e12,DUALBOUND);
00938 parameters[numberParameters-1].setLonghelp
00939 (
00940 "The dual algorithm in Clp is a single phase algorithm as opposed to a two phase\
00941 algorithm where you first get feasible then optimal. If a problem has both upper and\
00942 lower bounds then it is trivial to get dual feasible by setting non basic variables\
00943 to correct bound. If the gap between the upper and lower bounds of a variable is more\
00944 than the value of dualBound Clp introduces fake bounds so that it can make the problem\
00945 dual feasible. This has the same effect as a composite objective function in the\
00946 primal algorithm. Too high a value may mean more iterations, while too low a bound means\
00947 the code may go all the way and then have to increase the bounds. OSL had a heuristic to\
00948 adjust bounds, maybe we need that here."
00949 );
00950 parameters[numberParameters-1].setDoubleValue(models->dualBound());
00951 parameters[numberParameters++]=
00952 ClpItem("dualP!ivot","Dual pivot choice algorithm",
00953 "auto!matic",DUALPIVOT);
00954 parameters[numberParameters-1].append("dant!zig");
00955 parameters[numberParameters-1].append("partial");
00956 parameters[numberParameters-1].append("steep!est");
00957 parameters[numberParameters-1].setLonghelp
00958 (
00959 "Clp can use any pivot selection algorithm which the user codes as long as it\
00960 implements the features in the abstract pivot base class. The Dantzig method is implemented\
00961 to show a simple method but its use is deprecated. Steepest is the method of choice and there\
00962 are two variants which keep all weights updated but only scan a subset each iteration.\
00963 Partial switches this on while automatic decides at each iteration based on information\
00964 about the factorization."
00965 );
00966 parameters[numberParameters++]=
00967 ClpItem("dualS!implex","Do dual simplex algorithm",
00968 DUALSIMPLEX);
00969 parameters[numberParameters-1].setLonghelp
00970 (
00971 "This command solves the current model using the dual steepest algorithm.\
00972 The time and iterations may be affected by settings such as presolve, scaling, crash\
00973 and also by dual pivot method, fake bound on variables and dual and primal tolerances."
00974 );
00975 parameters[numberParameters++]=
00976 ClpItem("dualT!olerance","For an optimal solution \
00977 no dual infeasibility may exceed this value",
00978 1.0e-20,1.0e12,DUALTOLERANCE);
00979 parameters[numberParameters-1].setLonghelp
00980 (
00981 "Normally the default tolerance is fine, but you may want to increase it a\
00982 bit if a dual run seems to be having a hard time"
00983 );
00984 parameters[numberParameters-1].setDoubleValue(models->dualTolerance());
00985 parameters[numberParameters++]=
00986 ClpItem("end","Stops clp execution",
00987 EXIT);
00988 parameters[numberParameters-1].setLonghelp
00989 (
00990 "This stops the execution of Clp, end, exit, quit and stop are synonyms"
00991 );
00992 parameters[numberParameters++]=
00993 ClpItem("error!sAllowed","Whether to allow import errors",
00994 "off",ERRORSALLOWED);
00995 parameters[numberParameters-1].append("on");
00996 parameters[numberParameters-1].setLonghelp
00997 (
00998 "The default is not to use any model which had errors when reading the mps file.\
00999 Setting this to 'on' will allow all errors from which the code can recover\
01000 by ignoring the error."
01001 );
01002 parameters[numberParameters++]=
01003 ClpItem("exit","Stops clp execution",
01004 EXIT);
01005 parameters[numberParameters-1].setLonghelp
01006 (
01007 "This stops the execution of Clp, end, exit, quit and stop are synonyms"
01008 );
01009 parameters[numberParameters++]=
01010 ClpItem("export","Export model as mps file",
01011 EXPORT);
01012 parameters[numberParameters-1].setLonghelp
01013 (
01014 "This will write an MPS format file to the given file name. It will use the default\
01015 directory given by 'directory'. A name of '$' will use the previous value for the name. This\
01016 is initialized to 'default.mps'."
01017 );
01018 parameters[numberParameters-1].setStringValue(exportFile);
01019 parameters[numberParameters++]=
01020 ClpItem("fakeB!ound","All bounds <= this value - DEBUG",
01021 1.0,1.0e15,FAKEBOUND,false);
01022 parameters[numberParameters++]=
01023 ClpItem("help","Print out version, non-standard options and some help",
01024 HELP);
01025 parameters[numberParameters++]=
01026 ClpItem("idiot!Crash","Whether to try idiot crash",
01027 -1,200,IDIOT);
01028 parameters[numberParameters-1].setLonghelp
01029 (
01030 "This is a type of 'crash' which works well on some homogeneous problems.\
01031 It works best on problems with unit elements and rhs but will do something to any model. It should only be\
01032 used before primal. It can be set to -1 when the code decides for itself whether to use it,\
01033 0 to switch off or n > 0 to do n passes."
01034 );
01035 parameters[numberParameters-1].setIntValue(doIdiot);
01036 parameters[numberParameters++]=
01037 ClpItem("import","Import model from mps file",
01038 IMPORT);
01039 parameters[numberParameters-1].setLonghelp
01040 (
01041 "This will read an MPS format file from the given file name. It will use the default\
01042 directory given by 'directory'. A name of '$' will use the previous value for the name. This\
01043 is initialized to '', i.e. it must be set. If you have libgz then it can read compressed\
01044 files 'xxxxxxxx.gz'.."
01045 );
01046 parameters[numberParameters-1].setStringValue(importFile);
01047 parameters[numberParameters++]=
01048 ClpItem("keepN!ames","Whether to keep names from import",
01049 "on",KEEPNAMES);
01050 parameters[numberParameters-1].append("off");
01051 parameters[numberParameters-1].setLonghelp
01052 (
01053 "It saves space to get rid of names so if you need to you can set this to off."
01054 );
01055 parameters[numberParameters++]=
01056 ClpItem("log!Level","Level of detail in output",
01057 0,63,LOGLEVEL);
01058 parameters[numberParameters-1].setLonghelp
01059 (
01060 "If 0 then there should be no output in normal circumstances. 1 is probably the best\
01061 value for most uses, while 2 and 3 give more information."
01062 );
01063 parameters[numberParameters-1].setIntValue(models->logLevel());
01064 parameters[numberParameters++]=
01065 ClpItem("max!imize","Set optimization direction to maximize",
01066 MAXIMIZE,299);
01067 parameters[numberParameters-1].setLonghelp
01068 (
01069 "The default is minimize - use 'maximize' for maximization.\n\
01070 You can also use the parameters 'direction maximize'."
01071 );
01072 parameters[numberParameters++]=
01073 ClpItem("maxF!actor","Maximum number of iterations between \
01074 refactorizations",
01075 1,999999,MAXFACTOR);
01076 parameters[numberParameters-1].setLonghelp
01077 (
01078 "If this is at its default value of 200 then in this executable clp will guess at a\
01079 value to use. Otherwise the user can set a value. The code may decide to re-factorize\
01080 earlier."
01081 );
01082 parameters[numberParameters-1].setIntValue(models->factorizationFrequency());
01083 parameters[numberParameters++]=
01084 ClpItem("maxIt!erations","Maximum number of iterations before \
01085 stopping",
01086 0,99999999,MAXITERATION);
01087 parameters[numberParameters-1].setLonghelp
01088 (
01089 "This can be used for testing purposes. The corresponding library call\n\
01090 \tsetMaximumIterations(value)\n can be useful. If the code stops on\
01091 seconds or by an interrupt this will be treated as stopping on maximum iterations"
01092 );
01093 parameters[numberParameters-1].setIntValue(models->maximumIterations());
01094 parameters[numberParameters++]=
01095 ClpItem("min!imize","Set optimization direction to minimize",
01096 MINIMIZE,299);
01097 parameters[numberParameters-1].setLonghelp
01098 (
01099 "The default is minimize - use 'maximize' for maximization.\n\
01100 This should only be necessary if you have previously set maximization \
01101 You can also use the parameters 'direction minimize'."
01102 );
01103 parameters[numberParameters++]=
01104 ClpItem("mess!ages","Controls if Clpnnnn is printed",
01105 "off",MESSAGES);
01106 parameters[numberParameters-1].append("on");
01107 parameters[numberParameters-1].setLonghelp
01108 ("The default for the Clp library is to put out messages such as:\n\
01109 Clp0005 2261 Objective 109.024 Primal infeas 944413 (758)\n\
01110 but this program turns this off to make it look more friendly. It can be useful\
01111 to turn them back on if you want to be able 'grep' for particular messages or if\
01112 you intend to override the behavior of a particular message."
01113 );
01114 parameters[numberParameters++]=
01115 ClpItem("netlib","Solve entire netlib test set",
01116 NETLIB_DUAL,-1,false);
01117 parameters[numberParameters++]=
01118 ClpItem("netlibP!rimal","Solve entire netlib test set (primal)",
01119 NETLIB_PRIMAL,-1,false);
01120 parameters[numberParameters++]=
01121 ClpItem("network","Tries to make network matrix",
01122 NETWORK,-1,false);
01123 parameters[numberParameters-1].setLonghelp
01124 (
01125 "Clp will go faster if the matrix can be converted to a network. The matrix\
01126 operations may be a bit faster with more efficient storage, but the main advantage\
01127 comes from using a network factorization. It will probably not be as fast as a \
01128 specialized network code."
01129 );
01130 parameters[numberParameters++]=
01131 ClpItem("objective!Scale","Scale factor to apply to objective",
01132 -1.0e20,1.0e20,OBJSCALE,false);
01133 parameters[numberParameters-1].setDoubleValue(models->optimizationDirection());
01134 parameters[numberParameters++]=
01135 ClpItem("passP!resolve","How many passes in presolve",
01136 0,100,PRESOLVEPASS);
01137 parameters[numberParameters-1].setLonghelp
01138 (
01139 "Normally Presolve does 5 passes but you may want to do less to make it\
01140 more lightweight or do more if improvements are still being made. As Presolve will return\
01141 if nothing is being taken out, then you should not need to use this fine tuning."
01142 );
01143 parameters[numberParameters-1].setIntValue(preSolve);
01144 parameters[numberParameters++]=
01145 ClpItem("pertV!alue","Method of perturbation",
01146 -5000,102,PERTVALUE,false);
01147 parameters[numberParameters-1].setIntValue(models->perturbation());
01148 parameters[numberParameters++]=
01149 ClpItem("perturb!ation","Whether to perturb problem",
01150 "on",PERTURBATION);
01151 parameters[numberParameters-1].append("off");
01152 parameters[numberParameters-1].setLonghelp
01153 (
01154 "Perturbation helps to stop cycling, but Clp uses other measures for this.\
01155 However large problems and especially ones with unit elements and unit rhs or costs\
01156 benefit from perturbation. Normally Clp tries to be intelligent, but you can switch this off.\
01157 The Clp library has this off by default. This program has it on."
01158 );
01159 parameters[numberParameters++]=
01160 ClpItem("plus!Minus","Tries to make +- 1 matrix",
01161 PLUSMINUS,-1,false);
01162 parameters[numberParameters-1].setLonghelp
01163 (
01164 "Clp will go slightly faster if the matrix can be converted so that the elements are\
01165 not stored and are known to be unit. The main advantage is memory use. Clp may automatically\
01166 see if it can convert the problem so you should not need to use this."
01167 );
01168 parameters[numberParameters++]=
01169 ClpItem("presolve","Whether to presolve problem",
01170 "on",PRESOLVE);
01171 parameters[numberParameters-1].append("off");
01172 parameters[numberParameters-1].append("more");
01173 parameters[numberParameters-1].setLonghelp
01174 (
01175 "Presolve analyzes the model to find such things as redundant equations, equations\
01176 which fix some variables, equations which can be transformed into bounds etc etc. For the\
01177 initial solve of any problem this is worth doing unless you know that it will have no effect."
01178 );
01179 parameters[numberParameters++]=
01180 ClpItem("primalP!ivot","Primal pivot choice algorithm",
01181 "auto!matic",PRIMALPIVOT);
01182 parameters[numberParameters-1].append("exa!ct");
01183 parameters[numberParameters-1].append("dant!zig");
01184 parameters[numberParameters-1].append("part!ial");
01185 parameters[numberParameters-1].append("steep!est");
01186 parameters[numberParameters-1].append("change");
01187 parameters[numberParameters-1].append("sprint");
01188 parameters[numberParameters-1].setLonghelp
01189 (
01190 "Clp can use any pivot selection algorithm which the user codes as long as it\
01191 implements the features in the abstract pivot base class. The Dantzig method is implemented\
01192 to show a simple method but its use is deprecated. Exact devex is the method of choice and there\
01193 are two variants which keep all weights updated but only scan a subset each iteration.\
01194 Partial switches this on while change initially does dantzig until the factorization\
01195 becomes denser. This is still a work in progress."
01196 );
01197 parameters[numberParameters++]=
01198 ClpItem("primalS!implex","Do primal simplex algorithm",
01199 PRIMALSIMPLEX);
01200 parameters[numberParameters-1].setLonghelp
01201 (
01202 "This command solves the current model using the primal algorithm.\
01203 The default is to use exact devex.\
01204 The time and iterations may be affected by settings such as presolve, scaling, crash\
01205 and also by column selection method, infeasibility weight and dual and primal tolerances."
01206 );
01207 parameters[numberParameters++]=
01208 ClpItem("primalT!olerance","For an optimal solution \
01209 no primal infeasibility may exceed this value",
01210 1.0e-20,1.0e12,PRIMALTOLERANCE);
01211 parameters[numberParameters-1].setLonghelp
01212 (
01213 "Normally the default tolerance is fine, but you may want to increase it a\
01214 bit if a primal run seems to be having a hard time"
01215 );
01216 parameters[numberParameters-1].setDoubleValue(models->primalTolerance());
01217 parameters[numberParameters++]=
01218 ClpItem("primalW!eight","Initially algorithm acts as if it \
01219 costs this much to be infeasible",
01220 1.0e-20,1.0e20,PRIMALWEIGHT);
01221 parameters[numberParameters-1].setLonghelp
01222 (
01223 "The primal algorithm in Clp is a single phase algorithm as opposed to a two phase\
01224 algorithm where you first get feasible then optimal. So Clp is minimizing this weight times\
01225 the sum of primal infeasibilities plus the true objective function (in minimization sense).\
01226 Too high a value may mean more iterations, while too low a bound means\
01227 the code may go all the way and then have to increase the weight in order to get feasible.\
01228 OSL had a heuristic to\
01229 adjust bounds, maybe we need that here."
01230 );
01231 parameters[numberParameters-1].setDoubleValue(models->infeasibilityCost());
01232 parameters[numberParameters++]=
01233 ClpItem("quit","Stops clp execution",
01234 EXIT);
01235 parameters[numberParameters-1].setLonghelp
01236 (
01237 "This stops the execution of Clp, end, exit, quit and stop are synonyms"
01238 );
01239 parameters[numberParameters++]=
01240 ClpItem("restore!Model","Restore model from binary file",
01241 RESTORE);
01242 parameters[numberParameters-1].setLonghelp
01243 (
01244 "This reads data save by saveModel from the given file. It will use the default\
01245 directory given by 'directory'. A name of '$' will use the previous value for the name. This\
01246 is initialized to 'default.prob'."
01247 );
01248 parameters[numberParameters-1].setStringValue(restoreFile);
01249 parameters[numberParameters++]=
01250 ClpItem("reverse","Reverses sign of objective",
01251 REVERSE,false);
01252 parameters[numberParameters-1].setLonghelp
01253 (
01254 "Useful for testing if maximization works correctly"
01255 );
01256 parameters[numberParameters++]=
01257 ClpItem("save!Model","Save model to binary file",
01258 SAVE);
01259 parameters[numberParameters-1].setLonghelp
01260 (
01261 "This will save the problem to the given file name for future use\
01262 by restoreModel. It will use the default\
01263 directory given by 'directory'. A name of '$' will use the previous value for the name. This\
01264 is initialized to 'default.prob'."
01265 );
01266 parameters[numberParameters-1].setStringValue(saveFile);
01267 parameters[numberParameters++]=
01268 ClpItem("scal!ing","Whether to scale problem",
01269 "off",SCALING);
01270 parameters[numberParameters-1].append("equi!librium");
01271 parameters[numberParameters-1].append("geo!metric");
01272 parameters[numberParameters-1].append("auto!matic");
01273 parameters[numberParameters-1].setLonghelp
01274 (
01275 "Scaling can help in solving problems which might otherwise fail because of lack of\
01276 accuracy. It can also reduce the number of iterations. It is not applied if the range\
01277 of elements is small. When unscaled it is possible that there may be small primal and/or\
01278 infeasibilities."
01279 );
01280 parameters[numberParameters-1].setCurrentOption(3);
01281 parameters[numberParameters++]=
01282 ClpItem("sec!onds","maximum seconds",
01283 0.0,1.0e12,MAXTIME);
01284 parameters[numberParameters-1].setLonghelp
01285 (
01286 "After this many seconds clp will act as if maximum iterations had been reached.\
01287 In this program it is really only useful for testing but the library function\n\
01288 \tsetMaximumSeconds(value)\n can be useful."
01289 );
01290 parameters[numberParameters-1].setDoubleValue(models->maximumSeconds());
01291 parameters[numberParameters++]=
01292 ClpItem("sol!ution","Prints solution to file",
01293 SOLUTION);
01294 parameters[numberParameters-1].setLonghelp
01295 (
01296 "This will write a primitive solution file to the given file name. It will use the default\
01297 directory given by 'directory'. A name of '$' will use the previous value for the name. This\
01298 is initialized to 'stdout'."
01299 );
01300 parameters[numberParameters-1].setStringValue(solutionFile);
01301 parameters[numberParameters++]=
01302 ClpItem("spars!eFactor","Whether factorization treated as sparse",
01303 "on",SPARSEFACTOR,0,false);
01304 parameters[numberParameters-1].append("off");
01305 parameters[numberParameters-1].append("on");
01306 parameters[numberParameters++]=
01307 ClpItem("sprint!Crash","Whether to try sprint crash",
01308 -1,500,SPRINT);
01309 parameters[numberParameters-1].setLonghelp
01310 (
01311 "For long and thin problems this program may solve a series of small problems\
01312 created by taking a subset of the columns. I introduced the idea as 'Sprint' after\
01313 an LP code of that name of the 60's which tried the same tactic (not totally successfully).\
01314 Cplex calls it 'sifting'. -1 is automatic choice, 0 is off, n is number of passes"
01315 );
01316 parameters[numberParameters-1].setIntValue(doSprint);
01317 ClpItem("stdin","From stdin",
01318 STDIN,-1,false);
01319 parameters[numberParameters++]=
01320 ClpItem("stop","Stops clp execution",
01321 EXIT);
01322 parameters[numberParameters-1].setLonghelp
01323 (
01324 "This stops the execution of Clp, end, exit, quit and stop are synonyms"
01325 );
01326 parameters[numberParameters++]=
01327 ClpItem("tight!en","Poor person's preSolve for now",
01328 TIGHTEN,-1,false);
01329 parameters[numberParameters++]=
01330 ClpItem("unitTest","Do unit test",
01331 UNITTEST,-1,false);
01332 assert(numberParameters<MAXPARAMETERS);
01333
01334
01335 int numberGoodCommands=0;
01336 bool * goodModels = new bool[1];
01337
01338
01339 int iModel=0;
01340 goodModels[0]=false;
01341
01342
01343
01344
01345
01346
01347
01348
01349 std::string field;
01350 std::cout<<"Coin LP version "<<CLPVERSION
01351 <<", build "<<__DATE__<<std::endl;
01352
01353 while (1) {
01354
01355 field=getCommand(argc,argv);
01356
01357
01358 if (!field.length()) {
01359 if (numberGoodCommands==1&&goodModels[0]) {
01360
01361 field="duals";
01362 } else if (!numberGoodCommands) {
01363
01364 std::cout
01365 <<"Clp takes input from arguments ( - switches to stdin)"
01366 <<std::endl
01367 <<"Enter ? for list of commands or help"<<std::endl;
01368 field="-";
01369 } else {
01370 break;
01371 }
01372 }
01373
01374
01375 int numberQuery=0;
01376 if (field!="?") {
01377 int length = field.length();
01378 int i;
01379 for (i=length-1;i>0;i--) {
01380 if (field[i]=='?')
01381 numberQuery++;
01382 else
01383 break;
01384 }
01385 field=field.substr(0,length-numberQuery);
01386 }
01387
01388 int iParam;
01389 int numberMatches=0;
01390 int firstMatch=-1;
01391 for ( iParam=0; iParam<numberParameters; iParam++ ) {
01392 int match = parameters[iParam].matches(field);
01393 if (match==1) {
01394 numberMatches = 1;
01395 firstMatch=iParam;
01396 break;
01397 } else {
01398 if (match&&firstMatch<0)
01399 firstMatch=iParam;
01400 numberMatches += match>>1;
01401 }
01402 }
01403 if (iParam<numberParameters&&!numberQuery) {
01404
01405 ClpItem found = parameters[iParam];
01406 ClpParameterType type = found.type();
01407 int valid;
01408 numberGoodCommands++;
01409 if (type==GENERALQUERY) {
01410 std::cout<<"In argument list keywords have leading - "
01411 ", -stdin or just - switches to stdin"<<std::endl;
01412 std::cout<<"One command per line (and no -)"<<std::endl;
01413 std::cout<<"abcd? gives list of possibilities, if only one + explanation"<<std::endl;
01414 std::cout<<"abcd?? adds explanation, if only one fuller help"<<std::endl;
01415 std::cout<<"abcd without value (where expected) gives current value"<<std::endl;
01416 std::cout<<"abcd value sets value"<<std::endl;
01417 std::cout<<"Commands are:"<<std::endl;
01418 int maxAcross=5;
01419 int limits[]={1,101,201,301,401};
01420 std::vector<std::string> types;
01421 types.push_back("Double parameters:");
01422 types.push_back("Int parameters:");
01423 types.push_back("Keyword parameters and others:");
01424 types.push_back("Actions:");
01425 int iType;
01426 for (iType=0;iType<4;iType++) {
01427 int across=0;
01428 std::cout<<types[iType]<<std::endl;
01429 for ( iParam=0; iParam<numberParameters; iParam++ ) {
01430 int type = parameters[iParam].indexNumber();
01431 if (parameters[iParam].displayThis()&&type>=limits[iType]
01432 &&type<limits[iType+1]) {
01433 if (!across)
01434 std::cout<<" ";
01435 std::cout<<parameters[iParam].matchName()<<" ";
01436 across++;
01437 if (across==maxAcross) {
01438 std::cout<<std::endl;
01439 across=0;
01440 }
01441 }
01442 }
01443 if (across)
01444 std::cout<<std::endl;
01445 }
01446 } else if (type<101) {
01447
01448 double value = getDoubleField(argc,argv,&valid);
01449 if (!valid) {
01450 parameters[iParam].setDoubleValue(value);
01451 parameters[iParam].setDoubleParameter(models+iModel,value);
01452 } else if (valid==1) {
01453 abort();
01454 } else {
01455 std::cout<<parameters[iParam].name()<<" has value "<<
01456 parameters[iParam].doubleValue()<<std::endl;
01457 }
01458 } else if (type<201) {
01459
01460 int value = getIntField(argc,argv,&valid);
01461 if (!valid) {
01462 parameters[iParam].setIntValue(value);
01463 if (parameters[iParam].type()==PRESOLVEPASS)
01464 preSolve = value;
01465 else if (parameters[iParam].type()==IDIOT)
01466 doIdiot = value;
01467 else if (parameters[iParam].type()==SPRINT)
01468 doSprint = value;
01469 else
01470 parameters[iParam].setIntParameter(models+iModel,value);
01471 } else if (valid==1) {
01472 abort();
01473 } else {
01474 std::cout<<parameters[iParam].name()<<" has value "<<
01475 parameters[iParam].intValue()<<std::endl;
01476 }
01477 } else if (type<301) {
01478
01479 std::string value = getString(argc,argv);
01480 int action = parameters[iParam].parameterOption(value);
01481 if (action<0) {
01482 if (value!="EOL") {
01483
01484 parameters[iParam].printOptions();
01485 } else {
01486
01487 std::cout<<parameters[iParam].name()<<" has value "<<
01488 parameters[iParam].currentOption()<<std::endl;
01489 }
01490 } else {
01491 parameters[iParam].setCurrentOption(action);
01492
01493 switch (type) {
01494 case DIRECTION:
01495 if (action==0)
01496 models[iModel].setOptimizationDirection(1);
01497 else if (action==1)
01498 models[iModel].setOptimizationDirection(-1);
01499 else
01500 models[iModel].setOptimizationDirection(0);
01501 break;
01502 case DUALPIVOT:
01503 if (action==0) {
01504 ClpDualRowSteepest steep(3);
01505 models[iModel].setDualRowPivotAlgorithm(steep);
01506 } else if (action==1) {
01507 ClpDualRowDantzig dantzig;
01508 models[iModel].setDualRowPivotAlgorithm(dantzig);
01509 } else if (action==2) {
01510
01511 ClpDualRowSteepest steep(2);
01512 models[iModel].setDualRowPivotAlgorithm(steep);
01513 } else {
01514 ClpDualRowSteepest steep;
01515 models[iModel].setDualRowPivotAlgorithm(steep);
01516 }
01517 break;
01518 case PRIMALPIVOT:
01519 if (action==0) {
01520 ClpPrimalColumnSteepest steep(3);
01521 models[iModel].setPrimalColumnPivotAlgorithm(steep);
01522 } else if (action==1) {
01523 ClpPrimalColumnSteepest steep(0);
01524 models[iModel].setPrimalColumnPivotAlgorithm(steep);
01525 } else if (action==2) {
01526 ClpPrimalColumnDantzig dantzig;
01527 models[iModel].setPrimalColumnPivotAlgorithm(dantzig);
01528 } else if (action==3) {
01529 ClpPrimalColumnSteepest steep(2);
01530 models[iModel].setPrimalColumnPivotAlgorithm(steep);
01531 } else if (action==4) {
01532 ClpPrimalColumnSteepest steep(1);
01533 models[iModel].setPrimalColumnPivotAlgorithm(steep);
01534 } else if (action==5) {
01535 ClpPrimalColumnSteepest steep(4);
01536 models[iModel].setPrimalColumnPivotAlgorithm(steep);
01537 } else if (action==6) {
01538 ClpPrimalColumnSteepest steep(10);
01539 models[iModel].setPrimalColumnPivotAlgorithm(steep);
01540 }
01541 break;
01542 case SCALING:
01543 models[iModel].scaling(action);
01544 break;
01545 case SPARSEFACTOR:
01546 models[iModel].setSparseFactorization((1-action)!=0);
01547 break;
01548 case BIASLU:
01549 models[iModel].factorization()->setBiasLU(action);
01550 break;
01551 case PERTURBATION:
01552 if (action==0)
01553 models[iModel].setPerturbation(50);
01554 else
01555 models[iModel].setPerturbation(100);
01556 break;
01557 case ERRORSALLOWED:
01558 allowImportErrors = action;
01559 break;
01560 case KEEPNAMES:
01561 keepImportNames = 1-action;
01562 break;
01563 case PRESOLVE:
01564 if (action==0)
01565 preSolve = 5;
01566 else if (action==1)
01567 preSolve=0;
01568 else
01569 preSolve=10;
01570 break;
01571 case CRASH:
01572 doCrash=action;
01573 break;
01574 case MESSAGES:
01575 models[iModel].messageHandler()->setPrefix(action!=0);
01576 break;
01577 default:
01578 abort();
01579 }
01580 }
01581 } else {
01582
01583 if (type==EXIT)
01584 break;
01585 switch (type) {
01586 case DUALSIMPLEX:
01587 case PRIMALSIMPLEX:
01588 case BARRIER:
01589 if (goodModels[iModel]) {
01590 ClpSolve::SolveType method;
01591 ClpSolve::PresolveType presolveType;
01592 ClpSimplex * model2 = models+iModel;
01593 ClpSolve solveOptions;
01594 if (preSolve!=5&&preSolve)
01595 presolveType=ClpSolve::presolveNumber;
01596 else if (preSolve)
01597 presolveType=ClpSolve::presolveOn;
01598 else
01599 presolveType=ClpSolve::presolveOff;
01600 solveOptions.setPresolveType(presolveType,preSolve);
01601 if (type==DUALSIMPLEX)
01602 method=ClpSolve::useDual;
01603 else if (type==PRIMALSIMPLEX)
01604 method=ClpSolve::usePrimalorSprint;
01605 else
01606 method = ClpSolve::useBarrier;
01607 solveOptions.setSolveType(method);
01608 if (method==ClpSolve::useDual) {
01609
01610 if (doCrash)
01611 solveOptions.setSpecialOption(0,1);
01612 else if (doIdiot)
01613 solveOptions.setSpecialOption(0,2,doIdiot);
01614 } else if (method==ClpSolve::usePrimalorSprint) {
01615
01616 if (doCrash) {
01617 solveOptions.setSpecialOption(1,1);
01618 } else if (doSprint>0) {
01619
01620 solveOptions.setSpecialOption(1,3,doSprint);
01621 } else if (doIdiot>0) {
01622 solveOptions.setSpecialOption(1,2,doIdiot);
01623 } else {
01624 if (doIdiot==0) {
01625 if (doSprint==0)
01626 solveOptions.setSpecialOption(1,4);
01627 else
01628 solveOptions.setSpecialOption(1,9);
01629 } else {
01630 if (doSprint==0)
01631 solveOptions.setSpecialOption(1,8);
01632 else
01633 solveOptions.setSpecialOption(1,7);
01634 }
01635 }
01636 }
01637 model2->initialSolve(solveOptions);
01638 } else {
01639 std::cout<<"** Current model not valid"<<std::endl;
01640 }
01641 break;
01642 case TIGHTEN:
01643 if (goodModels[iModel]) {
01644 int numberInfeasibilities = models[iModel].tightenPrimalBounds();
01645 if (numberInfeasibilities)
01646 std::cout<<"** Analysis indicates model infeasible"<<std::endl;
01647 } else {
01648 std::cout<<"** Current model not valid"<<std::endl;
01649 }
01650 break;
01651 case PLUSMINUS:
01652 if (goodModels[iModel]) {
01653 ClpMatrixBase * saveMatrix = models[iModel].clpMatrix();
01654 ClpPackedMatrix* clpMatrix =
01655 dynamic_cast< ClpPackedMatrix*>(saveMatrix);
01656 if (clpMatrix) {
01657 ClpPlusMinusOneMatrix * newMatrix = new ClpPlusMinusOneMatrix(*(clpMatrix->matrix()));
01658 if (newMatrix->getIndices()) {
01659 models[iModel].replaceMatrix(newMatrix);
01660 delete saveMatrix;
01661 std::cout<<"Matrix converted to +- one matrix"<<std::endl;
01662 } else {
01663 std::cout<<"Matrix can not be converted to +- 1 matrix"<<std::endl;
01664 }
01665 } else {
01666 std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
01667 }
01668 } else {
01669 std::cout<<"** Current model not valid"<<std::endl;
01670 }
01671 break;
01672 case NETWORK:
01673 if (goodModels[iModel]) {
01674 ClpMatrixBase * saveMatrix = models[iModel].clpMatrix();
01675 ClpPackedMatrix* clpMatrix =
01676 dynamic_cast< ClpPackedMatrix*>(saveMatrix);
01677 if (clpMatrix) {
01678 ClpNetworkMatrix * newMatrix = new ClpNetworkMatrix(*(clpMatrix->matrix()));
01679 if (newMatrix->getIndices()) {
01680 models[iModel].replaceMatrix(newMatrix);
01681 delete saveMatrix;
01682 std::cout<<"Matrix converted to network matrix"<<std::endl;
01683 } else {
01684 std::cout<<"Matrix can not be converted to network matrix"<<std::endl;
01685 }
01686 } else {
01687 std::cout<<"Matrix not a ClpPackedMatrix"<<std::endl;
01688 }
01689 } else {
01690 std::cout<<"** Current model not valid"<<std::endl;
01691 }
01692 break;
01693 case IMPORT:
01694 {
01695
01696 field = getString(argc,argv);
01697 if (field=="$") {
01698 field = parameters[iParam].stringValue();
01699 } else if (field=="EOL") {
01700 parameters[iParam].printString();
01701 break;
01702 } else {
01703 parameters[iParam].setStringValue(field);
01704 }
01705 std::string fileName;
01706 bool canOpen=false;
01707 if (field=="-") {
01708
01709 canOpen=true;
01710 fileName = "-";
01711 } else {
01712 if (field[0]=='/'||field[0]=='~'||field[0]=='\\')
01713 fileName = field;
01714 else
01715 fileName = directory+field;
01716 FILE *fp=fopen(fileName.c_str(),"r");
01717 if (fp) {
01718
01719 fclose(fp);
01720 canOpen=true;
01721 } else {
01722 std::cout<<"Unable to open file "<<fileName<<std::endl;
01723 }
01724 }
01725 if (canOpen) {
01726 int status =models[iModel].readMps(fileName.c_str(),
01727 keepImportNames!=0,
01728 allowImportErrors!=0);
01729 if (!status||(status>0&&allowImportErrors)) {
01730 goodModels[iModel]=true;
01731
01732 models[iModel].createStatus();
01733 time2 = CoinCpuTime();
01734 totalTime += time2-time1;
01735 time1=time2;
01736 } else {
01737
01738 std::cout<<"There were "<<status<<
01739 " errors on input"<<std::endl;
01740 }
01741 }
01742 }
01743 break;
01744 case EXPORT:
01745 {
01746
01747 field = getString(argc,argv);
01748 if (field=="$") {
01749 field = parameters[iParam].stringValue();
01750 } else if (field=="EOL") {
01751 parameters[iParam].printString();
01752 break;
01753 } else {
01754 parameters[iParam].setStringValue(field);
01755 }
01756 std::string fileName;
01757 bool canOpen=false;
01758 if (field[0]=='/'||field[0]=='~')
01759 fileName = field;
01760 else
01761 fileName = directory+field;
01762 FILE *fp=fopen(fileName.c_str(),"w");
01763 if (fp) {
01764
01765 fclose(fp);
01766 canOpen=true;
01767 } else {
01768 std::cout<<"Unable to open file "<<fileName<<std::endl;
01769 }
01770 if (canOpen) {
01771
01772 bool deleteModel2=false;
01773 ClpSimplex * model2 = models+iModel;
01774 if (preSolve) {
01775 ClpPresolve pinfo;
01776 model2 =
01777 pinfo.presolvedModel(models[iModel],1.0e-8,
01778 false,preSolve);
01779 if (model2) {
01780 printf("Saving presolved model on %s\n",
01781 fileName.c_str());
01782 deleteModel2=true;
01783 } else {
01784 printf("Presolved model looks infeasible - saving original on %s\n",
01785 fileName.c_str());
01786 deleteModel2=false;
01787 model2 = models+iModel;
01788
01789 }
01790 } else {
01791 printf("Saving model on %s\n",
01792 fileName.c_str());
01793 }
01794
01795 int iRow;
01796 int numberRows=model2->numberRows();
01797 int iColumn;
01798 int numberColumns=model2->numberColumns();
01799
01800 char ** rowNames = NULL;
01801 char ** columnNames = NULL;
01802 if (model2->lengthNames()) {
01803 rowNames = new char * [numberRows];
01804 for (iRow=0;iRow<numberRows;iRow++) {
01805 rowNames[iRow] =
01806 strdup(model2->rowName(iRow).c_str());
01807 #ifdef STRIPBLANKS
01808 char * xx = rowNames[iRow];
01809 int i;
01810 int length = strlen(xx);
01811 int n=0;
01812 for (i=0;i<length;i++) {
01813 if (xx[i]!=' ')
01814 xx[n++]=xx[i];
01815 }
01816 xx[n]='\0';
01817 #endif
01818 }
01819
01820 columnNames = new char * [numberColumns];
01821 for (iColumn=0;iColumn<numberColumns;iColumn++) {
01822 columnNames[iColumn] =
01823 strdup(model2->columnName(iColumn).c_str());
01824 #ifdef STRIPBLANKS
01825 char * xx = columnNames[iColumn];
01826 int i;
01827 int length = strlen(xx);
01828 int n=0;
01829 for (i=0;i<length;i++) {
01830 if (xx[i]!=' ')
01831 xx[n++]=xx[i];
01832 }
01833 xx[n]='\0';
01834 #endif
01835 }
01836 }
01837
01838 CoinMpsIO writer;
01839 writer.setMpsData(*model2->matrix(), COIN_DBL_MAX,
01840 model2->getColLower(), model2->getColUpper(),
01841 model2->getObjCoefficients(),
01842 (const char*) 0 ,
01843 model2->getRowLower(), model2->getRowUpper(),
01844 columnNames, rowNames);
01845
01846 writer.copyInIntegerInformation(model2->integerInformation());
01847 writer.writeMps(fileName.c_str(),0,0,1);
01848 if (rowNames) {
01849 for (iRow=0;iRow<numberRows;iRow++) {
01850 free(rowNames[iRow]);
01851 }
01852 delete [] rowNames;
01853 for (iColumn=0;iColumn<numberColumns;iColumn++) {
01854 free(columnNames[iColumn]);
01855 }
01856 delete [] columnNames;
01857 }
01858 if (deleteModel2)
01859 delete model2;
01860 time2 = CoinCpuTime();
01861 totalTime += time2-time1;
01862 time1=time2;
01863 }
01864 }
01865 break;
01866 case SAVE:
01867 {
01868
01869 field = getString(argc,argv);
01870 if (field=="$") {
01871 field = parameters[iParam].stringValue();
01872 } else if (field=="EOL") {
01873 parameters[iParam].printString();
01874 break;
01875 } else {
01876 parameters[iParam].setStringValue(field);
01877 }
01878 std::string fileName;
01879 bool canOpen=false;
01880 if (field[0]=='/'||field[0]=='~')
01881 fileName = field;
01882 else
01883 fileName = directory+field;
01884 FILE *fp=fopen(fileName.c_str(),"wb");
01885 if (fp) {
01886
01887 fclose(fp);
01888 canOpen=true;
01889 } else {
01890 std::cout<<"Unable to open file "<<fileName<<std::endl;
01891 }
01892 if (canOpen) {
01893 int status;
01894
01895 bool deleteModel2=false;
01896 ClpSimplex * model2 = models+iModel;
01897 if (preSolve) {
01898 ClpPresolve pinfo;
01899 model2 =
01900 pinfo.presolvedModel(models[iModel],1.0e-8,
01901 false,preSolve);
01902 if (model2) {
01903 printf("Saving presolved model on %s\n",
01904 fileName.c_str());
01905 deleteModel2=true;
01906 } else {
01907 printf("Presolved model looks infeasible - saving original on %s\n",
01908 fileName.c_str());
01909 deleteModel2=false;
01910 model2 = models+iModel;
01911
01912 }
01913 } else {
01914 printf("Saving model on %s\n",
01915 fileName.c_str());
01916 }
01917 status =model2->saveModel(fileName.c_str());
01918 if (deleteModel2)
01919 delete model2;
01920 if (!status) {
01921 goodModels[iModel]=true;
01922 time2 = CoinCpuTime();
01923 totalTime += time2-time1;
01924 time1=time2;
01925 } else {
01926
01927 std::cout<<"There were errors on output"<<std::endl;
01928 }
01929 }
01930 }
01931 break;
01932 case RESTORE:
01933 {
01934
01935 field = getString(argc,argv);
01936 if (field=="$") {
01937 field = parameters[iParam].stringValue();
01938 } else if (field=="EOL") {
01939 parameters[iParam].printString();
01940 break;
01941 } else {
01942 parameters[iParam].setStringValue(field);
01943 }
01944 std::string fileName;
01945 bool canOpen=false;
01946 if (field[0]=='/'||field[0]=='~')
01947 fileName = field;
01948 else
01949 fileName = directory+field;
01950 FILE *fp=fopen(fileName.c_str(),"rb");
01951 if (fp) {
01952
01953 fclose(fp);
01954 canOpen=true;
01955 } else {
01956 std::cout<<"Unable to open file "<<fileName<<std::endl;
01957 }
01958 if (canOpen) {
01959 int status =models[iModel].restoreModel(fileName.c_str());
01960 if (!status) {
01961 goodModels[iModel]=true;
01962 time2 = CoinCpuTime();
01963 totalTime += time2-time1;
01964 time1=time2;
01965 } else {
01966
01967 std::cout<<"There were errors on input"<<std::endl;
01968 }
01969 }
01970 }
01971 break;
01972 case MAXIMIZE:
01973 models[iModel].setOptimizationDirection(-1);
01974 break;
01975 case MINIMIZE:
01976 models[iModel].setOptimizationDirection(1);
01977 break;
01978 case ALLSLACK:
01979 models[iModel].createStatus();
01980 {
01981
01982 int iColumn;
01983 double * solution = models[iModel].primalColumnSolution();
01984 const double * lower = models[iModel].columnLower();
01985 const double * upper = models[iModel].columnUpper();
01986 int numberColumns = models[iModel].numberColumns();
01987 for (iColumn=0;iColumn<numberColumns;iColumn++) {
01988 if (lower[iColumn]>0.0) {
01989 solution[iColumn]=lower[iColumn];
01990 } else if (upper[iColumn]<0.0) {
01991 solution[iColumn]=upper[iColumn];
01992 } else {
01993 solution[iColumn]=0.0;
01994 }
01995 }
01996 }
01997 break;
01998 case REVERSE:
01999 if (goodModels[iModel]) {
02000 int iColumn;
02001 int numberColumns=models[iModel].numberColumns();
02002 double * dualColumnSolution =
02003 models[iModel].dualColumnSolution();
02004 ClpObjective * obj = models[iModel].objectiveAsObject();
02005 assert(dynamic_cast<ClpLinearObjective *> (obj));
02006 double offset;
02007 double * objective = obj->gradient(NULL,offset,true);
02008 for (iColumn=0;iColumn<numberColumns;iColumn++) {
02009 dualColumnSolution[iColumn] = dualColumnSolution[iColumn];
02010 objective[iColumn] = -objective[iColumn];
02011 }
02012 int iRow;
02013 int numberRows=models[iModel].numberRows();
02014 double * dualRowSolution =
02015 models[iModel].dualRowSolution();
02016 for (iRow=0;iRow<numberRows;iRow++)
02017 dualRowSolution[iRow] = dualRowSolution[iRow];
02018 }
02019 break;
02020 case DIRECTORY:
02021 {
02022 std::string name = getString(argc,argv);
02023 if (name!="EOL") {
02024 int length=name.length();
02025 if (name[length-1]=='/')
02026 directory=name;
02027 else
02028 directory = name+"/";
02029 parameters[iParam].setStringValue(directory);
02030 } else {
02031 parameters[iParam].printString();
02032 }
02033 }
02034 break;
02035 case STDIN:
02036 read_mode=-1;
02037 break;
02038 case NETLIB_DUAL:
02039 case NETLIB_PRIMAL:
02040 {
02041
02042 const char * fields[4];
02043 int nFields=2;
02044 fields[0]="fake main from unitTest";
02045 fields[1]="-netlib";
02046 if (directory!="./") {
02047 fields[2]="-netlibDir";
02048 fields[3]=directory.c_str();
02049 nFields=4;
02050 }
02051 if (type==NETLIB_DUAL)
02052 std::cerr<<"Doing netlib with dual agorithm"<<std::endl;
02053 else
02054 std::cerr<<"Doing netlib with primal agorithm"<<std::endl;
02055 mainTest(nFields,fields,(type==NETLIB_DUAL),models[iModel],
02056 (preSolve!=0),doIdiot);
02057 }
02058 break;
02059 case UNITTEST:
02060 {
02061
02062 const char * fields[3];
02063 int nFields=1;
02064 fields[0]="fake main from unitTest";
02065 if (directory!="./") {
02066 fields[1]="-mpsDir";
02067 fields[2]=directory.c_str();
02068 nFields=3;
02069 }
02070 mainTest(nFields,fields,false,models[iModel],(preSolve!=0),
02071 false);
02072 }
02073 break;
02074 case FAKEBOUND:
02075 if (goodModels[iModel]) {
02076
02077 double value = getDoubleField(argc,argv,&valid);
02078 if (!valid) {
02079 std::cout<<"Setting "<<parameters[iParam].name()<<
02080 " to DEBUG "<<value<<std::endl;
02081 int iRow;
02082 int numberRows=models[iModel].numberRows();
02083 double * rowLower = models[iModel].rowLower();
02084 double * rowUpper = models[iModel].rowUpper();
02085 for (iRow=0;iRow<numberRows;iRow++) {
02086
02087 if (rowLower[iRow]>-1.0e20||rowUpper[iRow]<1.0e20) {
02088 rowLower[iRow]=max(rowLower[iRow],-value);
02089 rowUpper[iRow]=min(rowUpper[iRow],value);
02090 }
02091 }
02092 int iColumn;
02093 int numberColumns=models[iModel].numberColumns();
02094 double * columnLower = models[iModel].columnLower();
02095 double * columnUpper = models[iModel].columnUpper();
02096 for (iColumn=0;iColumn<numberColumns;iColumn++) {
02097
02098 if (columnLower[iColumn]>-1.0e20||
02099 columnUpper[iColumn]<1.0e20) {
02100 columnLower[iColumn]=max(columnLower[iColumn],-value);
02101 columnUpper[iColumn]=min(columnUpper[iColumn],value);
02102 }
02103 }
02104 } else if (valid==1) {
02105 abort();
02106 } else {
02107 std::cout<<"enter value for "<<parameters[iParam].name()<<
02108 std::endl;
02109 }
02110 }
02111 break;
02112 case HELP:
02113 std::cout<<"Coin LP version "<<CLPVERSION
02114 <<", build "<<__DATE__<<std::endl;
02115 std::cout<<"Non default values:-"<<std::endl;
02116 std::cout<<"Perturbation "<<models[0].perturbation()<<" (default 100)"
02117 <<std::endl;
02118 printit(
02119 "Presolve being done with 5 passes\n\
02120 Dual steepest edge steep/partial on matrix shape and factorization density\n\
02121 Clpnnnn taken out of messages\n\
02122 If Factorization frequency default then done on size of matrix\n\n\
02123 (-)unitTest, (-)netlib or (-)netlibp will do standard tests\n\n\
02124 You can switch to interactive mode at any time so\n\
02125 clp watson.mps -scaling off -primalsimplex\nis the same as\n\
02126 clp watson.mps -\nscaling off\nprimalsimplex"
02127 );
02128 break;
02129 case SOLUTION:
02130 if (goodModels[iModel]) {
02131
02132 field = getString(argc,argv);
02133 if (field=="$") {
02134 field = parameters[iParam].stringValue();
02135 } else if (field=="EOL") {
02136 parameters[iParam].printString();
02137 break;
02138 } else {
02139 parameters[iParam].setStringValue(field);
02140 }
02141 std::string fileName;
02142 FILE *fp=NULL;
02143 if (field=="-"||field=="EOL"||field=="stdout") {
02144
02145 fp=stdout;
02146 } else if (field=="stderr") {
02147
02148 fp=stderr;
02149 } else {
02150 if (field[0]=='/'||field[0]=='~')
02151 fileName = field;
02152 else
02153 fileName = directory+field;
02154 fp=fopen(fileName.c_str(),"w");
02155 }
02156 if (fp) {
02157
02158 int iRow;
02159 int numberRows=models[iModel].numberRows();
02160 int lengthName = models[iModel].lengthNames();
02161
02162
02163 std::vector<std::string> rowNames =
02164 *(models[iModel].rowNames());
02165 std::vector<std::string> columnNames =
02166 *(models[iModel].columnNames());
02167
02168 double * dualRowSolution = models[iModel].dualRowSolution();
02169 double * primalRowSolution =
02170 models[iModel].primalRowSolution();
02171 double * rowLower = models[iModel].rowLower();
02172 double * rowUpper = models[iModel].rowUpper();
02173 double primalTolerance = models[iModel].primalTolerance();
02174 char format[6];
02175 sprintf(format,"%%-%ds",max(lengthName,8));
02176 for (iRow=0;iRow<numberRows;iRow++) {
02177 if (primalRowSolution[iRow]>rowUpper[iRow]+primalTolerance||
02178 primalRowSolution[iRow]<rowLower[iRow]-primalTolerance)
02179 fprintf(fp,"** ");
02180 fprintf(fp,"%7d ",iRow);
02181 if (lengthName)
02182 fprintf(fp,format,rowNames[iRow].c_str());
02183 fprintf(fp,"%15.8g %15.8g\n",primalRowSolution[iRow],
02184 dualRowSolution[iRow]);
02185 }
02186 int iColumn;
02187 int numberColumns=models[iModel].numberColumns();
02188 double * dualColumnSolution =
02189 models[iModel].dualColumnSolution();
02190 double * primalColumnSolution =
02191 models[iModel].primalColumnSolution();
02192 double * columnLower = models[iModel].columnLower();
02193 double * columnUpper = models[iModel].columnUpper();
02194 for (iColumn=0;iColumn<numberColumns;iColumn++) {
02195 if (primalColumnSolution[iColumn]>columnUpper[iColumn]+primalTolerance||
02196 primalColumnSolution[iColumn]<columnLower[iColumn]-primalTolerance)
02197 fprintf(fp,"** ");
02198 fprintf(fp,"%7d ",iColumn);
02199 if (lengthName)
02200 fprintf(fp,format,columnNames[iColumn].c_str());
02201 fprintf(fp,"%15.8g %15.8g\n",
02202 primalColumnSolution[iColumn],
02203 dualColumnSolution[iColumn]);
02204 }
02205 if (fp!=stdout)
02206 fclose(fp);
02207 } else {
02208 std::cout<<"Unable to open file "<<fileName<<std::endl;
02209 }
02210 } else {
02211 std::cout<<"** Current model not valid"<<std::endl;
02212
02213 }
02214 break;
02215 default:
02216 abort();
02217 }
02218 }
02219 } else if (!numberMatches) {
02220 std::cout<<"No match for "<<field<<" - ? for list of commands"
02221 <<std::endl;
02222 } else if (numberMatches==1) {
02223 if (!numberQuery) {
02224 std::cout<<"Short match for "<<field<<" - completion: ";
02225 std::cout<<parameters[firstMatch].matchName()<<std::endl;
02226 } else if (numberQuery) {
02227 std::cout<<parameters[firstMatch].matchName()<<" : ";
02228 std::cout<<parameters[firstMatch].shortHelp()<<std::endl;
02229 if (numberQuery>=2)
02230 parameters[firstMatch].printLongHelp();
02231 }
02232 } else {
02233 if (!numberQuery)
02234 std::cout<<"Multiple matches for "<<field<<" - possible completions:"
02235 <<std::endl;
02236 else
02237 std::cout<<"Completions of "<<field<<":"<<std::endl;
02238 for ( iParam=0; iParam<numberParameters; iParam++ ) {
02239 int match = parameters[iParam].matches(field);
02240 if (match&¶meters[iParam].displayThis()) {
02241 std::cout<<parameters[iParam].matchName();
02242 if (numberQuery>=2)
02243 std::cout<<" : "<<parameters[iParam].shortHelp();
02244 std::cout<<std::endl;
02245 }
02246 }
02247 }
02248 }
02249 delete [] models;
02250 delete [] goodModels;
02251 }
02252
02253 #ifdef DMALLOC
02254 dmalloc_log_unfreed();
02255 dmalloc_shutdown();
02256 #endif
02257 return 0;
02258 }