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 | |