00001
00002
00003 #ifndef ClpModel_H
00004 #define ClpModel_H
00005
00006 #include <iostream>
00007 #include <cassert>
00008 #include <cmath>
00009 #include <vector>
00010 #include <string>
00011 #ifndef COIN_USE_CLP
00012 #define COIN_USE_CLP
00013 #endif
00014 #include "ClpPackedMatrix.hpp"
00015 #include "CoinMessageHandler.hpp"
00016 #include "ClpParameters.hpp"
00017 #include "ClpObjective.hpp"
00018 class ClpEventHandler;
00019
00020
00021 #ifndef COIN_DBL_MAX
00022 #define COIN_DBL_MAX DBL_MAX
00023 #endif
00024
00034 class CoinBuild;
00035 class CoinModel;
00036 class ClpModel {
00037
00038 public:
00039
00045
00046 ClpModel ( );
00047
00052 ClpModel(const ClpModel & rhs, int scalingMode=-1);
00054 ClpModel & operator=(const ClpModel & rhs);
00059 ClpModel (const ClpModel * wholeModel,
00060 int numberRows, const int * whichRows,
00061 int numberColumns, const int * whichColumns,
00062 bool dropNames=true, bool dropIntegers=true);
00064 ~ClpModel ( );
00066
00080 void loadProblem ( const ClpMatrixBase& matrix,
00081 const double* collb, const double* colub,
00082 const double* obj,
00083 const double* rowlb, const double* rowub,
00084 const double * rowObjective=NULL);
00085 void loadProblem ( const CoinPackedMatrix& matrix,
00086 const double* collb, const double* colub,
00087 const double* obj,
00088 const double* rowlb, const double* rowub,
00089 const double * rowObjective=NULL);
00090
00093 void loadProblem ( const int numcols, const int numrows,
00094 const CoinBigIndex* start, const int* index,
00095 const double* value,
00096 const double* collb, const double* colub,
00097 const double* obj,
00098 const double* rowlb, const double* rowub,
00099 const double * rowObjective=NULL);
00105 int loadProblem ( CoinModel & modelObject,bool tryPlusMinusOne=false);
00107 void loadProblem ( const int numcols, const int numrows,
00108 const CoinBigIndex* start, const int* index,
00109 const double* value,const int * length,
00110 const double* collb, const double* colub,
00111 const double* obj,
00112 const double* rowlb, const double* rowub,
00113 const double * rowObjective=NULL);
00115 void loadQuadraticObjective(const int numberColumns,
00116 const CoinBigIndex * start,
00117 const int * column, const double * element);
00118 void loadQuadraticObjective ( const CoinPackedMatrix& matrix);
00120 void deleteQuadraticObjective();
00122 void setRowObjective(const double * rowObjective);
00124 int readMps(const char *filename,
00125 bool keepNames=false,
00126 bool ignoreErrors = false);
00128 int readGMPL(const char *filename,const char * dataName,
00129 bool keepNames=false);
00131 void copyInIntegerInformation(const char * information);
00133 void deleteIntegerInformation();
00135 void setContinuous(int index);
00137 void setInteger(int index);
00139 bool isInteger(int index) const;
00141 void resize (int newNumberRows, int newNumberColumns);
00143 void deleteRows(int number, const int * which);
00145 void addRow(int numberInRow, const int * columns,
00146 const double * elements, double rowLower=-COIN_DBL_MAX,
00147 double rowUpper=COIN_DBL_MAX);
00149 void addRows(int number, const double * rowLower,
00150 const double * rowUpper,
00151 const CoinBigIndex * rowStarts, const int * columns,
00152 const double * elements);
00154 void addRows(int number, const double * rowLower,
00155 const double * rowUpper,
00156 const CoinBigIndex * rowStarts, const int * rowLengths,
00157 const int * columns,
00158 const double * elements);
00159 #ifndef CLP_NO_VECTOR
00160 void addRows(int number, const double * rowLower,
00161 const double * rowUpper,
00162 const CoinPackedVectorBase * const * rows);
00163 #endif
00164
00169 int addRows(const CoinBuild & buildObject,bool tryPlusMinusOne=false,
00170 bool checkDuplicates=true);
00179 int addRows(CoinModel & modelObject,bool tryPlusMinusOne=false,
00180 bool checkDuplicates=true);
00181
00183 void deleteColumns(int number, const int * which);
00185 void addColumn(int numberInColumn,
00186 const int * rows,
00187 const double * elements,
00188 double columnLower=0.0,
00189 double columnUpper=COIN_DBL_MAX,
00190 double objective=0.0);
00192 void addColumns(int number, const double * columnLower,
00193 const double * columnUpper,
00194 const double * objective,
00195 const CoinBigIndex * columnStarts, const int * rows,
00196 const double * elements);
00197 void addColumns(int number, const double * columnLower,
00198 const double * columnUpper,
00199 const double * objective,
00200 const CoinBigIndex * columnStarts, const int * columnLengths,
00201 const int * rows,
00202 const double * elements);
00203 #ifndef CLP_NO_VECTOR
00204 void addColumns(int number, const double * columnLower,
00205 const double * columnUpper,
00206 const double * objective,
00207 const CoinPackedVectorBase * const * columns);
00208 #endif
00209
00214 int addColumns(const CoinBuild & buildObject,bool tryPlusMinusOne=false,
00215 bool checkDuplicates=true);
00223 int addColumns(CoinModel & modelObject,bool tryPlusMinusOne=false,
00224 bool checkDuplicates=true);
00226 inline void modifyCoefficient(int row, int column, double newElement,
00227 bool keepZero=false)
00228 {matrix_->modifyCoefficient(row,column,newElement,keepZero);}
00230 void chgRowLower(const double * rowLower);
00232 void chgRowUpper(const double * rowUpper);
00234 void chgColumnLower(const double * columnLower);
00236 void chgColumnUpper(const double * columnUpper);
00238 void chgObjCoefficients(const double * objIn);
00242 void borrowModel(ClpModel & otherModel);
00245 void returnModel(ClpModel & otherModel);
00246
00248 void createEmptyMatrix();
00249 #ifndef CLP_NO_STD
00250
00251 void dropNames();
00253 void copyNames(std::vector<std::string> & rowNames,
00254 std::vector<std::string> & columnNames);
00256 void copyRowNames(const std::vector<std::string> & rowNames,int first, int last);
00258 void copyColumnNames(const std::vector<std::string> & columnNames, int first, int last);
00260 void copyRowNames(const char * const * rowNames,int first, int last);
00262 void copyColumnNames(const char * const * columnNames, int first, int last);
00264 void setRowName(int rowIndex, std::string & name) ;
00266 void setColumnName(int colIndex, std::string & name) ;
00267 #endif
00268
00281 int writeMps(const char *filename,
00282 int formatType=0,int numberAcross=2,
00283 double objSense=0.0) const ;
00285
00287
00288 inline int numberRows() const {
00289 return numberRows_;
00290 }
00291 inline int getNumRows() const {
00292 return numberRows_;
00293 }
00295 inline int getNumCols() const {
00296 return numberColumns_;
00297 }
00298 inline int numberColumns() const {
00299 return numberColumns_;
00300 }
00302 inline double primalTolerance() const {
00303 return dblParam_[ClpPrimalTolerance];
00304 }
00305 void setPrimalTolerance( double value) ;
00307 inline double dualTolerance() const { return dblParam_[ClpDualTolerance]; }
00308 void setDualTolerance( double value) ;
00310 inline double primalObjectiveLimit() const { return dblParam_[ClpPrimalObjectiveLimit];}
00311 void setPrimalObjectiveLimit(double value);
00313 inline double dualObjectiveLimit() const { return dblParam_[ClpDualObjectiveLimit];}
00314 void setDualObjectiveLimit(double value);
00316 inline double objectiveOffset() const { return dblParam_[ClpObjOffset];}
00317 void setObjectiveOffset(double value);
00318 #ifndef CLP_NO_STD
00319 inline std::string problemName() const { return strParam_[ClpProbName]; };
00320 #endif
00321
00322 inline int numberIterations() const { return numberIterations_; }
00323 inline int getIterationCount() const { return numberIterations_; }
00324 inline void setNumberIterations(int numberIterations)
00325 { numberIterations_ = numberIterations;};
00327 inline int solveType() const
00328 { return solveType_;};
00329 inline void setSolveType(int type)
00330 { solveType_=type;};
00332 inline int maximumIterations() const { return intParam_[ClpMaxNumIteration]; }
00333 void setMaximumIterations(int value);
00335 inline double maximumSeconds() const { return dblParam_[ClpMaxSeconds]; }
00336 void setMaximumSeconds(double value);
00338 bool hitMaximumIterations() const;
00348 inline int status() const { return problemStatus_; }
00349 inline int problemStatus() const { return problemStatus_; }
00351 inline void setProblemStatus(int problemStatus)
00352 { problemStatus_ = problemStatus;};
00365 inline int secondaryStatus() const { return secondaryStatus_; }
00366 inline void setSecondaryStatus(int status)
00367 { secondaryStatus_ = status;};
00369 inline bool isAbandoned() const { return problemStatus_==4; }
00371 inline bool isProvenOptimal() const { return problemStatus_==0; }
00373 inline bool isProvenPrimalInfeasible() const { return problemStatus_==1; }
00375 inline bool isProvenDualInfeasible() const { return problemStatus_==2; }
00377 bool isPrimalObjectiveLimitReached() const ;
00379 bool isDualObjectiveLimitReached() const ;
00381 inline bool isIterationLimitReached() const { return problemStatus_==3; }
00383 inline double optimizationDirection() const {
00384 return optimizationDirection_;
00385 }
00386 inline double getObjSense() const { return optimizationDirection_; }
00387 void setOptimizationDirection(double value);
00389 inline double * primalRowSolution() const { return rowActivity_; }
00390 inline const double * getRowActivity() const { return rowActivity_; }
00392 inline double * primalColumnSolution() const { return columnActivity_; }
00393 inline const double * getColSolution() const { return columnActivity_; }
00394 inline void setColSolution(const double * input)
00395 { memcpy(columnActivity_,input,numberColumns_*sizeof(double));};
00397 inline double * dualRowSolution() const { return dual_; }
00398 inline const double * getRowPrice() const { return dual_; }
00400 inline double * dualColumnSolution() const { return reducedCost_; }
00401 inline const double * getReducedCost() const { return reducedCost_; }
00403 inline double* rowLower() const { return rowLower_; }
00404 inline const double* getRowLower() const { return rowLower_; }
00406 inline double* rowUpper() const { return rowUpper_; }
00407 inline const double* getRowUpper() const { return rowUpper_; }
00408
00412 void setObjectiveCoefficient( int elementIndex, double elementValue );
00414 inline void setObjCoeff( int elementIndex, double elementValue )
00415 { setObjectiveCoefficient( elementIndex, elementValue);};
00416
00419 void setColumnLower( int elementIndex, double elementValue );
00420
00423 void setColumnUpper( int elementIndex, double elementValue );
00424
00426 void setColumnBounds( int elementIndex,
00427 double lower, double upper );
00428
00437 void setColumnSetBounds(const int* indexFirst,
00438 const int* indexLast,
00439 const double* boundList);
00440
00443 inline void setColLower( int elementIndex, double elementValue )
00444 { setColumnLower(elementIndex, elementValue);};
00447 inline void setColUpper( int elementIndex, double elementValue )
00448 { setColumnUpper(elementIndex, elementValue);};
00449
00451 inline void setColBounds( int elementIndex,
00452 double lower, double upper )
00453 { setColumnBounds(elementIndex, lower, upper);};
00454
00461 inline void setColSetBounds(const int* indexFirst,
00462 const int* indexLast,
00463 const double* boundList)
00464 { setColumnSetBounds(indexFirst, indexLast, boundList);};
00465
00468 void setRowLower( int elementIndex, double elementValue );
00469
00472 void setRowUpper( int elementIndex, double elementValue ) ;
00473
00475 void setRowBounds( int elementIndex,
00476 double lower, double upper ) ;
00477
00484 void setRowSetBounds(const int* indexFirst,
00485 const int* indexLast,
00486 const double* boundList);
00487
00489
00490 inline const double * rowScale() const {return rowScale_;};
00491 inline const double * columnScale() const {return columnScale_;};
00492 inline void setRowScale(double * scale) { delete [] (double *) rowScale_; rowScale_ = scale;};
00493 inline void setColumnScale(double * scale) { delete [] (double *) columnScale_; columnScale_ = scale;};
00495 inline double objectiveScale() const
00496 { return objectiveScale_;} ;
00497 inline void setObjectiveScale(double value)
00498 { objectiveScale_ = value;} ;
00500 inline double rhsScale() const
00501 { return rhsScale_;} ;
00502 inline void setRhsScale(double value)
00503 { rhsScale_ = value;} ;
00505 void scaling(int mode=1);
00508 void unscale();
00510 inline int scalingFlag() const {return scalingFlag_;};
00512 inline double * objective() const
00513 {
00514 if (objective_) {
00515 double offset;
00516 return objective_->gradient(NULL,NULL,offset,false);
00517 } else {
00518 return NULL;
00519 }
00520 }
00521 inline double * objective(const double * solution, double & offset,bool refresh=true) const
00522 {
00523 offset=0.0;
00524 if (objective_) {
00525 return objective_->gradient(NULL,solution,offset,refresh);
00526 } else {
00527 return NULL;
00528 }
00529 }
00530 inline const double * getObjCoefficients() const
00531 {
00532 if (objective_) {
00533 double offset;
00534 return objective_->gradient(NULL,NULL,offset,false);
00535 } else {
00536 return NULL;
00537 }
00538 }
00540 inline double * rowObjective() const { return rowObjective_; }
00541 inline const double * getRowObjCoefficients() const {
00542 return rowObjective_;
00543 }
00545 inline double * columnLower() const { return columnLower_; }
00546 inline const double * getColLower() const { return columnLower_; }
00548 inline double * columnUpper() const { return columnUpper_; }
00549 inline const double * getColUpper() const { return columnUpper_; }
00551 inline CoinPackedMatrix * matrix() const {
00552 if ( matrix_ == NULL ) return NULL;
00553 else return matrix_->getPackedMatrix();
00554 }
00556 inline int getNumElements() const
00557 { return matrix_->getNumElements();};
00560 inline double getSmallElementValue() const
00561 { return smallElement_;};
00562 inline void setSmallElementValue(double value)
00563 { smallElement_=value;};
00565 inline ClpMatrixBase * rowCopy() const { return rowCopy_; }
00567 inline ClpMatrixBase * clpMatrix() const { return matrix_; }
00573 void replaceMatrix(ClpMatrixBase * matrix,bool deleteCurrent=false);
00579 inline void replaceMatrix(CoinPackedMatrix * matrix,
00580 bool deleteCurrent=false)
00581 { replaceMatrix(new ClpPackedMatrix(matrix),deleteCurrent);};
00583 inline double objectiveValue() const {
00584 return objectiveValue_*optimizationDirection_ - dblParam_[ClpObjOffset];
00585 }
00586 inline void setObjectiveValue(double value) {
00587 objectiveValue_ = (value+ dblParam_[ClpObjOffset])/optimizationDirection_;
00588 }
00589 inline double getObjValue() const {
00590 return objectiveValue_*optimizationDirection_ - dblParam_[ClpObjOffset];
00591 }
00593 inline char * integerInformation() const { return integerType_; }
00596 double * infeasibilityRay() const;
00597 double * unboundedRay() const;
00599 inline bool statusExists() const
00600 { return (status_!=NULL);};
00602 inline unsigned char * statusArray() const
00603 { return status_;};
00606 unsigned char * statusCopy() const;
00608 void copyinStatus(const unsigned char * statusArray);
00609
00611 inline void setUserPointer (void * pointer)
00612 { userPointer_=pointer;};
00613 inline void * getUserPointer () const
00614 { return userPointer_;};
00616 inline int whatsChanged() const
00617 { return whatsChanged_;} ;
00618 inline void setWhatsChanged(int value)
00619 { whatsChanged_ = value;} ;
00621 inline int numberThreads() const
00622 { return numberThreads_;} ;
00623 inline void setNumberThreads(int value)
00624 { numberThreads_ = value;} ;
00626
00628
00629 void passInMessageHandler(CoinMessageHandler * handler);
00631 CoinMessageHandler * pushMessageHandler(CoinMessageHandler * handler,
00632 bool & oldDefault);
00634 void popMessageHandler(CoinMessageHandler * oldHandler,bool oldDefault);
00636 void newLanguage(CoinMessages::Language language);
00637 inline void setLanguage(CoinMessages::Language language) { newLanguage(language); }
00639 inline CoinMessageHandler * messageHandler() const { return handler_; }
00641 inline CoinMessages messages() const { return messages_; }
00643 inline CoinMessages * messagesPointer() { return & messages_; }
00645 inline CoinMessages coinMessages() const { return coinMessages_; }
00647 inline CoinMessages * coinMessagesPointer() { return & coinMessages_; }
00656 inline void setLogLevel(int value) { handler_->setLogLevel(value); }
00657 inline int logLevel() const { return handler_->logLevel(); }
00659 void passInEventHandler(const ClpEventHandler * eventHandler);
00661 inline ClpEventHandler * eventHandler() const
00662 { return eventHandler_;};
00664 inline int lengthNames() const { return lengthNames_; }
00665 #ifndef CLP_NO_STD
00666
00667 inline void setLengthNames(int value) { lengthNames_=value; }
00669 inline const std::vector<std::string> * rowNames() const {
00670 return &rowNames_;
00671 }
00672 inline const std::string& rowName(int iRow) const {
00673 return rowNames_[iRow];
00674 }
00676 std::string getRowName(int iRow) const;
00678 inline const std::vector<std::string> * columnNames() const {
00679 return &columnNames_;
00680 }
00681 inline const std::string& columnName(int iColumn) const {
00682 return columnNames_[iColumn];
00683 }
00685 std::string getColumnName(int iColumn) const;
00686 #endif
00687
00688 inline ClpObjective * objectiveAsObject() const
00689 { return objective_;};
00690 void setObjective(ClpObjective * objective);
00691 inline void setObjectivePointer(ClpObjective * objective)
00692 { objective_ = objective;};
00695 int emptyProblem(int * infeasNumber=NULL, double * infeasSum=NULL,bool printMessage=true);
00696
00698
00707 void times(double scalar,
00708 const double * x, double * y) const;
00712 void transposeTimes(double scalar,
00713 const double * x, double * y) const ;
00715
00716
00717
00735
00736 bool setIntParam(ClpIntParam key, int value) ;
00738 bool setDblParam(ClpDblParam key, double value) ;
00739 #ifndef CLP_NO_STD
00740
00741 bool setStrParam(ClpStrParam key, const std::string & value);
00742 #endif
00743
00744 inline bool getIntParam(ClpIntParam key, int& value) const {
00745 if (key!=ClpLastIntParam) {
00746 value = intParam_[key];
00747 return true;
00748 } else {
00749 return false;
00750 }
00751 }
00752
00753 inline bool getDblParam(ClpDblParam key, double& value) const {
00754 if (key!=ClpLastDblParam) {
00755 value = dblParam_[key];
00756 return true;
00757 } else {
00758 return false;
00759 }
00760 }
00761 #ifndef CLP_NO_STD
00762
00763 inline bool getStrParam(ClpStrParam key, std::string& value) const {
00764 if (key!=ClpLastStrParam) {
00765 value = strParam_[key];
00766 return true;
00767 } else {
00768 return false;
00769 }
00770 }
00771 #endif
00772
00773 void generateCpp( FILE * fp);
00775
00778 protected:
00780 void gutsOfDelete();
00783 void gutsOfCopy(const ClpModel & rhs, bool trueCopy=true);
00785 void getRowBound(int iRow, double& lower, double& upper) const;
00787 void gutsOfLoadModel ( int numberRows, int numberColumns,
00788 const double* collb, const double* colub,
00789 const double* obj,
00790 const double* rowlb, const double* rowub,
00791 const double * rowObjective=NULL);
00793 void gutsOfScaling();
00795 inline double rawObjectiveValue() const {
00796 return objectiveValue_;
00797 }
00799 const char * const * const rowNamesAsChar() const;
00801 const char * const * const columnNamesAsChar() const;
00803 void deleteNamesAsChar(const char * const * const names,int number) const;
00805
00806
00808 protected:
00809
00812
00813 double optimizationDirection_;
00815 double dblParam_[ClpLastDblParam];
00817 double objectiveValue_;
00819 double smallElement_;
00821 double objectiveScale_;
00823 double rhsScale_;
00825 int numberRows_;
00827 int numberColumns_;
00829 double * rowActivity_;
00831 double * columnActivity_;
00833 double * dual_;
00835 double * reducedCost_;
00837 double* rowLower_;
00839 double* rowUpper_;
00841 ClpObjective * objective_;
00843 double * rowObjective_;
00845 double * columnLower_;
00847 double * columnUpper_;
00849 ClpMatrixBase * matrix_;
00851 ClpMatrixBase * rowCopy_;
00853 double * ray_;
00855 double * rowScale_;
00857 double * columnScale_;
00859 int scalingFlag_;
00867 unsigned char * status_;
00869 char * integerType_;
00871 void * userPointer_;
00873 int intParam_[ClpLastIntParam];
00875 int numberIterations_;
00877 int solveType_;
00893 unsigned int whatsChanged_;
00895 int problemStatus_;
00897 int secondaryStatus_;
00899 int lengthNames_;
00901 int numberThreads_;
00903 CoinMessageHandler * handler_;
00905 bool defaultHandler_;
00907 ClpEventHandler * eventHandler_;
00908 #ifndef CLP_NO_STD
00909
00910 std::vector<std::string> rowNames_;
00912 std::vector<std::string> columnNames_;
00913 #endif
00914
00915 CoinMessages messages_;
00917 CoinMessages coinMessages_;
00918 #ifndef CLP_NO_STD
00919
00920 std::string strParam_[ClpLastStrParam];
00921 #endif
00922
00923 };
00926 class ClpDataSave {
00927
00928 public:
00932
00933 ClpDataSave ( );
00934
00936 ClpDataSave(const ClpDataSave &);
00938 ClpDataSave & operator=(const ClpDataSave & rhs);
00940 ~ClpDataSave ( );
00941
00943
00945 public:
00946
00949 double dualBound_;
00950 double infeasibilityCost_;
00951 double pivotTolerance_;
00952 double acceptablePivot_;
00953 double objectiveScale_;
00954 int sparseThreshold_;
00955 int perturbation_;
00956 int forceFactorization_;
00957 int scalingFlag_;
00959 };
00960
00961 #endif