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 OsiAuxInfo;
00020 class OsiRowCut;
00021 class OsiRowCutDebugger;
00022 class CoinSet;
00023 class CoinBuild;
00024 class CoinModel;
00025 class OsiSolverBranch;
00026 class OsiSolverResult;
00027 #include "CoinFinite.hpp"
00028
00029
00030
00054 class OsiSolverInterface {
00055 friend void OsiSolverInterfaceCommonUnitTest(
00056 const OsiSolverInterface* emptySi,
00057 const std::string & mpsDir,
00058 const std::string & netlibDir);
00059 friend void OsiSolverInterfaceMpsUnitTest(
00060 const std::vector<OsiSolverInterface*> & vecSiP,
00061 const std::string & mpsDir);
00062
00063 public:
00065 class ApplyCutsReturnCode {
00066 friend class OsiSolverInterface;
00067 friend class OsiOslSolverInterface;
00068
00069 public:
00071
00072
00073 ApplyCutsReturnCode():
00074 intInconsistent_(0),
00075 extInconsistent_(0),
00076 infeasible_(0),
00077 ineffective_(0),
00078 applied_(0) {}
00080 ApplyCutsReturnCode(const ApplyCutsReturnCode & rhs):
00081 intInconsistent_(rhs.intInconsistent_),
00082 extInconsistent_(rhs.extInconsistent_),
00083 infeasible_(rhs.infeasible_),
00084 ineffective_(rhs.ineffective_),
00085 applied_(rhs.applied_) {}
00087 ApplyCutsReturnCode & operator=(const ApplyCutsReturnCode& rhs)
00088 {
00089 if (this != &rhs) {
00090 intInconsistent_ = rhs.intInconsistent_;
00091 extInconsistent_ = rhs.extInconsistent_;
00092 infeasible_ = rhs.infeasible_;
00093 ineffective_ = rhs.ineffective_;
00094 applied_ = rhs.applied_;
00095 }
00096 return *this;
00097 }
00099 ~ApplyCutsReturnCode(){}
00101
00104
00105 inline int getNumInconsistent(){return intInconsistent_;}
00107 inline int getNumInconsistentWrtIntegerModel(){return extInconsistent_;}
00109 inline int getNumInfeasible(){return infeasible_;}
00111 inline int getNumIneffective(){return ineffective_;}
00113 inline int getNumApplied(){return applied_;}
00115
00116 private:
00119
00120 inline void incrementInternallyInconsistent(){intInconsistent_++;}
00122 inline void incrementExternallyInconsistent(){extInconsistent_++;}
00124 inline void incrementInfeasible(){infeasible_++;}
00126 inline void incrementIneffective(){ineffective_++;}
00128 inline void incrementApplied(){applied_++;}
00130
00132
00133
00134 int intInconsistent_;
00136 int extInconsistent_;
00138 int infeasible_;
00140 int ineffective_;
00142 int applied_;
00144 };
00145
00146
00147
00148 public:
00150
00151
00152 virtual void initialSolve() = 0;
00153
00155 virtual void resolve() = 0;
00156
00158 virtual void branchAndBound() = 0;
00159
00177 #ifdef CBC_NEXT_VERSION
00178 virtual int solveBranches(int depth,const OsiSolverBranch * branch,
00179 OsiSolverResult * result,
00180 int & numberSolves, int & numberIterations,
00181 bool forceBranch=false);
00182 #endif
00183
00184
00185
00242
00243 virtual bool setIntParam(OsiIntParam key, int value) {
00244 if (key == OsiLastIntParam) return (false) ;
00245 intParam_[key] = value;
00246 return true;
00247 }
00248
00249 virtual bool setDblParam(OsiDblParam key, double value) {
00250 if (key == OsiLastDblParam) return (false) ;
00251 dblParam_[key] = value;
00252 return true;
00253 }
00254
00255 virtual bool setStrParam(OsiStrParam key, const std::string & value) {
00256 if (key == OsiLastStrParam) return (false) ;
00257 strParam_[key] = value;
00258 return true;
00259 }
00260
00261 virtual bool setHintParam(OsiHintParam key, bool yesNo=true,
00262 OsiHintStrength strength=OsiHintTry,
00263 void * otherInformation=NULL) {
00264 if (key==OsiLastHintParam)
00265 return false;
00266 hintParam_[key] = yesNo;
00267 hintStrength_[key] = strength;
00268 if (strength == OsiForceDo)
00269 throw CoinError("OsiForceDo illegal",
00270 "setHintParam", "OsiSolverInterface");
00271 return true;
00272 }
00273
00274 virtual bool getIntParam(OsiIntParam key, int& value) const {
00275 if (key == OsiLastIntParam) return (false) ;
00276 value = intParam_[key];
00277 return true;
00278 }
00279
00280 virtual bool getDblParam(OsiDblParam key, double& value) const {
00281 if (key == OsiLastDblParam) return (false) ;
00282 value = dblParam_[key];
00283 return true;
00284 }
00285
00286 virtual bool getStrParam(OsiStrParam key, std::string& value) const {
00287 if (key == OsiLastStrParam) return (false) ;
00288 value = strParam_[key];
00289 return true;
00290 }
00291
00292 virtual bool getHintParam(OsiHintParam key, bool& yesNo,
00293 OsiHintStrength& strength,
00294 void *& otherInformation) const {
00295 if (key==OsiLastHintParam)
00296 return false;
00297 yesNo = hintParam_[key];
00298 strength = hintStrength_[key];
00299 otherInformation=NULL;
00300 return true;
00301 }
00302
00303 virtual bool getHintParam(OsiHintParam key, bool& yesNo,
00304 OsiHintStrength& strength) const {
00305 if (key==OsiLastHintParam)
00306 return false;
00307 yesNo = hintParam_[key];
00308 strength = hintStrength_[key];
00309 return true;
00310 }
00311
00312 virtual bool getHintParam(OsiHintParam key, bool& yesNo) const {
00313 if (key==OsiLastHintParam)
00314 return false;
00315 yesNo = hintParam_[key];
00316 return true;
00317 }
00318
00319 void copyParameters(OsiSolverInterface & rhs);
00321
00322
00324
00325
00326 virtual bool isAbandoned() const = 0;
00328 virtual bool isProvenOptimal() const = 0;
00330 virtual bool isProvenPrimalInfeasible() const = 0;
00332 virtual bool isProvenDualInfeasible() const = 0;
00334 virtual bool isPrimalObjectiveLimitReached() const = 0;
00336 virtual bool isDualObjectiveLimitReached() const = 0;
00338 virtual bool isIterationLimitReached() const = 0;
00340
00341
00359 virtual CoinWarmStart *getEmptyWarmStart () const = 0 ;
00360
00367 virtual CoinWarmStart* getWarmStart() const = 0;
00368
00376 virtual bool setWarmStart(const CoinWarmStart* warmstart) = 0;
00378
00379
00400
00401 virtual void markHotStart();
00403 virtual void solveFromHotStart();
00405 virtual void unmarkHotStart();
00407
00408
00419
00420 virtual int getNumCols() const = 0;
00421
00423 virtual int getNumRows() const = 0;
00424
00426 virtual int getNumElements() const = 0;
00427
00429 virtual int getNumIntegers() const ;
00430
00432 virtual const double * getColLower() const = 0;
00433
00435 virtual const double * getColUpper() const = 0;
00436
00446 virtual const char * getRowSense() const = 0;
00447
00460 virtual const double * getRightHandSide() const = 0;
00461
00470 virtual const double * getRowRange() const = 0;
00471
00473 virtual const double * getRowLower() const = 0;
00474
00476 virtual const double * getRowUpper() const = 0;
00477
00479 virtual const double * getObjCoefficients() const = 0;
00480
00482 virtual double getObjSense() const = 0;
00483
00485 virtual bool isContinuous(int colIndex) const = 0;
00486
00488 virtual bool isBinary(int colIndex) const;
00489
00494 virtual bool isInteger(int colIndex) const;
00495
00497 virtual bool isIntegerNonBinary(int colIndex) const;
00498
00500 virtual bool isFreeBinary(int colIndex) const;
00501 #if 0
00503 virtual std::string getRowName(int rowIndex) const;
00504
00506 virtual std::string getColName(int colIndex) const;
00507 #endif
00508
00510 virtual const CoinPackedMatrix * getMatrixByRow() const = 0;
00511
00513 virtual const CoinPackedMatrix * getMatrixByCol() const = 0;
00514
00516 virtual double getInfinity() const = 0;
00518
00521
00522 virtual const double * getColSolution() const = 0;
00523
00525 virtual const double * getRowPrice() const = 0;
00526
00528 virtual const double * getReducedCost() const = 0;
00529
00532 virtual const double * getRowActivity() const = 0;
00533
00535 virtual double getObjValue() const = 0;
00536
00539 virtual int getIterationCount() const = 0;
00540
00554 virtual std::vector<double*> getDualRays(int maxNumRays) const = 0;
00566 virtual std::vector<double*> getPrimalRays(int maxNumRays) const = 0;
00567
00570 virtual OsiVectorInt getFractionalIndices(const double etol=1.e-05)
00571 const;
00573
00574
00587 virtual void setObjCoeff( int elementIndex, double elementValue ) = 0;
00588
00590 virtual void setObjCoeffSet(const int* indexFirst,
00591 const int* indexLast,
00592 const double* coeffList);
00593
00596 virtual void setColLower( int elementIndex, double elementValue ) = 0;
00597
00600 virtual void setColUpper( int elementIndex, double elementValue ) = 0;
00601
00605 virtual void setColBounds( int elementIndex,
00606 double lower, double upper ) {
00607 setColLower(elementIndex, lower);
00608 setColUpper(elementIndex, upper);
00609 }
00610
00617 virtual void setColSetBounds(const int* indexFirst,
00618 const int* indexLast,
00619 const double* boundList);
00620
00623 virtual void setRowLower( int elementIndex, double elementValue ) = 0;
00624
00627 virtual void setRowUpper( int elementIndex, double elementValue ) = 0;
00628
00632 virtual void setRowBounds( int elementIndex,
00633 double lower, double upper ) {
00634 setRowLower(elementIndex, lower);
00635 setRowUpper(elementIndex, upper);
00636 }
00637
00639 virtual void setRowType(int index, char sense, double rightHandSide,
00640 double range) = 0;
00641
00646 virtual void setRowSetBounds(const int* indexFirst,
00647 const int* indexLast,
00648 const double* boundList);
00649
00654 virtual void setRowSetTypes(const int* indexFirst,
00655 const int* indexLast,
00656 const char* senseList,
00657 const double* rhsList,
00658 const double* rangeList);
00659 #if 0
00661 virtual void setRowName(int rowIndex, std::string & name) {};
00662
00664 virtual void setColName(int colIndex, std::string & name) {};
00665 #endif
00668 virtual void setObjSense(double s) = 0;
00669
00679 virtual void setColSolution(const double *colsol) = 0;
00680
00691 virtual void setRowPrice(const double * rowprice) = 0;
00692
00697 virtual void setObjective(const double * array);
00698
00703 virtual void setColLower(const double * array);
00704
00709 virtual void setColUpper(const double * array);
00711
00712
00716 virtual void setContinuous(int index) = 0;
00718 virtual void setInteger(int index) = 0;
00721 virtual void setContinuous(const int* indices, int len);
00724 virtual void setInteger(const int* indices, int len);
00726
00727
00728
00736 virtual void addCol(const CoinPackedVectorBase& vec,
00737 const double collb, const double colub,
00738 const double obj) = 0;
00744 virtual void addCols(const int numcols,
00745 const CoinPackedVectorBase * const * cols,
00746 const double* collb, const double* colub,
00747 const double* obj);
00749 virtual void addCol(int numberElements, const int * rows, const double * elements,
00750 const double collb, const double colub,
00751 const double obj) ;
00757 virtual void addCols(const int numcols,
00758 const int * columnStarts, const int * rows, const double * elements,
00759 const double* collb, const double* colub,
00760 const double* obj);
00762 void addCols(const CoinBuild & buildObject);
00768 int addCols(CoinModel & modelObject);
00769 #if 0
00770
00771 virtual void addCols(const CoinPackedMatrix& matrix,
00772 const double* collb, const double* colub,
00773 const double* obj);
00774 #endif
00775
00781 virtual void deleteCols(const int num, const int * colIndices) = 0;
00782
00784 virtual void addRow(const CoinPackedVectorBase& vec,
00785 const double rowlb, const double rowub) = 0;
00787 virtual void addRow(const CoinPackedVectorBase& vec,
00788 const char rowsen, const double rowrhs,
00789 const double rowrng) = 0;
00795 virtual void addRows(const int numrows,
00796 const CoinPackedVectorBase * const * rows,
00797 const double* rowlb, const double* rowub);
00803 virtual void addRows(const int numrows,
00804 const CoinPackedVectorBase * const * rows,
00805 const char* rowsen, const double* rowrhs,
00806 const double* rowrng);
00808 virtual void addRow(int numberElements, const int * columns, const double * element,
00809 const double rowlb, const double rowub) ;
00815 virtual void addRows(const int numrows,
00816 const int * rowStarts, const int * columns, const double * element,
00817 const double* rowlb, const double* rowub);
00819 void addRows(const CoinBuild & buildObject);
00826 int addRows(CoinModel & modelObject);
00827 #if 0
00828
00829 virtual void addRows(const CoinPackedMatrix& matrix,
00830 const double* rowlb, const double* rowub);
00832 virtual void addRows(const CoinPackedMatrix& matrix,
00833 const char* rowsen, const double* rowrhs,
00834 const double* rowrng);
00835 #endif
00836
00841 virtual void deleteRows(const int num, const int * rowIndices) = 0;
00842
00843
00866 virtual ApplyCutsReturnCode applyCuts(const OsiCuts & cs,
00867 double effectivenessLb = 0.0);
00872 virtual void applyRowCuts(int numberCuts, const OsiRowCut * cuts);
00876 virtual void applyRowCuts(int numberCuts, const OsiRowCut ** cuts);
00878
00879
00880
00894 virtual void loadProblem(const CoinPackedMatrix& matrix,
00895 const double* collb, const double* colub,
00896 const double* obj,
00897 const double* rowlb, const double* rowub) = 0;
00898
00908 virtual void assignProblem(CoinPackedMatrix*& matrix,
00909 double*& collb, double*& colub, double*& obj,
00910 double*& rowlb, double*& rowub) = 0;
00911
00924 virtual void loadProblem(const CoinPackedMatrix& matrix,
00925 const double* collb, const double* colub,
00926 const double* obj,
00927 const char* rowsen, const double* rowrhs,
00928 const double* rowrng) = 0;
00929
00939 virtual void assignProblem(CoinPackedMatrix*& matrix,
00940 double*& collb, double*& colub, double*& obj,
00941 char*& rowsen, double*& rowrhs,
00942 double*& rowrng) = 0;
00943
00946 virtual void loadProblem(const int numcols, const int numrows,
00947 const CoinBigIndex * start, const int* index,
00948 const double* value,
00949 const double* collb, const double* colub,
00950 const double* obj,
00951 const double* rowlb, const double* rowub) = 0;
00952
00955 virtual void loadProblem(const int numcols, const int numrows,
00956 const CoinBigIndex * start, const int* index,
00957 const double* value,
00958 const double* collb, const double* colub,
00959 const double* obj,
00960 const char* rowsen, const double* rowrhs,
00961 const double* rowrng) = 0;
00967 virtual int loadFromCoinModel ( CoinModel & modelObject, bool keepSolution=false);
00968
00974 virtual int readMps(const char *filename,
00975 const char *extension = "mps") ;
00976
00983 virtual int readMps(const char *filename, const char*extension,
00984 int & numberSets, CoinSet ** & sets);
00985
00990 virtual int readGMPL(const char *filename, const char * dataname=NULL);
00997 virtual void writeMps(const char *filename,
00998 const char *extension = "mps",
00999 double objSense=0.0) const = 0;
01000
01013 int writeMpsNative(const char *filename,
01014 const char ** rowNames, const char ** columnNames,
01015 int formatType=0,int numberAcross=2,
01016 double objSense=0.0) const ;
01017
01018
01019
01020
01040 virtual void writeLp(const char *filename,
01041 const char *extension = "lp",
01042 double epsilon = 1e-5,
01043 int numberAcross = 10,
01044 int decimals = 5,
01045 double objSense = 0.0,
01046 bool useRowNames = true) const;
01047
01052 virtual void writeLp(FILE *fp,
01053 double epsilon = 1e-5,
01054 int numberAcross = 10,
01055 int decimals = 5,
01056 double objSense = 0.0,
01057 bool useRowNames = true) const;
01058
01077 int writeLpNative(const char *filename,
01078 char const * const * const rowNames,
01079 char const * const * const columnNames,
01080 const double epsilon = 1.0e-5,
01081 const int numberAcross = 10,
01082 const int decimals = 5,
01083 const double objSense = 0.0,
01084 const bool useRowNames = true) const;
01085
01090 int writeLpNative(FILE *fp,
01091 char const * const * const rowNames,
01092 char const * const * const columnNames,
01093 const double epsilon = 1.0e-5,
01094 const int numberAcross = 10,
01095 const int decimals = 5,
01096 const double objSense = 0.0,
01097 const bool useRowNames = true) const;
01098
01101 virtual int readLp(const char *filename, const double epsilon = 1e-5);
01102
01105 int readLp(FILE *fp, const double epsilon = 1e-5);
01106
01112 virtual void replaceMatrixOptional(const CoinPackedMatrix & matrix) {};
01114 virtual void replaceMatrix(const CoinPackedMatrix & matrix) {abort();};
01116
01117
01118
01128 void setApplicationData (void * appData);
01135 void setAuxiliaryInfo(OsiAuxInfo * auxiliaryInfo);
01136
01138 void * getApplicationData() const;
01140 OsiAuxInfo * getAuxiliaryInfo() const;
01142
01143
01157 void passInMessageHandler(CoinMessageHandler * handler);
01159 void newLanguage(CoinMessages::Language language);
01160 void setLanguage(CoinMessages::Language language)
01161 {newLanguage(language);};
01163 CoinMessageHandler * messageHandler() const
01164 {return handler_;};
01166 CoinMessages messages()
01167 {return messages_;};
01169 CoinMessages * messagesPointer()
01170 {return &messages_;};
01172
01173
01182 virtual void activateRowCutDebugger (const char * modelName);
01183
01189 virtual void activateRowCutDebugger( const double * solution);
01199 const OsiRowCutDebugger * getRowCutDebugger() const;
01201 const OsiRowCutDebugger * getRowCutDebuggerAlways() const;
01202
01204
01205
01213 public:
01215
01216
01219 virtual int canDoSimplexInterface() const;
01226 virtual void enableSimplexInterface(bool doingPrimal) ;
01227
01229 virtual void disableSimplexInterface() ;
01230
01237 virtual void enableFactorization() const;
01239 virtual void disableFactorization() const;
01240
01245 virtual bool basisIsAvailable() const ;
01247 inline bool optimalBasisIsAvailable() const
01248 { return basisIsAvailable();};
01249
01262 virtual void getBasisStatus(int* cstat, int* rstat) const ;
01263
01270 virtual int setBasisStatus(const int* cstat, const int* rstat) ;
01271
01279 virtual int pivot(int colIn, int colOut, int outStatus) ;
01280
01292 virtual int primalPivotResult(int colIn, int sign,
01293 int& colOut, int& outStatus,
01294 double& t, CoinPackedVector* dx);
01295
01302 virtual int dualPivotResult(int& colIn, int& sign,
01303 int colOut, int outStatus,
01304 double& t, CoinPackedVector* dx) ;
01305
01307 virtual void getReducedGradient(double* columnReducedCosts,
01308 double * duals,
01309 const double * c) ;
01310
01313 virtual void setObjectiveAndRefresh(double* c) ;
01314
01316 virtual void getBInvARow(int row, double* z, double * slack=NULL) const ;
01317
01319 virtual void getBInvRow(int row, double* z) const ;
01320
01322 virtual void getBInvACol(int col, double* vec) const ;
01323
01325 virtual void getBInvCol(int col, double* vec) const ;
01326
01331 virtual void getBasics(int* index) const ;
01333
01334
01335
01337
01338
01339 OsiSolverInterface();
01340
01346 virtual OsiSolverInterface * clone(bool copyData = true) const = 0;
01347
01349 OsiSolverInterface(const OsiSolverInterface &);
01350
01352 OsiSolverInterface & operator=(const OsiSolverInterface& rhs);
01353
01355 virtual ~OsiSolverInterface ();
01356
01363 virtual void reset();
01365
01366
01367
01368 protected:
01370
01371
01372 virtual void applyRowCut( const OsiRowCut & rc ) = 0;
01373
01375 virtual void applyColCut( const OsiColCut & cc ) = 0;
01376
01379 inline void
01380 convertBoundToSense(const double lower, const double upper,
01381 char& sense, double& right, double& range) const;
01384 inline void
01385 convertSenseToBound(const char sense, const double right,
01386 const double range,
01387 double& lower, double& upper) const;
01390 template <class T> inline T
01391 forceIntoRange(const T value, const T lower, const T upper) const {
01392 return value < lower ? lower : (value > upper ? upper : value);
01393 }
01400 void setInitialData();
01402
01404
01405
01406 OsiRowCutDebugger * rowCutDebugger_;
01408
01409
01410
01411 private:
01413
01414
01415 OsiAuxInfo * appDataEtc_;
01417 int intParam_[OsiLastIntParam];
01419 double dblParam_[OsiLastDblParam];
01421 std::string strParam_[OsiLastStrParam];
01423 bool hintParam_[OsiLastHintParam];
01425 OsiHintStrength hintStrength_[OsiLastHintParam];
01428 CoinWarmStart* ws_;
01429
01430 protected:
01432 CoinMessageHandler * handler_;
01438 bool defaultHandler_;
01440 CoinMessages messages_;
01442 };
01443
01444
01452 void
01453 OsiSolverInterfaceCommonUnitTest(
01454 const OsiSolverInterface* emptySi,
01455 const std::string & mpsDir,
01456 const std::string & netlibDir);
01457
01458
01461 void
01462 OsiSolverInterfaceMpsUnitTest(
01463 const std::vector<OsiSolverInterface*> & vecSiP,
01464 const std::string & mpsDir);
01465
01466
01469 inline void
01470 OsiSolverInterface::convertBoundToSense(const double lower, const double upper,
01471 char& sense, double& right,
01472 double& range) const
01473 {
01474 double inf = getInfinity();
01475 range = 0.0;
01476 if (lower > -inf) {
01477 if (upper < inf) {
01478 right = upper;
01479 if (upper==lower) {
01480 sense = 'E';
01481 } else {
01482 sense = 'R';
01483 range = upper - lower;
01484 }
01485 } else {
01486 sense = 'G';
01487 right = lower;
01488 }
01489 } else {
01490 if (upper < inf) {
01491 sense = 'L';
01492 right = upper;
01493 } else {
01494 sense = 'N';
01495 right = 0.0;
01496 }
01497 }
01498 }
01499
01500
01503 inline void
01504 OsiSolverInterface::convertSenseToBound(const char sense, const double right,
01505 const double range,
01506 double& lower, double& upper) const
01507 {
01508 double inf=getInfinity();
01509 switch (sense) {
01510 case 'E':
01511 lower = upper = right;
01512 break;
01513 case 'L':
01514 lower = -inf;
01515 upper = right;
01516 break;
01517 case 'G':
01518 lower = right;
01519 upper = inf;
01520 break;
01521 case 'R':
01522 lower = right - range;
01523 upper = right;
01524 break;
01525 case 'N':
01526 lower = -inf;
01527 upper = inf;
01528 break;
01529 }
01530 }
01531
01532 #endif