00001
00002
00003 #ifndef OsiSolverInterface_H
00004 #define OsiSolverInterface_H
00005
00006 #include <string>
00007 #include <vector>
00008
00009 #include "CoinMessageHandler.hpp"
00010 #include "CoinPackedVectorBase.hpp"
00011
00012 #include "OsiCollections.hpp"
00013 #include "OsiSolverParameters.hpp"
00014
00015 class CoinPackedMatrix;
00016 class CoinWarmStart;
00017
00018 class OsiCuts;
00019 class OsiRowCut;
00020 class OsiRowCutDebugger;
00021
00022
00023
00047 class OsiSolverInterface {
00048 friend void OsiSolverInterfaceCommonUnitTest(
00049 const OsiSolverInterface* emptySi,
00050 const std::string & mpsDir,
00051 const std::string & netlibDir);
00052 friend void OsiSolverInterfaceMpsUnitTest(
00053 const std::vector<OsiSolverInterface*> & vecSiP,
00054 const std::string & mpsDir);
00055
00056 public:
00058 class ApplyCutsReturnCode {
00059 friend class OsiSolverInterface;
00060 friend class OsiOslSolverInterface;
00061
00062 public:
00064
00065
00066 ApplyCutsReturnCode():
00067 intInconsistent_(0),
00068 extInconsistent_(0),
00069 infeasible_(0),
00070 ineffective_(0),
00071 applied_(0) {}
00073 ApplyCutsReturnCode(const ApplyCutsReturnCode & rhs):
00074 intInconsistent_(rhs.intInconsistent_),
00075 extInconsistent_(rhs.extInconsistent_),
00076 infeasible_(rhs.infeasible_),
00077 ineffective_(rhs.ineffective_),
00078 applied_(rhs.applied_) {}
00080 ApplyCutsReturnCode & operator=(const ApplyCutsReturnCode& rhs)
00081 {
00082 if (this != &rhs) {
00083 intInconsistent_ = rhs.intInconsistent_;
00084 extInconsistent_ = rhs.extInconsistent_;
00085 infeasible_ = rhs.infeasible_;
00086 ineffective_ = rhs.ineffective_;
00087 applied_ = rhs.applied_;
00088 }
00089 return *this;
00090 }
00092 ~ApplyCutsReturnCode(){}
00094
00097
00098 inline int getNumInconsistent(){return intInconsistent_;}
00100 inline int getNumInconsistentWrtIntegerModel(){return extInconsistent_;}
00102 inline int getNumInfeasible(){return infeasible_;}
00104 inline int getNumIneffective(){return ineffective_;}
00106 inline int getNumApplied(){return applied_;}
00108
00109 private:
00112
00113 inline void incrementInternallyInconsistent(){intInconsistent_++;}
00115 inline void incrementExternallyInconsistent(){extInconsistent_++;}
00117 inline void incrementInfeasible(){infeasible_++;}
00119 inline void incrementIneffective(){ineffective_++;}
00121 inline void incrementApplied(){applied_++;}
00123
00125
00126
00127 int intInconsistent_;
00129 int extInconsistent_;
00131 int infeasible_;
00133 int ineffective_;
00135 int applied_;
00137 };
00138
00139
00140
00141 public:
00143
00144
00145 virtual void initialSolve() = 0;
00146
00148 virtual void resolve() = 0;
00149
00151 virtual void branchAndBound() = 0;
00153
00154
00211
00212 virtual bool setIntParam(OsiIntParam key, int value) {
00213 if (key == OsiLastIntParam) return (false) ;
00214 intParam_[key] = value;
00215 return true;
00216 }
00217
00218 virtual bool setDblParam(OsiDblParam key, double value) {
00219 if (key == OsiLastDblParam) return (false) ;
00220 dblParam_[key] = value;
00221 return true;
00222 }
00223
00224 virtual bool setStrParam(OsiStrParam key, const std::string & value) {
00225 if (key == OsiLastStrParam) return (false) ;
00226 strParam_[key] = value;
00227 return true;
00228 }
00229
00230 virtual bool setHintParam(OsiHintParam key, bool yesNo=true,
00231 OsiHintStrength strength=OsiHintTry,
00232 void * otherInformation=NULL) {
00233 if (key==OsiLastHintParam)
00234 return false;
00235 hintParam_[key] = yesNo;
00236 hintStrength_[key] = strength;
00237 if (strength == OsiForceDo)
00238 throw CoinError("OsiForceDo illegal",
00239 "setHintParam", "OsiSolverInterface");
00240 return true;
00241 }
00242
00243 virtual bool getIntParam(OsiIntParam key, int& value) const {
00244 if (key == OsiLastIntParam) return (false) ;
00245 value = intParam_[key];
00246 return true;
00247 }
00248
00249 virtual bool getDblParam(OsiDblParam key, double& value) const {
00250 if (key == OsiLastDblParam) return (false) ;
00251 value = dblParam_[key];
00252 return true;
00253 }
00254
00255 virtual bool getStrParam(OsiStrParam key, std::string& value) const {
00256 if (key == OsiLastStrParam) return (false) ;
00257 value = strParam_[key];
00258 return true;
00259 }
00260
00261 virtual bool getHintParam(OsiHintParam key, bool& yesNo,
00262 OsiHintStrength& strength,
00263 void *& otherInformation) const {
00264 if (key==OsiLastHintParam)
00265 return false;
00266 yesNo = hintParam_[key];
00267 strength = hintStrength_[key];
00268 otherInformation=NULL;
00269 return true;
00270 }
00271
00272 virtual bool getHintParam(OsiHintParam key, bool& yesNo,
00273 OsiHintStrength& strength) const {
00274 if (key==OsiLastHintParam)
00275 return false;
00276 yesNo = hintParam_[key];
00277 strength = hintStrength_[key];
00278 return true;
00279 }
00280
00281 virtual bool getHintParam(OsiHintParam key, bool& yesNo) const {
00282 if (key==OsiLastHintParam)
00283 return false;
00284 yesNo = hintParam_[key];
00285 return true;
00286 }
00287
00288 void copyParameters(OsiSolverInterface & rhs);
00290
00291
00293
00294
00295 virtual bool isAbandoned() const = 0;
00297 virtual bool isProvenOptimal() const = 0;
00299 virtual bool isProvenPrimalInfeasible() const = 0;
00301 virtual bool isProvenDualInfeasible() const = 0;
00303 virtual bool isPrimalObjectiveLimitReached() const = 0;
00305 virtual bool isDualObjectiveLimitReached() const = 0;
00307 virtual bool isIterationLimitReached() const = 0;
00309
00310
00320 virtual CoinWarmStart *getEmptyWarmStart () const = 0 ;
00321
00327 virtual CoinWarmStart* getWarmStart() const = 0;
00328
00333 virtual bool setWarmStart(const CoinWarmStart* warmstart) = 0;
00335
00336
00357
00358 virtual void markHotStart();
00360 virtual void solveFromHotStart();
00362 virtual void unmarkHotStart();
00364
00365
00376
00377 virtual int getNumCols() const = 0;
00378
00380 virtual int getNumRows() const = 0;
00381
00383 virtual int getNumElements() const = 0;
00384
00386 virtual const double * getColLower() const = 0;
00387
00389 virtual const double * getColUpper() const = 0;
00390
00400 virtual const char * getRowSense() const = 0;
00401
00414 virtual const double * getRightHandSide() const = 0;
00415
00424 virtual const double * getRowRange() const = 0;
00425
00427 virtual const double * getRowLower() const = 0;
00428
00430 virtual const double * getRowUpper() const = 0;
00431
00433 virtual const double * getObjCoefficients() const = 0;
00434
00436 virtual double getObjSense() const = 0;
00437
00439 virtual bool isContinuous(int colIndex) const = 0;
00440
00442 virtual bool isBinary(int colIndex) const;
00443
00448 virtual bool isInteger(int colIndex) const;
00449
00451 virtual bool isIntegerNonBinary(int colIndex) const;
00452
00454 virtual bool isFreeBinary(int colIndex) const;
00455
00457 virtual const CoinPackedMatrix * getMatrixByRow() const = 0;
00458
00460 virtual const CoinPackedMatrix * getMatrixByCol() const = 0;
00461
00463 virtual double getInfinity() const = 0;
00465
00468
00469 virtual const double * getColSolution() const = 0;
00470
00472 virtual const double * getRowPrice() const = 0;
00473
00475 virtual const double * getReducedCost() const = 0;
00476
00479 virtual const double * getRowActivity() const = 0;
00480
00482 virtual double getObjValue() const = 0;
00483
00486 virtual int getIterationCount() const = 0;
00487
00501 virtual std::vector<double*> getDualRays(int maxNumRays) const = 0;
00513 virtual std::vector<double*> getPrimalRays(int maxNumRays) const = 0;
00514
00517 virtual OsiVectorInt getFractionalIndices(const double etol=1.e-05)
00518 const;
00520
00521
00534 virtual void setObjCoeff( int elementIndex, double elementValue ) = 0;
00535
00537 virtual void setObjCoeffSet(const int* indexFirst,
00538 const int* indexLast,
00539 const double* coeffList);
00540
00543 virtual void setColLower( int elementIndex, double elementValue ) = 0;
00544
00547 virtual void setColUpper( int elementIndex, double elementValue ) = 0;
00548
00552 virtual void setColBounds( int elementIndex,
00553 double lower, double upper ) {
00554 setColLower(elementIndex, lower);
00555 setColUpper(elementIndex, upper);
00556 }
00557
00564 virtual void setColSetBounds(const int* indexFirst,
00565 const int* indexLast,
00566 const double* boundList);
00567
00570 virtual void setRowLower( int elementIndex, double elementValue ) = 0;
00571
00574 virtual void setRowUpper( int elementIndex, double elementValue ) = 0;
00575
00579 virtual void setRowBounds( int elementIndex,
00580 double lower, double upper ) {
00581 setRowLower(elementIndex, lower);
00582 setRowUpper(elementIndex, upper);
00583 }
00584
00586 virtual void setRowType(int index, char sense, double rightHandSide,
00587 double range) = 0;
00588
00593 virtual void setRowSetBounds(const int* indexFirst,
00594 const int* indexLast,
00595 const double* boundList);
00596
00601 virtual void setRowSetTypes(const int* indexFirst,
00602 const int* indexLast,
00603 const char* senseList,
00604 const double* rhsList,
00605 const double* rangeList);
00606
00609 virtual void setObjSense(double s) = 0;
00610
00620 virtual void setColSolution(const double *colsol) = 0;
00621
00632 virtual void setRowPrice(const double * rowprice) = 0;
00633
00635
00636
00640 virtual void setContinuous(int index) = 0;
00642 virtual void setInteger(int index) = 0;
00645 virtual void setContinuous(const int* indices, int len);
00648 virtual void setInteger(const int* indices, int len);
00650
00651
00652
00660 virtual void addCol(const CoinPackedVectorBase& vec,
00661 const double collb, const double colub,
00662 const double obj) = 0;
00668 virtual void addCols(const int numcols,
00669 const CoinPackedVectorBase * const * cols,
00670 const double* collb, const double* colub,
00671 const double* obj);
00672 #if 0
00673
00674 virtual void addCols(const CoinPackedMatrix& matrix,
00675 const double* collb, const double* colub,
00676 const double* obj);
00677 #endif
00678
00679 virtual void deleteCols(const int num, const int * colIndices) = 0;
00680
00682 virtual void addRow(const CoinPackedVectorBase& vec,
00683 const double rowlb, const double rowub) = 0;
00685 virtual void addRow(const CoinPackedVectorBase& vec,
00686 const char rowsen, const double rowrhs,
00687 const double rowrng) = 0;
00693 virtual void addRows(const int numrows,
00694 const CoinPackedVectorBase * const * rows,
00695 const double* rowlb, const double* rowub);
00701 virtual void addRows(const int numrows,
00702 const CoinPackedVectorBase * const * rows,
00703 const char* rowsen, const double* rowrhs,
00704 const double* rowrng);
00705 #if 0
00706
00707 virtual void addRows(const CoinPackedMatrix& matrix,
00708 const double* rowlb, const double* rowub);
00710 virtual void addRows(const CoinPackedMatrix& matrix,
00711 const char* rowsen, const double* rowrhs,
00712 const double* rowrng);
00713 #endif
00714
00715 virtual void deleteRows(const int num, const int * rowIndices) = 0;
00716
00717
00740 virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs,
00741 double effectivenessLb = 0.0);
00746 virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts);
00748
00749
00750
00764 virtual void loadProblem(const CoinPackedMatrix& matrix,
00765 const double* collb, const double* colub,
00766 const double* obj,
00767 const double* rowlb, const double* rowub) = 0;
00768
00778 virtual void assignProblem(CoinPackedMatrix*& matrix,
00779 double*& collb, double*& colub, double*& obj,
00780 double*& rowlb, double*& rowub) = 0;
00781
00794 virtual void loadProblem(const CoinPackedMatrix& matrix,
00795 const double* collb, const double* colub,
00796 const double* obj,
00797 const char* rowsen, const double* rowrhs,
00798 const double* rowrng) = 0;
00799
00809 virtual void assignProblem(CoinPackedMatrix*& matrix,
00810 double*& collb, double*& colub, double*& obj,
00811 char*& rowsen, double*& rowrhs,
00812 double*& rowrng) = 0;
00813
00816 virtual void loadProblem(const int numcols, const int numrows,
00817 const int* start, const int* index,
00818 const double* value,
00819 const double* collb, const double* colub,
00820 const double* obj,
00821 const double* rowlb, const double* rowub) = 0;
00822
00825 virtual void loadProblem(const int numcols, const int numrows,
00826 const int* start, const int* index,
00827 const double* value,
00828 const double* collb, const double* colub,
00829 const double* obj,
00830 const char* rowsen, const double* rowrhs,
00831 const double* rowrng) = 0;
00832
00838 virtual int readMps(const char *filename,
00839 const char *extension = "mps") ;
00840
00847 virtual void writeMps(const char *filename,
00848 const char *extension = "mps",
00849 double objSense=0.0) const = 0;
00850
00863 int writeMpsNative(const char *filename,
00864 const char ** rowNames, const char ** columnNames,
00865 int formatType=0,int numberAcross=2,
00866 double objSense=0.0) const ;
00868
00869
00870
00880 void setApplicationData (void * appData);
00881
00883 void * getApplicationData() const;
00885
00886
00900 void passInMessageHandler(CoinMessageHandler * handler);
00902 void newLanguage(CoinMessages::Language language);
00903 void setLanguage(CoinMessages::Language language)
00904 {newLanguage(language);};
00906 CoinMessageHandler * messageHandler() const
00907 {return handler_;};
00909 CoinMessages messages()
00910 {return messages_;};
00912 CoinMessages * messagesPointer()
00913 {return &messages_;};
00915
00916
00925 virtual void activateRowCutDebugger (const char * modelName);
00926
00936 const OsiRowCutDebugger * getRowCutDebugger() const;
00938
00939
00940
00942
00943
00944 OsiSolverInterface();
00945
00951 virtual OsiSolverInterface * clone(bool copyData = true) const = 0;
00952
00954 OsiSolverInterface(const OsiSolverInterface &);
00955
00957 OsiSolverInterface & operator=(const OsiSolverInterface& rhs);
00958
00960 virtual ~OsiSolverInterface ();
00961
00968 virtual void reset();
00970
00971
00972
00973 protected:
00975
00976
00977 virtual void applyRowCut( const OsiRowCut & rc ) = 0;
00978
00980 virtual void applyColCut( const OsiColCut & cc ) = 0;
00981
00984 inline void
00985 convertBoundToSense(const double lower, const double upper,
00986 char& sense, double& right, double& range) const;
00989 inline void
00990 convertSenseToBound(const char sense, const double right,
00991 const double range,
00992 double& lower, double& upper) const;
00995 template <class T> inline T
00996 forceIntoRange(const T value, const T lower, const T upper) const {
00997 return value < lower ? lower : (value > upper ? upper : value);
00998 }
01005 void setInitialData();
01007
01009
01010
01011 OsiRowCutDebugger * rowCutDebugger_;
01013
01014
01015
01016 private:
01018
01019
01020 void * appData_;
01022 int intParam_[OsiLastIntParam];
01024 double dblParam_[OsiLastDblParam];
01026 std::string strParam_[OsiLastStrParam];
01028 bool hintParam_[OsiLastHintParam];
01030 OsiHintStrength hintStrength_[OsiLastHintParam];
01033 CoinWarmStart* ws_;
01034
01035 protected:
01037 CoinMessageHandler * handler_;
01043 bool defaultHandler_;
01045 CoinMessages messages_;
01047 };
01048
01049
01057 void
01058 OsiSolverInterfaceCommonUnitTest(
01059 const OsiSolverInterface* emptySi,
01060 const std::string & mpsDir,
01061 const std::string & netlibDir);
01062
01063
01066 void
01067 OsiSolverInterfaceMpsUnitTest(
01068 const std::vector<OsiSolverInterface*> & vecSiP,
01069 const std::string & mpsDir);
01070
01071
01074 inline void
01075 OsiSolverInterface::convertBoundToSense(const double lower, const double upper,
01076 char& sense, double& right,
01077 double& range) const
01078 {
01079 double inf = getInfinity();
01080 range = 0.0;
01081 if (lower > -inf) {
01082 if (upper < inf) {
01083 right = upper;
01084 if (upper==lower) {
01085 sense = 'E';
01086 } else {
01087 sense = 'R';
01088 range = upper - lower;
01089 }
01090 } else {
01091 sense = 'G';
01092 right = lower;
01093 }
01094 } else {
01095 if (upper < inf) {
01096 sense = 'L';
01097 right = upper;
01098 } else {
01099 sense = 'N';
01100 right = 0.0;
01101 }
01102 }
01103 }
01104
01105
01108 inline void
01109 OsiSolverInterface::convertSenseToBound(const char sense, const double right,
01110 const double range,
01111 double& lower, double& upper) const
01112 {
01113 double inf=getInfinity();
01114 switch (sense) {
01115 case 'E':
01116 lower = upper = right;
01117 break;
01118 case 'L':
01119 lower = -inf;
01120 upper = right;
01121 break;
01122 case 'G':
01123 lower = right;
01124 upper = inf;
01125 break;
01126 case 'R':
01127 lower = right - range;
01128 upper = right;
01129 break;
01130 case 'N':
01131 lower = -inf;
01132 upper = inf;
01133 break;
01134 }
01135 }
01136
01137 #endif