summaryrefslogtreecommitdiff
path: root/thirdparty/linux/include/coin/CoinStructuredModel.hpp
blob: 19659b8fb5870959e53994cc7f644e5f100e3360 (plain)
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