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