| 1 | /* $Id: CoinStructuredModel.hpp 1372 2011-01-03 23:31:00Z lou $ */ |
| 2 | // Copyright (C) 2008, International Business Machines |
| 3 | // Corporation and others. All Rights Reserved. |
| 4 | // This code is licensed under the terms of the Eclipse Public License (EPL). |
| 5 | |
| 6 | #ifndef CoinStructuredModel_H |
| 7 | #define CoinStructuredModel_H |
| 8 | |
| 9 | #include "CoinModel.hpp" |
| 10 | #include <vector> |
| 11 | |
| 12 | /** |
| 13 | This is a model which is made up of Coin(Structured)Model blocks. |
| 14 | */ |
| 15 | typedef struct CoinModelInfo2 { |
| 16 | int rowBlock; // Which row block |
| 17 | int columnBlock; // Which column block |
| 18 | char matrix; // nonzero if matrix exists |
| 19 | char rhs; // nonzero if non default rhs exists |
| 20 | char rowName; // nonzero if row names exists |
| 21 | char integer; // nonzero if integer information exists |
| 22 | char bounds; // nonzero if non default bounds/objective exists |
| 23 | char columnName; // nonzero if column names exists |
| 24 | CoinModelInfo2() : |
| 25 | rowBlock(0), |
| 26 | columnBlock(0), |
| 27 | matrix(0), |
| 28 | rhs(0), |
| 29 | rowName(0), |
| 30 | integer(0), |
| 31 | bounds(0), |
| 32 | columnName(0) |
| 33 | {} |
| 34 | } CoinModelBlockInfo; |
| 35 | |
| 36 | class CoinStructuredModel : public CoinBaseModel { |
| 37 | |
| 38 | public: |
| 39 | /**@name Useful methods for building model */ |
| 40 | //@{ |
| 41 | /** add a block from a CoinModel using names given as parameters |
| 42 | returns number of errors (e.g. both have objectives but not same) |
| 43 | */ |
| 44 | int addBlock(const std::string & rowBlock, |
| 45 | const std::string & columnBlock, |
| 46 | const CoinBaseModel & block); |
| 47 | /** add a block from a CoinModel with names in model |
| 48 | returns number of errors (e.g. both have objectives but not same) |
| 49 | */ |
| 50 | int addBlock(const CoinBaseModel & block); |
| 51 | /** add a block from a CoinModel using names given as parameters |
| 52 | returns number of errors (e.g. both have objectives but not same) |
| 53 | This passes in block - structured model takes ownership |
| 54 | */ |
| 55 | int addBlock(const std::string & rowBlock, |
| 56 | const std::string & columnBlock, |
| 57 | CoinBaseModel * block); |
| 58 | /** add a block using names |
| 59 | */ |
| 60 | int addBlock(const std::string & rowBlock, |
| 61 | const std::string & columnBlock, |
| 62 | const CoinPackedMatrix & matrix, |
| 63 | const double * rowLower, const double * rowUpper, |
| 64 | const double * columnLower, const double * columnUpper, |
| 65 | const double * objective); |
| 66 | |
| 67 | /** Write the problem in MPS format to a file with the given filename. |
| 68 | |
| 69 | \param compression can be set to three values to indicate what kind |
| 70 | of file should be written |
| 71 | <ul> |
| 72 | <li> 0: plain text (default) |
| 73 | <li> 1: gzip compressed (.gz is appended to \c filename) |
| 74 | <li> 2: bzip2 compressed (.bz2 is appended to \c filename) (TODO) |
| 75 | </ul> |
| 76 | If the library was not compiled with the requested compression then |
| 77 | writeMps falls back to writing a plain text file. |
| 78 | |
| 79 | \param formatType specifies the precision to used for values in the |
| 80 | MPS file |
| 81 | <ul> |
| 82 | <li> 0: normal precision (default) |
| 83 | <li> 1: extra accuracy |
| 84 | <li> 2: IEEE hex |
| 85 | </ul> |
| 86 | |
| 87 | \param numberAcross specifies whether 1 or 2 (default) values should be |
| 88 | specified on every data line in the MPS file. |
| 89 | |
| 90 | not const as may change model e.g. fill in default bounds |
| 91 | */ |
| 92 | int writeMps(const char *filename, int compression = 0, |
| 93 | int formatType = 0, int numberAcross = 2, bool keepStrings=false) ; |
| 94 | /** Decompose a CoinModel |
| 95 | 1 - try D-W |
| 96 | 2 - try Benders |
| 97 | 3 - try Staircase |
| 98 | Returns number of blocks or zero if no structure |
| 99 | */ |
| 100 | int decompose(const CoinModel &model,int type, |
| 101 | int maxBlocks=50); |
| 102 | /** Decompose a model specified as arrays + CoinPackedMatrix |
| 103 | 1 - try D-W |
| 104 | 2 - try Benders |
| 105 | 3 - try Staircase |
| 106 | Returns number of blocks or zero if no structure |
| 107 | */ |
| 108 | int decompose(const CoinPackedMatrix & matrix, |
| 109 | const double * rowLower, const double * rowUpper, |
| 110 | const double * columnLower, const double * columnUpper, |
| 111 | const double * objective, int type,int maxBlocks=50, |
| 112 | double objectiveOffset=0.0); |
| 113 | |
| 114 | //@} |
| 115 | |
| 116 | |
| 117 | /**@name For getting information */ |
| 118 | //@{ |
| 119 | /// Return number of row blocks |
| 120 | inline int numberRowBlocks() const |
| 121 | { return numberRowBlocks_;} |
| 122 | /// Return number of column blocks |
| 123 | inline int numberColumnBlocks() const |
| 124 | { return numberColumnBlocks_;} |
| 125 | /// Return number of elementBlocks |
| 126 | inline CoinBigIndex numberElementBlocks() const |
| 127 | { return numberElementBlocks_;} |
| 128 | /// Return number of elements |
| 129 | CoinBigIndex numberElements() const override; |
| 130 | /// Return the i'th row block name |
| 131 | inline const std::string & getRowBlock(int i) const |
| 132 | { return rowBlockNames_[i];} |
| 133 | /// Set i'th row block name |
| 134 | inline void setRowBlock(int i,const std::string &name) |
| 135 | { rowBlockNames_[i] = name;} |
| 136 | /// Add or check a row block name and number of rows |
| 137 | int addRowBlock(int numberRows,const std::string &name) ; |
| 138 | /// Return a row block index given a row block name |
| 139 | int rowBlock(const std::string &name) const; |
| 140 | /// Return i'th the column block name |
| 141 | inline const std::string & getColumnBlock(int i) const |
| 142 | { return columnBlockNames_[i];} |
| 143 | /// Set i'th column block name |
| 144 | inline void setColumnBlock(int i,const std::string &name) |
| 145 | { columnBlockNames_[i] = name;} |
| 146 | /// Add or check a column block name and number of columns |
| 147 | int addColumnBlock(int numberColumns,const std::string &name) ; |
| 148 | /// Return a column block index given a column block name |
| 149 | int columnBlock(const std::string &name) const; |
| 150 | /// Return i'th block type |
| 151 | inline const CoinModelBlockInfo & blockType(int i) const |
| 152 | { return blockType_[i];} |
| 153 | /// Return i'th block |
| 154 | inline CoinBaseModel * block(int i) const |
| 155 | { return blocks_[i];} |
| 156 | /// Return block corresponding to row and column |
| 157 | const CoinBaseModel * block(int row,int column) const; |
| 158 | /// Return i'th block as CoinModel (or NULL) |
| 159 | CoinModel * coinBlock(int i) const; |
| 160 | /// Return block corresponding to row and column as CoinModel |
| 161 | const CoinBaseModel * coinBlock(int row,int column) const; |
| 162 | /// Return block number corresponding to row and column |
| 163 | int blockIndex(int row,int column) const; |
| 164 | /** Return model as a CoinModel block |
| 165 | and fill in info structure and update counts |
| 166 | */ |
| 167 | CoinModel * coinModelBlock(CoinModelBlockInfo & info) ; |
| 168 | /// Sets given block into coinModelBlocks_ |
| 169 | void setCoinModel(CoinModel * block, int iBlock); |
| 170 | /// Refresh info in blockType_ |
| 171 | void refresh(int iBlock); |
| 172 | /** Fill pointers corresponding to row and column */ |
| 173 | |
| 174 | CoinModelBlockInfo block(int row,int column, |
| 175 | const double * & rowLower, const double * & rowUpper, |
| 176 | const double * & columnLower, const double * & columnUpper, |
| 177 | const double * & objective) const; |
| 178 | /// Direction of optimization (1 - minimize, -1 - maximize, 0 - ignore |
| 179 | inline double optimizationDirection() const { |
| 180 | return optimizationDirection_; |
| 181 | } |
| 182 | /// Set direction of optimization (1 - minimize, -1 - maximize, 0 - ignore |
| 183 | inline void setOptimizationDirection(double value) |
| 184 | { optimizationDirection_=value;} |
| 185 | //@} |
| 186 | |
| 187 | /**@name Constructors, destructor */ |
| 188 | //@{ |
| 189 | /** Default constructor. */ |
| 190 | CoinStructuredModel(); |
| 191 | /** Read a problem in MPS format from the given filename. |
| 192 | May try and decompose |
| 193 | */ |
| 194 | CoinStructuredModel(const char *fileName,int decompose=0, |
| 195 | int maxBlocks=50); |
| 196 | /** Destructor */ |
| 197 | virtual ~CoinStructuredModel(); |
| 198 | //@} |
| 199 | |
| 200 | /**@name Copy method */ |
| 201 | //@{ |
| 202 | /** The copy constructor. */ |
| 203 | CoinStructuredModel(const CoinStructuredModel&); |
| 204 | /// = |
| 205 | CoinStructuredModel& operator=(const CoinStructuredModel&); |
| 206 | /// Clone |
| 207 | virtual CoinBaseModel * clone() const override; |
| 208 | //@} |
| 209 | |
| 210 | private: |
| 211 | |
| 212 | /** Fill in info structure and update counts |
| 213 | Returns number of inconsistencies on border |
| 214 | */ |
| 215 | int fillInfo(CoinModelBlockInfo & info,const CoinModel * block); |
| 216 | /** Fill in info structure and update counts |
| 217 | */ |
| 218 | void fillInfo(CoinModelBlockInfo & info,const CoinStructuredModel * block); |
| 219 | /**@name Data members */ |
| 220 | //@{ |
| 221 | /// Current number of row blocks |
| 222 | int numberRowBlocks_; |
| 223 | /// Current number of column blocks |
| 224 | int numberColumnBlocks_; |
| 225 | /// Current number of element blocks |
| 226 | int numberElementBlocks_; |
| 227 | /// Maximum number of element blocks |
| 228 | int maximumElementBlocks_; |
| 229 | /// Rowblock name |
| 230 | std::vector<std::string> rowBlockNames_; |
| 231 | /// Columnblock name |
| 232 | std::vector<std::string> columnBlockNames_; |
| 233 | /// Blocks |
| 234 | CoinBaseModel ** blocks_; |
| 235 | /// CoinModel copies of blocks or NULL if original CoinModel |
| 236 | CoinModel ** coinModelBlocks_; |
| 237 | /// Which parts of model are set in block |
| 238 | CoinModelBlockInfo * blockType_; |
| 239 | //@} |
| 240 | }; |
| 241 | #endif |
| 242 | |