DyLP trunk
|
00001 #ifndef OsiDylpSolverInterface_H 00002 #define OsiDylpSolverInterface_H 00003 00004 /* 00005 Copyright (C) 2002, 2003, 2004. 00006 Lou Hafer, Stephen Tse, International Business Machines Corporation and 00007 others. All Rights Reserved. 00008 Copyright (C) 2005 -- 2010 Lou Hafer 00009 00010 This file is a portion of the COIN/OSI interface for dylp and is licensed 00011 under the terms of the Eclipse Public License (EPL) 00012 */ 00013 00023 /* 00024 sccs: @(#)OsiDylpSolverInterface.hpp 1.12 09/16/04 00025 cvs: $Id: OsiDylpSolverInterface.hpp 1312 2008-10-10 00:26:32Z lou $ 00026 */ 00027 00028 #include "OsiConfig.h" 00029 #include <CoinPackedMatrix.hpp> 00030 #include <OsiSolverInterface.hpp> 00031 #include <CoinWarmStart.hpp> 00032 #include <CoinMessageHandler.hpp> 00033 #include <CoinMpsIO.hpp> 00034 #include <CoinPresolveMatrix.hpp> 00035 00036 #define DYLP_INTERNAL 00037 extern "C" { 00038 #include "dylp.h" 00039 } 00040 00041 class OsiDylpWarmStartBasis ; 00042 00045 typedef enum { startInvalid = 0, 00046 startCold = 1, startWarm, startHot } ODSI_start_enum ; 00047 00048 00107 class OsiDylpSolverInterface: virtual public OsiSolverInterface 00108 00109 { friend int OsiDylpSolverInterfaceUnitTest(const std::string &mpsDir, 00110 const std::string &netLibDir) ; 00111 00112 /* 00113 Consult the COIN OSI documentation or relevant source code for details 00114 not covered here. Supported functions are listed first, followed by 00115 unsupported functions. 00116 */ 00117 00118 public: 00119 00122 00125 OsiDylpSolverInterface() ; 00126 00129 OsiDylpSolverInterface(const OsiDylpSolverInterface &src) ; 00130 00133 OsiSolverInterface* clone(bool copyData = true) const ; 00134 00137 OsiDylpSolverInterface &operator=(const OsiDylpSolverInterface &rhs) ; 00138 00141 ~OsiDylpSolverInterface() ; 00142 00147 void reset() ; 00148 00150 00153 00156 int readMps(const char *filename, const char *extension = "mps") ; 00157 00162 int readMps(const char *filename, const char *extension, 00163 int &numberSets, CoinSet **&sets) ; 00164 00172 void writeMps(const char *basename, 00173 const char *extension = "mps", 00174 double objsense = 0.0) const ; 00175 00179 void loadProblem(const CoinPackedMatrix &matrix, 00180 const double *collb, const double *colub, const double *obj, 00181 const char *rowsen, const double *rowrhs, 00182 const double *rowrng) ; 00183 00187 void loadProblem(const CoinPackedMatrix &matrix, 00188 const double *collb, const double *colub, const double *obj, 00189 const double *rowlb, const double *rowub) ; 00190 00194 void loadProblem(const int colcnt, const int rowcnt, 00195 const int *start, const int *index, const double *value, 00196 const double *collb, const double *colub, const double *obj, 00197 const char *sense, const double *rhsin, const double *range) ; 00198 00202 void loadProblem(const int colcnt, const int rowcnt, 00203 const int *start, const int *index, const double *value, 00204 const double *collb, const double *colub, const double *obj, 00205 const double *row_lower, const double *row_upper) ; 00206 00210 void assignProblem(CoinPackedMatrix *&matrix, 00211 double *&collb, double *&colub, double *&obj, 00212 char *&rowsen, double *&rowrhs, double *&rowrng) ; 00213 00217 void assignProblem(CoinPackedMatrix *&matrix, 00218 double *&collb, double *&colub, double *&obj, 00219 double *&rowlb, double *&rowub) ; 00220 00222 00226 00229 int getNumCols() const ; 00230 00233 int getNumRows() const ; 00234 00237 int getNumElements() const ; 00238 00244 int getNumIntegers() const ; 00245 00248 const double* getColLower() const ; 00249 00252 const double* getColUpper() const ; 00253 00256 bool isContinuous(int colIndex) const ; 00257 00260 bool isBinary(int colIndex) const ; 00261 00264 bool isIntegerNonBinary (int colIndex) const ; 00265 00268 bool isInteger (int colIndex) const ; 00269 00272 const char* getRowSense() const ; 00273 00276 const double* getRightHandSide() const ; 00277 00280 const double* getRowRange() const ; 00281 00284 const double* getRowLower() const ; 00285 00288 const double* getRowUpper() const ; 00289 00292 const double* getObjCoefficients() const ; 00293 00299 double getObjSense() const ; 00300 00303 const CoinPackedMatrix *getMatrixByRow() const ; 00304 00307 const CoinPackedMatrix *getMatrixByCol() const ; 00309 00316 00319 void setObjName (std::string name) ; 00320 00326 void setRowName(int ndx, std::string name) ; 00327 00333 void setColName(int ndx, std::string name) ; 00334 00336 00339 00342 void setContinuous(int index) ; 00343 using OsiSolverInterface::setContinuous ; 00344 00347 void setInteger(int index) ; 00348 using OsiSolverInterface::setInteger ; 00349 00352 void setColLower(int index, double value) ; 00353 using OsiSolverInterface::setColLower ; 00354 00357 void setColUpper(int index, double value) ; 00358 using OsiSolverInterface::setColUpper ; 00359 00362 void setRowLower(int index, double value) ; 00363 00366 void setRowUpper(int index, double value) ; 00367 00370 void setRowType(int index, char rowsen, double rowrhs, double rowrng) ; 00371 00374 void setObjCoeff (int index, double value) ; 00375 00378 void setObjective(const double * array); 00379 00386 void setObjSense(double sense) ; 00387 00390 void setColSolution(const double *colsol) ; 00391 00394 void setRowPrice(const double*) ; 00395 00396 /* For overload resolution with OSI::addCol functions. */ 00397 00398 using OsiSolverInterface::addCol ; 00399 00402 void addCol(const CoinPackedVectorBase &vec, 00403 const double collb, const double colub, const double obj) ; 00404 00407 void deleteCols(const int num, const int *colIndices) ; 00408 00409 /* For overload resolution with OSI::addRow functions. */ 00410 00411 using OsiSolverInterface::addRow ; 00412 00415 void addRow(const CoinPackedVectorBase &row, 00416 const double rowlb, const double rowub) ; 00417 00420 void addRow(const CoinPackedVectorBase &row, 00421 const char rowsen, const double rowrhs, const double rowrng) ; 00422 00425 void deleteRows(const int num, const int *rowIndices) ; 00426 00429 void applyRowCut(const OsiRowCut &cut) ; 00430 00433 void applyColCut(const OsiColCut &cut) ; 00435 00438 00441 void initialSolve() ; 00442 00445 CoinWarmStart *getEmptyWarmStart () const ; 00446 00449 CoinWarmStart *getWarmStart() const ; 00450 00458 bool setWarmStart(const CoinWarmStart *warmStart) ; 00459 00462 void resolve() ; 00463 00466 void markHotStart() ; 00467 00470 void solveFromHotStart() ; 00471 00474 void unmarkHotStart() ; 00475 00477 00480 00483 bool isAbandoned() const ; 00484 00487 bool isProvenOptimal() const ; 00488 00491 bool isProvenPrimalInfeasible() const ; 00492 00496 bool isProvenDualInfeasible() const ; 00497 00500 bool isIterationLimitReached() const ; 00501 00504 int getIterationCount() const ; 00505 00511 bool isPrimalObjectiveLimitReached() const ; 00512 00518 bool isDualObjectiveLimitReached() const ; 00520 00521 00524 00527 double getInfinity() const ; 00528 00531 bool setIntParam(OsiIntParam key, int value) ; 00532 00535 bool setDblParam(OsiDblParam key, double value) ; 00536 00539 bool setStrParam(OsiStrParam key, const std::string& value) ; 00540 00543 bool setHintParam(OsiHintParam key, bool sense = true, 00544 OsiHintStrength strength = OsiHintTry, void *info = 0) ; 00545 00548 bool getIntParam(OsiIntParam key, int &value) const ; 00549 00552 bool getDblParam(OsiDblParam key, double &value) const ; 00553 00556 bool getStrParam(OsiStrParam key, std::string &value) const ; 00557 00558 /* For overload resolution with OSI::getHintParam functions. */ 00559 00560 using OsiSolverInterface::getHintParam ; 00561 00564 bool getHintParam(OsiHintParam key, bool &sense, 00565 OsiHintStrength &strength, void *&info) const ; 00566 00569 inline void newLanguage(CoinMessages::Language language) 00570 { setOsiDylpMessages(language) ; } 00571 00574 inline void setLanguage(CoinMessages::Language language) 00575 { setOsiDylpMessages(language) ; } 00576 00578 00581 00584 double getObjValue() const ; 00585 00588 const double* getColSolution() const ; 00589 00592 const double* getRowPrice() const ; 00593 00596 const double* getReducedCost() const ; 00597 00600 const double* getRowActivity() const ; 00601 00610 std::vector<double *> getDualRays(int maxNumRays, bool fullRay) const ; 00611 00614 std::vector<double *> getPrimalRays(int maxNumRays) const ; 00615 00617 00620 00622 int canDoSimplexInterface() const ; 00623 00635 void enableFactorization() const ; 00636 00643 void disableFactorization() const ; 00644 00646 bool basisIsAvailable () const ; 00647 00655 void getBasisStatus (int *archStatus, int *logStatus) const ; 00656 00663 int setBasisStatus (const int *archStatus, const int *logStatus) ; 00664 00671 virtual void getReducedGradient(double *columnReducedCosts, 00672 double *duals, const double *c) const ; 00673 00675 virtual void getBasics(int *index) const ; 00676 00678 virtual void getBInvCol(int col, double *betak) const ; 00679 00681 virtual void getBInvACol(int col, double *abarj) const ; 00682 00684 virtual void getBInvRow(int row, double *betai) const ; 00685 00687 virtual void getBInvARow(int row, double *abari, double *betai = 0) const ; 00688 00690 00691 00694 00701 void activateRowCutDebugger (const char * modelName) ; 00702 00713 void activateRowCutDebugger (const double *solution, 00714 bool keepContinuous = false) ; 00715 00716 # if ODSI_PARANOIA >= 1 00717 00726 void indexCheck (int k, bool isCol, std::string rtnnme) ; 00727 # endif 00728 00730 00733 00736 void dylp_controlfile(const char* name, const bool silent, 00737 const bool mustexist = true) ; 00738 00741 void dylp_logfile(const char* name, bool echo = false) ; 00742 00745 void dylp_outfile(const char* name) ; 00746 00749 void dylp_printsoln(bool wantSoln, bool wantStats) ; 00750 00753 void setOsiDylpMessages(CoinMessages::Language local_language) ; 00754 00756 00759 00760 00763 void branchAndBound() ; 00764 00766 00776 00778 lpopts_struct *initialSolveOptions ; 00779 00781 lpopts_struct *resolveOptions ; 00782 00784 lptols_struct *tolerances ; 00785 00787 00788 private: 00789 00790 /* 00791 Private implementation state and helper functions. If you're contemplating 00792 using any of these, you should have a look at the code. 00793 See OsiDylpSolverInterface.cpp for descriptions. 00794 */ 00801 00803 consys_struct *consys ; 00805 lpprob_struct *lpprob ; 00807 lpstats_struct *statistics ; 00808 00810 00813 00815 static int reference_count ; 00817 static bool basis_ready ; 00818 00820 00821 00827 00834 ioid local_outchn ; 00835 00841 ioid local_logchn ; 00842 00847 bool initial_gtxecho ; 00848 00853 bool resolve_gtxecho ; 00854 00864 lpret_enum lp_retval ; 00865 00871 double obj_sense ; 00872 00875 double odsiInfinity ; 00876 00879 const std::string solvername ; 00880 00883 mutable void *info_[OsiLastHintParam] ; 00884 00887 bool mps_debug ; 00888 00896 CoinWarmStart *hotstart_fallback ; 00897 00918 enum basisCondition 00919 { basisNone = 0, basisFresh, basisModified, basisDamaged } ; 00920 00938 struct 00939 { CoinWarmStart *basis ; 00940 basisCondition condition ; 00941 int balance ; } activeBasis ; 00942 00948 bool solnIsFresh ; 00949 00956 mutable struct 00957 { int simplex ; 00958 bool saved_fullsys ; } simplex_state ; 00959 00961 00962 00963 00970 00971 mutable double _objval ; 00972 mutable double* _col_obj ; 00973 mutable double* _col_x ; 00974 mutable double* _col_cbar ; 00975 00976 mutable double* _row_rhs ; 00977 mutable double* _row_lower ; 00978 mutable double* _row_upper ; 00979 mutable char* _row_sense ; 00980 mutable double* _row_range ; 00981 mutable double* _row_lhs ; 00982 mutable double* _row_price ; 00983 00984 mutable CoinPackedMatrix* _matrix_by_col ; 00985 mutable CoinPackedMatrix* _matrix_by_row ; 00986 00988 00995 01001 CoinPresolveMatrix *preObj_ ; 01002 01009 const CoinPresolveAction *postActions_ ; 01010 01018 CoinPostsolveMatrix *postObj_ ; 01019 01021 int passLimit_ ; 01022 01024 bool keepIntegers_ ; 01025 01027 consys_struct *savedConsys_ ; 01028 01030 mutable double* saved_col_obj ; 01031 mutable double* saved_row_rhs ; 01032 mutable double* saved_row_lower ; 01033 mutable double* saved_row_upper ; 01034 mutable char* saved_row_sense ; 01035 mutable double* saved_row_range ; 01036 mutable CoinPackedMatrix* saved_matrix_by_col ; 01037 mutable CoinPackedMatrix* saved_matrix_by_row ; 01038 01040 01050 01051 CoinPresolveMatrix *initialisePresolve(bool keepIntegers) ; 01052 01054 void doPresolve() ; 01055 01057 bool evalPresolve() ; 01058 01060 void saveOriginalSys() ; 01061 01063 void installPresolve() ; 01064 01066 CoinPostsolveMatrix *initialisePostsolve(CoinPresolveMatrix *&preObj) ; 01067 01069 void doPostsolve() ; 01070 01072 void installPostsolve() ; 01073 01075 void destruct_presolve() ; 01076 01078 01082 01084 bool ensureOwnership () const ; 01085 01086 //}@ 01087 01091 void construct_lpprob() ; 01092 void construct_options() ; 01093 void construct_consys(int cols, int rows) ; 01094 void dylp_ioinit() ; 01095 void gen_rowparms(int rowcnt, 01096 double *rhs, double *rhslow, contyp_enum *ctyp, 01097 const double *rowlb, const double *rowub) ; 01098 void gen_rowparms(int rowcnt, 01099 double *rhs, double *rhslow, contyp_enum *ctyp, 01100 const char *sense, const double *rhsin, const double *range) ; 01101 void load_problem(const CoinMpsIO &mps) ; 01102 void load_problem(const CoinPackedMatrix &matrix, 01103 const double* col_lower, const double* col_upper, const double* obj, 01104 const contyp_enum *ctyp, const double* rhs, const double* rhslow) ; 01105 void load_problem (const int colcnt, const int rowcnt, 01106 const int *start, const int *lens, 01107 const int *index, const double *value, 01108 const double* col_lower, const double* col_upper, const double* obj, 01109 const contyp_enum *ctyp, const double* rhs, const double* rhslow) ; 01111 01115 lpret_enum do_lp (ODSI_start_enum start, bool echo) ; 01116 01118 void setBasisInLpprob (const OsiDylpWarmStartBasis *wsb, 01119 lpprob_struct *lpprob) const ; 01121 01124 void destruct_primal_cache() ; 01125 void destruct_dual_cache() ; 01126 void destruct_col_cache(bool structure) ; 01127 void destruct_row_cache(bool structure) ; 01128 void destruct_cache(bool rowStructure, bool colStructure) ; 01129 void destruct_problem(bool preserve_interface) ; 01130 void detach_dylp() const ; 01132 01133 01135 /* 01136 There are separate groups for member and static methods so that doxygen 01137 won't promote the group to the top level. 01138 */ 01140 01141 void add_col(const CoinPackedVectorBase& coin_coli, 01142 vartyp_enum vtypi, double vlbi, 01143 double vubi, double obji, const std::string *nme) ; 01144 void add_row(const CoinPackedVectorBase& coin_rowi, 01145 char clazzi, contyp_enum ctypi, 01146 double rhsi, double rhslowi, const std::string *nme) ; 01147 void calc_objval() ; 01148 contyp_enum bound_to_type(double lower, double upper) ; 01149 void gen_rowiparms(contyp_enum* ctypi, double* rhsi, double* rhslowi, 01150 char sensei, double rhsini, double rangei) ; 01151 void gen_rowiparms(contyp_enum* ctypi, double* rhsi, double* rhslowi, 01152 double rowlbi, double rowubi) ; 01153 void unimp_hint(bool dylpSense, bool hintSense, 01154 OsiHintStrength hintStrength, const char *msgString) ; 01155 void pessimal_primal() ; 01156 void reduceActiveBasis() ; 01157 01159 01162 static contyp_enum sense_to_type(char type) ; 01163 static char type_to_sense(contyp_enum type) ; 01165 01172 template<class T> static void copy(const T* src, T* dst, int n) ; 01173 template<class T> static T* copy(const T* src, int n) ; 01174 template<class T> static T* copy(const T* src) ; 01175 /* 01176 Specializations for more complicated structures. 01177 */ 01178 static basis_struct* copy_basis(const basis_struct* src, int dstsze) ; 01179 static void copy_basis(const basis_struct* src, basis_struct* dst) ; 01180 static lpprob_struct* copy_lpprob(const lpprob_struct* src) ; 01182 01183 #ifndef _MSC_VER 01184 01189 template<class T> static void assert_same(const T& t1, const T& t2, 01190 bool exact) ; 01191 template<class T> static void assert_same(const T* t1, const T* t2, 01192 int n, bool exact) ; 01193 01194 static void assert_same(double d1, double d2, bool exact) ; 01195 01196 static void assert_same(const basis_struct& b1, 01197 const basis_struct& b2, bool exact) ; 01198 static void assert_same(const consys_struct& c1, const 01199 consys_struct& c2, bool exact) ; 01200 static void assert_same(const conbnd_struct& c1, const 01201 conbnd_struct& c2, bool exact) ; 01202 static void assert_same(const lpprob_struct& l1, 01203 const lpprob_struct& l2, bool exact) ; 01204 static void assert_same(const OsiDylpSolverInterface& o1, 01205 const OsiDylpSolverInterface& o2, bool exact) ; 01207 #endif /* ! _MSC_VER */ 01208 01215 01221 template<class T> inline static T* idx_vec (T* vec) { return (vec-1) ; } 01222 01224 inline static int idx (int i) { return (i+1) ; } 01225 01231 template<class T> inline static T* inv_vec (T* vec) { return (vec+1) ; } 01232 01234 inline static int inv (int i) { return (i-1) ; } 01235 01236 static pkvec_struct* packed_vector( 01237 const CoinShallowPackedVector vector, int dimension) ; 01238 static void packed_vector( 01239 const CoinShallowPackedVector vector, int dimension, pkvec_struct *dst) ; 01241 01244 static std::string make_filename(const char *filename, 01245 const char *ext1, const char *ext2) ; 01247 01248 } ; 01249 01250 01251 /* 01252 OsiDylpSolverInterfaceTest.cpp 01253 */ 01254 01262 int OsiDylpSolverInterfaceUnitTest(const std::string & mpsDir, 01263 const std::string &netLibDir) ; 01264 01265 #endif // OsiDylpSolverInterface_H