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
36class CoinStructuredModel : public CoinBaseModel {
37
38public:
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
210private:
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