00001
00002
00003 #ifndef ClpModel_H
00004 #define ClpModel_H
00005
00006 #include "ClpConfig.h"
00007
00008 #include <iostream>
00009 #include <cassert>
00010 #include <cmath>
00011 #include <vector>
00012 #include <string>
00013
00014
00015
00016 #include "ClpPackedMatrix.hpp"
00017 #include "CoinMessageHandler.hpp"
00018 #include "CoinHelperFunctions.hpp"
00019 #include "ClpParameters.hpp"
00020 #include "ClpObjective.hpp"
00021 class ClpEventHandler;
00022
00023
00024 #ifndef COIN_DBL_MAX
00025 #define COIN_DBL_MAX DBL_MAX
00026 #endif
00027
00037 class CoinBuild;
00038 class CoinModel;
00039 class ClpModel {
00040
00041 public:
00042
00048
00049 ClpModel (bool emptyMessages=false );
00050
00055 ClpModel(const ClpModel & rhs, int scalingMode=-1);
00057 ClpModel & operator=(const ClpModel & rhs);
00062 ClpModel (const ClpModel * wholeModel,
00063 int numberRows, const int * whichRows,
00064 int numberColumns, const int * whichColumns,
00065 bool dropNames=true, bool dropIntegers=true);
00067 ~ClpModel ( );
00069
00083 void loadProblem ( const ClpMatrixBase& matrix,
00084 const double* collb, const double* colub,
00085 const double* obj,
00086 const double* rowlb, const double* rowub,
00087 const double * rowObjective=NULL);
00088 void loadProblem ( const CoinPackedMatrix& matrix,
00089 const double* collb, const double* colub,
00090 const double* obj,
00091 const double* rowlb, const double* rowub,
00092 const double * rowObjective=NULL);
00093
00096 void loadProblem ( const int numcols, const int numrows,
00097 const CoinBigIndex* start, const int* index,
00098 const double* value,
00099 const double* collb, const double* colub,
00100 const double* obj,
00101 const double* rowlb, const double* rowub,
00102 const double * rowObjective=NULL);
00108 int loadProblem ( CoinModel & modelObject,bool tryPlusMinusOne=false);
00110 void loadProblem ( const int numcols, const int numrows,
00111 const CoinBigIndex* start, const int* index,
00112 const double* value,const int * length,
00113 const double* collb, const double* colub,
00114 const double* obj,
00115 const double* rowlb, const double* rowub,
00116 const double * rowObjective=NULL);
00118 void loadQuadraticObjective(const int numberColumns,
00119 const CoinBigIndex * start,
00120 const int * column, const double * element);
00121 void loadQuadraticObjective ( const CoinPackedMatrix& matrix);
00123 void deleteQuadraticObjective();
00125 void setRowObjective(const double * rowObjective);
00127 int readMps(const char *filename,
00128 bool keepNames=false,
00129 bool ignoreErrors = false);
00131 int readGMPL(const char *filename,const char * dataName,
00132 bool keepNames=false);
00134 void copyInIntegerInformation(const char * information);
00136 void deleteIntegerInformation();
00138 void setContinuous(int index);
00140 void setInteger(int index);
00142 bool isInteger(int index) const;
00144 void resize (int newNumberRows, int newNumberColumns);
00146 void deleteRows(int number, const int * which);
00148 void addRow(int numberInRow, const int * columns,
00149 const double * elements, double rowLower=-COIN_DBL_MAX,
00150 double rowUpper=COIN_DBL_MAX);
00152 void addRows(int number, const double * rowLower,
00153 const double * rowUpper,
00154 const CoinBigIndex * rowStarts, const int * columns,
00155 const double * elements);
00157 void addRows(int number, const double * rowLower,
00158 const double * rowUpper,
00159 const CoinBigIndex * rowStarts, const int * rowLengths,
00160 const int * columns,
00161 const double * elements);
00162 #ifndef CLP_NO_VECTOR
00163 void addRows(int number, const double * rowLower,
00164 const double * rowUpper,
00165 const CoinPackedVectorBase * const * rows);
00166 #endif
00167
00172 int addRows(const CoinBuild & buildObject,bool tryPlusMinusOne=false,
00173 bool checkDuplicates=true);
00182 int addRows(CoinModel & modelObject,bool tryPlusMinusOne=false,
00183 bool checkDuplicates=true);
00184
00186 void deleteColumns(int number, const int * which);
00188 void addColumn(int numberInColumn,
00189 const int * rows,
00190 const double * elements,
00191 double columnLower=0.0,
00192 double columnUpper=COIN_DBL_MAX,
00193 double objective=0.0);
00195 void addColumns(int number, const double * columnLower,
00196 const double * columnUpper,
00197 const double * objective,
00198 const CoinBigIndex * columnStarts, const int * rows,
00199 const double * elements);
00200 void addColumns(int number, const double * columnLower,
00201 const double * columnUpper,
00202 const double * objective,
00203 const CoinBigIndex * columnStarts, const int * columnLengths,
00204 const int * rows,
00205 const double * elements);
00206 #ifndef CLP_NO_VECTOR
00207 void addColumns(int number, const double * columnLower,
00208 const double * columnUpper,
00209 const double * objective,
00210 const CoinPackedVectorBase * const * columns);
00211 #endif
00212
00217 int addColumns(const CoinBuild & buildObject,bool tryPlusMinusOne=false,
00218 bool checkDuplicates=true);
00226 int addColumns(CoinModel & modelObject,bool tryPlusMinusOne=false,
00227 bool checkDuplicates=true);
00229 inline void modifyCoefficient(int row, int column, double newElement,
00230 bool keepZero=false)
00231 {matrix_->modifyCoefficient(row,column,newElement,keepZero);}
00233 void chgRowLower(const double * rowLower);
00235 void chgRowUpper(const double * rowUpper);
00237 void chgColumnLower(const double * columnLower);
00239 void chgColumnUpper(const double * columnUpper);
00241 void chgObjCoefficients(const double * objIn);
00245 void borrowModel(ClpModel & otherModel);
00248 void returnModel(ClpModel & otherModel);
00249
00251 void createEmptyMatrix();
00259 int cleanMatrix(double threshold=1.0e-20);
00261 void copy(const ClpMatrixBase * from, ClpMatrixBase * & to);
00262 #ifndef CLP_NO_STD
00264 void dropNames();
00266 void copyNames(std::vector<std::string> & rowNames,
00267 std::vector<std::string> & columnNames);
00269 void copyRowNames(const std::vector<std::string> & rowNames,int first, int last);
00271 void copyColumnNames(const std::vector<std::string> & columnNames, int first, int last);
00273 void copyRowNames(const char * const * rowNames,int first, int last);
00275 void copyColumnNames(const char * const * columnNames, int first, int last);
00277 void setRowName(int rowIndex, std::string & name) ;
00279 void setColumnName(int colIndex, std::string & name) ;
00280 #endif
00281
00288 int findNetwork(char * rotate, double fractionNeeded=0.75);
00291 CoinModel * createCoinModel() const;
00292
00305 int writeMps(const char *filename,
00306 int formatType=0,int numberAcross=2,
00307 double objSense=0.0) const ;
00309
00311
00312 inline int numberRows() const {
00313 return numberRows_;
00314 }
00315 inline int getNumRows() const {
00316 return numberRows_;
00317 }
00319 inline int getNumCols() const {
00320 return numberColumns_;
00321 }
00322 inline int numberColumns() const {
00323 return numberColumns_;
00324 }
00326 inline double primalTolerance() const {
00327 return dblParam_[ClpPrimalTolerance];
00328 }
00329 void setPrimalTolerance( double value) ;
00331 inline double dualTolerance() const { return dblParam_[ClpDualTolerance]; }
00332 void setDualTolerance( double value) ;
00334 inline double primalObjectiveLimit() const { return dblParam_[ClpPrimalObjectiveLimit];}
00335 void setPrimalObjectiveLimit(double value);
00337 inline double dualObjectiveLimit() const { return dblParam_[ClpDualObjectiveLimit];}
00338 void setDualObjectiveLimit(double value);
00340 inline double objectiveOffset() const { return dblParam_[ClpObjOffset];}
00341 void setObjectiveOffset(double value);
00343 inline double presolveTolerance() const
00344 { return dblParam_[ClpPresolveTolerance];}
00345 #ifndef CLP_NO_STD
00346 inline std::string problemName() const { return strParam_[ClpProbName]; }
00347 #endif
00349 inline int numberIterations() const { return numberIterations_; }
00350 inline int getIterationCount() const { return numberIterations_; }
00351 inline void setNumberIterations(int numberIterations)
00352 { numberIterations_ = numberIterations;}
00354 inline int solveType() const
00355 { return solveType_;}
00356 inline void setSolveType(int type)
00357 { solveType_=type;}
00359 inline int maximumIterations() const { return intParam_[ClpMaxNumIteration]; }
00360 void setMaximumIterations(int value);
00362 inline double maximumSeconds() const { return dblParam_[ClpMaxSeconds]; }
00363 void setMaximumSeconds(double value);
00365 bool hitMaximumIterations() const;
00375 inline int status() const { return problemStatus_; }
00376 inline int problemStatus() const { return problemStatus_; }
00378 inline void setProblemStatus(int problemStatus)
00379 { problemStatus_ = problemStatus;}
00394 inline int secondaryStatus() const { return secondaryStatus_; }
00395 inline void setSecondaryStatus(int status)
00396 { secondaryStatus_ = status;}
00398 inline bool isAbandoned() const { return problemStatus_==4; }
00400 inline bool isProvenOptimal() const { return problemStatus_==0; }
00402 inline bool isProvenPrimalInfeasible() const { return problemStatus_==1; }
00404 inline bool isProvenDualInfeasible() const { return problemStatus_==2; }
00406 bool isPrimalObjectiveLimitReached() const ;
00408 bool isDualObjectiveLimitReached() const ;
00410 inline bool isIterationLimitReached() const { return problemStatus_==3; }
00412 inline double optimizationDirection() const {
00413 return optimizationDirection_;
00414 }
00415 inline double getObjSense() const { return optimizationDirection_; }
00416 void setOptimizationDirection(double value);
00418 inline double * primalRowSolution() const { return rowActivity_; }
00419 inline const double * getRowActivity() const { return rowActivity_; }
00421 inline double * primalColumnSolution() const { return columnActivity_; }
00422 inline const double * getColSolution() const { return columnActivity_; }
00423 inline void setColSolution(const double * input)
00424 { memcpy(columnActivity_,input,numberColumns_*sizeof(double));}
00426 inline double * dualRowSolution() const { return dual_; }
00427 inline const double * getRowPrice() const { return dual_; }
00429 inline double * dualColumnSolution() const { return reducedCost_; }
00430 inline const double * getReducedCost() const { return reducedCost_; }
00432 inline double* rowLower() const { return rowLower_; }
00433 inline const double* getRowLower() const { return rowLower_; }
00435 inline double* rowUpper() const { return rowUpper_; }
00436 inline const double* getRowUpper() const { return rowUpper_; }
00437
00441 void setObjectiveCoefficient( int elementIndex, double elementValue );
00443 inline void setObjCoeff( int elementIndex, double elementValue )
00444 { setObjectiveCoefficient( elementIndex, elementValue);}
00445
00448 void setColumnLower( int elementIndex, double elementValue );
00449
00452 void setColumnUpper( int elementIndex, double elementValue );
00453
00455 void setColumnBounds( int elementIndex,
00456 double lower, double upper );
00457
00466 void setColumnSetBounds(const int* indexFirst,
00467 const int* indexLast,
00468 const double* boundList);
00469
00472 inline void setColLower( int elementIndex, double elementValue )
00473 { setColumnLower(elementIndex, elementValue);}
00476 inline void setColUpper( int elementIndex, double elementValue )
00477 { setColumnUpper(elementIndex, elementValue);}
00478
00480 inline void setColBounds( int elementIndex,
00481 double lower, double upper )
00482 { setColumnBounds(elementIndex, lower, upper);}
00483
00490 inline void setColSetBounds(const int* indexFirst,
00491 const int* indexLast,
00492 const double* boundList)
00493 { setColumnSetBounds(indexFirst, indexLast, boundList);}
00494
00497 void setRowLower( int elementIndex, double elementValue );
00498
00501 void setRowUpper( int elementIndex, double elementValue ) ;
00502
00504 void setRowBounds( int elementIndex,
00505 double lower, double upper ) ;
00506
00513 void setRowSetBounds(const int* indexFirst,
00514 const int* indexLast,
00515 const double* boundList);
00516
00518
00519 inline const double * rowScale() const {return rowScale_;}
00520 inline const double * columnScale() const {return columnScale_;}
00521 inline const double * inverseRowScale() const {return inverseRowScale_;}
00522 inline const double * inverseColumnScale() const {return inverseColumnScale_;}
00523 inline double * mutableRowScale() const {return rowScale_;}
00524 inline double * mutableColumnScale() const {return columnScale_;}
00525 inline double * mutableInverseRowScale() const {return inverseRowScale_;}
00526 inline double * mutableInverseColumnScale() const {return inverseColumnScale_;}
00527 void setRowScale(double * scale) ;
00528 void setColumnScale(double * scale);
00530 inline double objectiveScale() const
00531 { return objectiveScale_;}
00532 inline void setObjectiveScale(double value)
00533 { objectiveScale_ = value;}
00535 inline double rhsScale() const
00536 { return rhsScale_;}
00537 inline void setRhsScale(double value)
00538 { rhsScale_ = value;}
00540 void scaling(int mode=1);
00543 void unscale();
00545 inline int scalingFlag() const {return scalingFlag_;}
00547 inline double * objective() const
00548 {
00549 if (objective_) {
00550 double offset;
00551 return objective_->gradient(NULL,NULL,offset,false);
00552 } else {
00553 return NULL;
00554 }
00555 }
00556 inline double * objective(const double * solution, double & offset,bool refresh=true) const
00557 {
00558 offset=0.0;
00559 if (objective_) {
00560 return objective_->gradient(NULL,solution,offset,refresh);
00561 } else {
00562 return NULL;
00563 }
00564 }
00565 inline const double * getObjCoefficients() const
00566 {
00567 if (objective_) {
00568 double offset;
00569 return objective_->gradient(NULL,NULL,offset,false);
00570 } else {
00571 return NULL;
00572 }
00573 }
00575 inline double * rowObjective() const { return rowObjective_; }
00576 inline const double * getRowObjCoefficients() const {
00577 return rowObjective_;
00578 }
00580 inline double * columnLower() const { return columnLower_; }
00581 inline const double * getColLower() const { return columnLower_; }
00583 inline double * columnUpper() const { return columnUpper_; }
00584 inline const double * getColUpper() const { return columnUpper_; }
00586 inline CoinPackedMatrix * matrix() const {
00587 if ( matrix_ == NULL ) return NULL;
00588 else return matrix_->getPackedMatrix();
00589 }
00591 inline int getNumElements() const
00592 { return matrix_->getNumElements();}
00595 inline double getSmallElementValue() const
00596 { return smallElement_;}
00597 inline void setSmallElementValue(double value)
00598 { smallElement_=value;}
00600 inline ClpMatrixBase * rowCopy() const { return rowCopy_; }
00602 inline ClpMatrixBase * clpMatrix() const { return matrix_; }
00604 inline ClpPackedMatrix * clpScaledMatrix() const { return scaledMatrix_; }
00606 inline void setClpScaledMatrix(ClpPackedMatrix * scaledMatrix)
00607 { delete scaledMatrix_; scaledMatrix_=scaledMatrix; }
00613 void replaceMatrix(ClpMatrixBase * matrix,bool deleteCurrent=false);
00619 inline void replaceMatrix(CoinPackedMatrix * matrix,
00620 bool deleteCurrent=false)
00621 { replaceMatrix(new ClpPackedMatrix(matrix),deleteCurrent);}
00623 inline double objectiveValue() const {
00624 return objectiveValue_*optimizationDirection_ - dblParam_[ClpObjOffset];
00625 }
00626 inline void setObjectiveValue(double value) {
00627 objectiveValue_ = (value+ dblParam_[ClpObjOffset])/optimizationDirection_;
00628 }
00629 inline double getObjValue() const {
00630 return objectiveValue_*optimizationDirection_ - dblParam_[ClpObjOffset];
00631 }
00633 inline char * integerInformation() const { return integerType_; }
00636 double * infeasibilityRay() const;
00637 double * unboundedRay() const;
00639 inline bool statusExists() const
00640 { return (status_!=NULL);}
00642 inline unsigned char * statusArray() const
00643 { return status_;}
00646 unsigned char * statusCopy() const;
00648 void copyinStatus(const unsigned char * statusArray);
00649
00651 inline void setUserPointer (void * pointer)
00652 { userPointer_=pointer;}
00653 inline void * getUserPointer () const
00654 { return userPointer_;}
00656 inline int whatsChanged() const
00657 { return whatsChanged_;}
00658 inline void setWhatsChanged(int value)
00659 { whatsChanged_ = value;}
00661 inline int numberThreads() const
00662 { return numberThreads_;}
00663 inline void setNumberThreads(int value)
00664 { numberThreads_ = value;}
00666
00668
00669 void passInMessageHandler(CoinMessageHandler * handler);
00671 CoinMessageHandler * pushMessageHandler(CoinMessageHandler * handler,
00672 bool & oldDefault);
00674 void popMessageHandler(CoinMessageHandler * oldHandler,bool oldDefault);
00676 void newLanguage(CoinMessages::Language language);
00677 inline void setLanguage(CoinMessages::Language language) { newLanguage(language); }
00679 inline CoinMessageHandler * messageHandler() const { return handler_; }
00681 inline CoinMessages messages() const { return messages_; }
00683 inline CoinMessages * messagesPointer() { return & messages_; }
00685 inline CoinMessages coinMessages() const { return coinMessages_; }
00687 inline CoinMessages * coinMessagesPointer() { return & coinMessages_; }
00696 inline void setLogLevel(int value) { handler_->setLogLevel(value); }
00697 inline int logLevel() const { return handler_->logLevel(); }
00699 inline bool defaultHandler() const
00700 { return defaultHandler_;}
00702 void passInEventHandler(const ClpEventHandler * eventHandler);
00704 inline ClpEventHandler * eventHandler() const
00705 { return eventHandler_;}
00707 inline CoinThreadRandom * randomNumberGenerator()
00708 { return &randomNumberGenerator_;}
00710 inline CoinThreadRandom & mutableRandomNumberGenerator()
00711 { return randomNumberGenerator_;}
00713 inline void setRandomSeed(int value)
00714 { randomNumberGenerator_.setSeed(value);}
00716 inline int lengthNames() const { return lengthNames_; }
00717 #ifndef CLP_NO_STD
00719 inline void setLengthNames(int value) { lengthNames_=value; }
00721 inline const std::vector<std::string> * rowNames() const {
00722 return &rowNames_;
00723 }
00724 inline const std::string& rowName(int iRow) const {
00725 return rowNames_[iRow];
00726 }
00728 std::string getRowName(int iRow) const;
00730 inline const std::vector<std::string> * columnNames() const {
00731 return &columnNames_;
00732 }
00733 inline const std::string& columnName(int iColumn) const {
00734 return columnNames_[iColumn];
00735 }
00737 std::string getColumnName(int iColumn) const;
00738 #endif
00740 inline ClpObjective * objectiveAsObject() const
00741 { return objective_;}
00742 void setObjective(ClpObjective * objective);
00743 inline void setObjectivePointer(ClpObjective * objective)
00744 { objective_ = objective;}
00747 int emptyProblem(int * infeasNumber=NULL, double * infeasSum=NULL,bool printMessage=true);
00748
00750
00759 void times(double scalar,
00760 const double * x, double * y) const;
00764 void transposeTimes(double scalar,
00765 const double * x, double * y) const ;
00767
00768
00769
00787
00788 bool setIntParam(ClpIntParam key, int value) ;
00790 bool setDblParam(ClpDblParam key, double value) ;
00791 #ifndef CLP_NO_STD
00793 bool setStrParam(ClpStrParam key, const std::string & value);
00794 #endif
00795
00796 inline bool getIntParam(ClpIntParam key, int& value) const {
00797 if (key<ClpLastIntParam) {
00798 value = intParam_[key];
00799 return true;
00800 } else {
00801 return false;
00802 }
00803 }
00804
00805 inline bool getDblParam(ClpDblParam key, double& value) const {
00806 if (key<ClpLastDblParam) {
00807 value = dblParam_[key];
00808 return true;
00809 } else {
00810 return false;
00811 }
00812 }
00813 #ifndef CLP_NO_STD
00814
00815 inline bool getStrParam(ClpStrParam key, std::string& value) const {
00816 if (key<ClpLastStrParam) {
00817 value = strParam_[key];
00818 return true;
00819 } else {
00820 return false;
00821 }
00822 }
00823 #endif
00825 void generateCpp( FILE * fp);
00826
00857 #define COIN_CBC_USING_CLP 0x01000000
00858 inline unsigned int specialOptions() const
00859 { return specialOptions_;}
00860 void setSpecialOptions(unsigned int value);
00861 inline bool inCbcBranchAndBound() const
00862 { return (specialOptions_&COIN_CBC_USING_CLP)!=0;}
00864
00867 protected:
00869 void gutsOfDelete(int type);
00873 void gutsOfCopy(const ClpModel & rhs, int trueCopy=1);
00875 void getRowBound(int iRow, double& lower, double& upper) const;
00877 void gutsOfLoadModel ( int numberRows, int numberColumns,
00878 const double* collb, const double* colub,
00879 const double* obj,
00880 const double* rowlb, const double* rowub,
00881 const double * rowObjective=NULL);
00883 void gutsOfScaling();
00885 inline double rawObjectiveValue() const {
00886 return objectiveValue_;
00887 }
00889 inline bool permanentArrays() const
00890 { return (specialOptions_&65536)!=0;}
00892 void startPermanentArrays();
00894 void stopPermanentArrays();
00896 const char * const * rowNamesAsChar() const;
00898 const char * const * columnNamesAsChar() const;
00900 void deleteNamesAsChar(const char * const * names,int number) const;
00902 void onStopped();
00904
00905
00907 protected:
00908
00911
00912 double optimizationDirection_;
00914 double dblParam_[ClpLastDblParam];
00916 double objectiveValue_;
00918 double smallElement_;
00920 double objectiveScale_;
00922 double rhsScale_;
00924 int numberRows_;
00926 int numberColumns_;
00928 double * rowActivity_;
00930 double * columnActivity_;
00932 double * dual_;
00934 double * reducedCost_;
00936 double* rowLower_;
00938 double* rowUpper_;
00940 ClpObjective * objective_;
00942 double * rowObjective_;
00944 double * columnLower_;
00946 double * columnUpper_;
00948 ClpMatrixBase * matrix_;
00950 ClpMatrixBase * rowCopy_;
00952 ClpPackedMatrix * scaledMatrix_;
00954 double * ray_;
00956 double * rowScale_;
00958 double * columnScale_;
00960 double * inverseRowScale_;
00962 double * inverseColumnScale_;
00964 int scalingFlag_;
00972 unsigned char * status_;
00974 char * integerType_;
00976 void * userPointer_;
00978 int intParam_[ClpLastIntParam];
00980 int numberIterations_;
00982 int solveType_;
00998 unsigned int whatsChanged_;
01000 int problemStatus_;
01002 int secondaryStatus_;
01004 int lengthNames_;
01006 int numberThreads_;
01010 unsigned int specialOptions_;
01012 CoinMessageHandler * handler_;
01014 bool defaultHandler_;
01016 CoinThreadRandom randomNumberGenerator_;
01018 ClpEventHandler * eventHandler_;
01019 #ifndef CLP_NO_STD
01021 std::vector<std::string> rowNames_;
01023 std::vector<std::string> columnNames_;
01024 #endif
01026 CoinMessages messages_;
01028 CoinMessages coinMessages_;
01030 int maximumColumns_;
01032 int maximumRows_;
01034 int maximumInternalColumns_;
01036 int maximumInternalRows_;
01038 CoinPackedMatrix baseMatrix_;
01040 CoinPackedMatrix baseRowCopy_;
01042 double * savedRowScale_;
01044 double * savedColumnScale_;
01045 #ifndef CLP_NO_STD
01047 std::string strParam_[ClpLastStrParam];
01048 #endif
01049
01050 };
01053 class ClpDataSave {
01054
01055 public:
01059
01060 ClpDataSave ( );
01061
01063 ClpDataSave(const ClpDataSave &);
01065 ClpDataSave & operator=(const ClpDataSave & rhs);
01067 ~ClpDataSave ( );
01068
01070
01072 public:
01073
01076 double dualBound_;
01077 double infeasibilityCost_;
01078 double pivotTolerance_;
01079 double acceptablePivot_;
01080 double objectiveScale_;
01081 int sparseThreshold_;
01082 int perturbation_;
01083 int forceFactorization_;
01084 int scalingFlag_;
01085 unsigned int specialOptions_;
01087 };
01088
01089 #endif