1 /* -*- C++ -*- |
1 (binary file text/x-chdr, hash: c1baa9a06a141f28cc081626be954c4589ed3a3a) |
2 * |
|
3 * This file is a part of LEMON, a generic C++ optimization library |
|
4 * |
|
5 * Copyright (C) 2003-2006 |
|
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport |
|
7 * (Egervary Research Group on Combinatorial Optimization, EGRES). |
|
8 * |
|
9 * Permission to use, modify and distribute this software is granted |
|
10 * provided that this copyright notice appears in all copies. For |
|
11 * precise terms see the accompanying LICENSE file. |
|
12 * |
|
13 * This software is provided "AS IS" with no warranty of any kind, |
|
14 * express or implied, and with no claim as to its suitability for any |
|
15 * purpose. |
|
16 * |
|
17 */ |
|
18 |
|
19 #ifndef LEMON_MATRIX_MAPS_H |
|
20 #define LEMON_MATRIX_MAPS_H |
|
21 |
|
22 |
|
23 #include <vector> |
|
24 #include <lemon/bits/utility.h> |
|
25 #include <lemon/maps.h> |
|
26 |
|
27 |
|
28 /// \file |
|
29 /// \ingroup maps |
|
30 /// \brief Maps indexed with pairs of items. |
|
31 /// |
|
32 /// \todo This file has the same name as the concept file in concept/, |
|
33 /// and this is not easily detectable in docs... |
|
34 namespace lemon { |
|
35 |
|
36 /// \brief Map for the coloumn view of the matrix |
|
37 /// |
|
38 /// Map for the coloumn view of the matrix. |
|
39 template <typename _MatrixMap> |
|
40 class MatrixRowMap : public MapTraits<_MatrixMap> { |
|
41 public: |
|
42 typedef _MatrixMap MatrixMap; |
|
43 typedef typename MatrixMap::SecondKey Key; |
|
44 typedef typename MatrixMap::Value Value; |
|
45 |
|
46 |
|
47 MatrixRowMap(MatrixMap& _matrix, typename MatrixMap::FirstKey _row) |
|
48 : matrix(_matrix), row(_row) {} |
|
49 |
|
50 /// \brief Subscription operator |
|
51 /// |
|
52 /// Subscription operator. |
|
53 typename MapTraits<MatrixMap>::ReturnValue |
|
54 operator[](Key col) { |
|
55 return matrix(row, col); |
|
56 } |
|
57 |
|
58 /// \brief Setter function |
|
59 /// |
|
60 /// Setter function. |
|
61 void set(Key col, const Value& val) { |
|
62 matrix.set(row, col, val); |
|
63 } |
|
64 |
|
65 /// \brief Subscription operator |
|
66 /// |
|
67 /// Subscription operator. |
|
68 typename MapTraits<MatrixMap>::ConstReturnValue |
|
69 operator[](Key col) const { |
|
70 return matrix(row, col); |
|
71 } |
|
72 |
|
73 private: |
|
74 MatrixMap& matrix; |
|
75 typename MatrixMap::FirstKey row; |
|
76 }; |
|
77 |
|
78 /// \brief Map for the row view of the matrix |
|
79 /// |
|
80 /// Map for the row view of the matrix. |
|
81 template <typename _MatrixMap> |
|
82 class ConstMatrixRowMap : public MapTraits<_MatrixMap> { |
|
83 public: |
|
84 typedef _MatrixMap MatrixMap; |
|
85 typedef typename MatrixMap::SecondKey Key; |
|
86 typedef typename MatrixMap::Value Value; |
|
87 |
|
88 |
|
89 ConstMatrixRowMap(const MatrixMap& _matrix, |
|
90 typename MatrixMap::FirstKey _row) |
|
91 : matrix(_matrix), row(_row) {} |
|
92 |
|
93 /// \brief Subscription operator |
|
94 /// |
|
95 /// Subscription operator. |
|
96 typename MapTraits<MatrixMap>::ConstReturnValue |
|
97 operator[](Key col) const { |
|
98 return matrix(row, col); |
|
99 } |
|
100 |
|
101 private: |
|
102 const MatrixMap& matrix; |
|
103 typename MatrixMap::FirstKey row; |
|
104 }; |
|
105 |
|
106 /// \brief Gives back a row view of the matrix map |
|
107 /// |
|
108 /// Gives back a row view of the matrix map. |
|
109 template <typename MatrixMap> |
|
110 MatrixRowMap<MatrixMap> matrixRowMap(MatrixMap& matrixMap, |
|
111 typename MatrixMap::FirstKey row) { |
|
112 return MatrixRowMap<MatrixMap>(matrixMap, row); |
|
113 } |
|
114 |
|
115 template <typename MatrixMap> |
|
116 ConstMatrixRowMap<MatrixMap> |
|
117 matrixRowMap(const MatrixMap& matrixMap, typename MatrixMap::FirstKey row) { |
|
118 return ConstMatrixRowMap<MatrixMap>(matrixMap, row); |
|
119 } |
|
120 |
|
121 /// \brief Map for the row view of the matrix |
|
122 /// |
|
123 /// Map for the row view of the matrix. |
|
124 template <typename _MatrixMap> |
|
125 class MatrixColMap : public MapTraits<_MatrixMap> { |
|
126 public: |
|
127 typedef _MatrixMap MatrixMap; |
|
128 typedef typename MatrixMap::FirstKey Key; |
|
129 typedef typename MatrixMap::Value Value; |
|
130 |
|
131 MatrixColMap(MatrixMap& _matrix, typename MatrixMap::SecondKey _col) |
|
132 : matrix(_matrix), col(_col) {} |
|
133 |
|
134 /// \brief Subscription operator |
|
135 /// |
|
136 /// Subscription operator. |
|
137 typename MapTraits<MatrixMap>::ReturnValue |
|
138 operator[](Key row) { |
|
139 return matrix(row, col); |
|
140 } |
|
141 |
|
142 /// \brief Setter function |
|
143 /// |
|
144 /// Setter function. |
|
145 void set(Key row, const Value& val) { |
|
146 matrix.set(row, col, val); |
|
147 } |
|
148 |
|
149 /// \brief Subscription operator |
|
150 /// |
|
151 /// Subscription operator. |
|
152 typename MapTraits<MatrixMap>::ConstReturnValue |
|
153 operator[](Key row) const { |
|
154 return matrix(row, col); |
|
155 } |
|
156 |
|
157 private: |
|
158 MatrixMap& matrix; |
|
159 typename MatrixMap::SecondKey col; |
|
160 }; |
|
161 |
|
162 /// \brief Map for the col view of the matrix |
|
163 /// |
|
164 /// Map for the col view of the matrix. |
|
165 template <typename _MatrixMap> |
|
166 class ConstMatrixColMap : public MapTraits<_MatrixMap> { |
|
167 public: |
|
168 typedef _MatrixMap MatrixMap; |
|
169 typedef typename MatrixMap::FirstKey Key; |
|
170 typedef typename MatrixMap::Value Value; |
|
171 |
|
172 ConstMatrixColMap(const MatrixMap& _matrix, |
|
173 typename MatrixMap::SecondKey _col) |
|
174 : matrix(_matrix), col(_col) {} |
|
175 |
|
176 /// \brief Subscription operator |
|
177 /// |
|
178 /// Subscription operator. |
|
179 typename MapTraits<MatrixMap>::ConstReturnValue |
|
180 operator[](Key row) const { |
|
181 return matrix(row, col); |
|
182 } |
|
183 |
|
184 private: |
|
185 const MatrixMap& matrix; |
|
186 typename MatrixMap::SecondKey col; |
|
187 }; |
|
188 |
|
189 /// \brief Gives back a col view of the matrix map |
|
190 /// |
|
191 /// Gives back a col view of the matrix map. |
|
192 template <typename MatrixMap> |
|
193 MatrixColMap<MatrixMap> matrixColMap(MatrixMap& matrixMap, |
|
194 typename MatrixMap::SecondKey col) { |
|
195 return MatrixColMap<MatrixMap>(matrixMap, col); |
|
196 } |
|
197 |
|
198 template <typename MatrixMap> |
|
199 ConstMatrixColMap<MatrixMap> |
|
200 matrixColMap(const MatrixMap& matrixMap, typename MatrixMap::SecondKey col) { |
|
201 return ConstMatrixColMap<MatrixMap>(matrixMap, col); |
|
202 } |
|
203 |
|
204 /// \brief Container for store values for each ordered pair of graph items |
|
205 /// |
|
206 /// This data structure can strore for each pair of the same item |
|
207 /// type a value. It increase the size of the container when the |
|
208 /// associated graph modified, so it updated automaticly whenever |
|
209 /// it is needed. |
|
210 template <typename _Graph, typename _Item, typename _Value> |
|
211 class DynamicMatrixMap |
|
212 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { |
|
213 public: |
|
214 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase |
|
215 Parent; |
|
216 |
|
217 typedef _Graph Graph; |
|
218 typedef _Item Key; |
|
219 |
|
220 typedef _Item FirstKey; |
|
221 typedef _Item SecondKey; |
|
222 typedef _Value Value; |
|
223 |
|
224 typedef True ReferenceMapTag; |
|
225 |
|
226 private: |
|
227 |
|
228 typedef std::vector<Value> Container; |
|
229 |
|
230 public: |
|
231 |
|
232 typedef typename Container::reference Reference; |
|
233 typedef typename Container::const_reference ConstReference; |
|
234 |
|
235 /// \brief Creates an item matrix for the given graph |
|
236 /// |
|
237 /// Creates an item matrix for the given graph. |
|
238 DynamicMatrixMap(const Graph& _graph) |
|
239 : values(size(_graph.maxId(Key()) + 1)) { |
|
240 Parent::attach(_graph.getNotifier(Key())); |
|
241 } |
|
242 |
|
243 /// \brief Creates an item matrix for the given graph |
|
244 /// |
|
245 /// Creates an item matrix for the given graph and assigns for each |
|
246 /// pairs of keys the given parameter. |
|
247 DynamicMatrixMap(const Graph& _graph, const Value& _val) |
|
248 : values(size(_graph.maxId(Key()) + 1), _val) { |
|
249 Parent::attach(_graph.getNotifier(Key())); |
|
250 } |
|
251 |
|
252 /// \brief Gives back the value assigned to the \c first - \c second |
|
253 /// ordered pair. |
|
254 /// |
|
255 /// Gives back the value assigned to the \c first - \c second ordered pair. |
|
256 ConstReference operator()(const Key& first, const Key& second) const { |
|
257 return values[index(Parent::getNotifier()->id(first), |
|
258 Parent::getNotifier()->id(second))]; |
|
259 } |
|
260 |
|
261 /// \brief Gives back the value assigned to the \c first - \c second |
|
262 /// ordered pair. |
|
263 /// |
|
264 /// Gives back the value assigned to the \c first - \c second ordered pair. |
|
265 Reference operator()(const Key& first, const Key& second) { |
|
266 return values[index(Parent::getNotifier()->id(first), |
|
267 Parent::getNotifier()->id(second))]; |
|
268 } |
|
269 |
|
270 /// \brief Setter function for the matrix map. |
|
271 /// |
|
272 /// Setter function for the matrix map. |
|
273 void set(const Key& first, const Key& second, const Value& val) { |
|
274 values[index(Parent::getNotifier()->id(first), |
|
275 Parent::getNotifier()->id(second))] = val; |
|
276 } |
|
277 |
|
278 protected: |
|
279 |
|
280 static int index(int i, int j) { |
|
281 if (i < j) { |
|
282 return j * j + i; |
|
283 } else { |
|
284 return i * i + i + j; |
|
285 } |
|
286 } |
|
287 |
|
288 static int size(int s) { |
|
289 return s * s; |
|
290 } |
|
291 |
|
292 virtual void add(const Key& key) { |
|
293 if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) { |
|
294 values.resize(size(Parent::getNotifier()->id(key) + 1)); |
|
295 } |
|
296 } |
|
297 |
|
298 virtual void erase(const Key&) {} |
|
299 |
|
300 virtual void build() { |
|
301 values.resize(size(Parent::getNotifier()->maxId() + 1)); |
|
302 } |
|
303 |
|
304 virtual void clear() { |
|
305 values.clear(); |
|
306 } |
|
307 |
|
308 private: |
|
309 std::vector<Value> values; |
|
310 }; |
|
311 |
|
312 /// \brief Container for store values for each unordered pair of graph items |
|
313 /// |
|
314 /// This data structure can strore for each pair of the same item |
|
315 /// type a value. It increase the size of the container when the |
|
316 /// associated graph modified, so it updated automaticly whenever |
|
317 /// it is needed. |
|
318 template <typename _Graph, typename _Item, typename _Value> |
|
319 class DynamicSymMatrixMap |
|
320 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase { |
|
321 public: |
|
322 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase |
|
323 Parent; |
|
324 |
|
325 typedef _Graph Graph; |
|
326 typedef _Item Key; |
|
327 |
|
328 typedef _Item FirstKey; |
|
329 typedef _Item SecondKey; |
|
330 typedef _Value Value; |
|
331 |
|
332 typedef True ReferenceMapTag; |
|
333 |
|
334 private: |
|
335 |
|
336 typedef std::vector<Value> Container; |
|
337 |
|
338 public: |
|
339 |
|
340 typedef typename Container::reference Reference; |
|
341 typedef typename Container::const_reference ConstReference; |
|
342 |
|
343 /// \brief Creates an item matrix for the given graph |
|
344 /// |
|
345 /// Creates an item matrix for the given graph. |
|
346 DynamicSymMatrixMap(const Graph& _graph) |
|
347 : values(size(_graph.maxId(Key()) + 1)) { |
|
348 Parent::attach(_graph.getNotifier(Key())); |
|
349 } |
|
350 |
|
351 /// \brief Creates an item matrix for the given graph |
|
352 /// |
|
353 /// Creates an item matrix for the given graph and assigns for each |
|
354 /// pairs of keys the given parameter. |
|
355 DynamicSymMatrixMap(const Graph& _graph, const Value& _val) |
|
356 : values(size(_graph.maxId(Key()) + 1), _val) { |
|
357 Parent::attach(_graph.getNotifier(Key())); |
|
358 } |
|
359 |
|
360 /// \brief Gives back the value assigned to the \c first - \c second |
|
361 /// unordered pair. |
|
362 /// |
|
363 /// Gives back the value assigned to the \c first - \c second unordered |
|
364 /// pair. |
|
365 ConstReference operator()(const Key& first, const Key& second) const { |
|
366 return values[index(Parent::getNotifier()->id(first), |
|
367 Parent::getNotifier()->id(second))]; |
|
368 } |
|
369 |
|
370 /// \brief Gives back the value assigned to the \c first - \c second |
|
371 /// unordered pair. |
|
372 /// |
|
373 /// Gives back the value assigned to the \c first - \c second unordered |
|
374 /// pair. |
|
375 Reference operator()(const Key& first, const Key& second) { |
|
376 return values[index(Parent::getNotifier()->id(first), |
|
377 Parent::getNotifier()->id(second))]; |
|
378 } |
|
379 |
|
380 /// \brief Setter function for the matrix map. |
|
381 /// |
|
382 /// Setter function for the matrix map. |
|
383 void set(const Key& first, const Key& second, const Value& val) { |
|
384 values[index(Parent::getNotifier()->id(first), |
|
385 Parent::getNotifier()->id(second))] = val; |
|
386 } |
|
387 |
|
388 protected: |
|
389 |
|
390 static int index(int i, int j) { |
|
391 if (i < j) { |
|
392 return j * (j + 1) / 2 + i; |
|
393 } else { |
|
394 return i * (i + 1) / 2 + j; |
|
395 } |
|
396 } |
|
397 |
|
398 static int size(int s) { |
|
399 return s * (s + 1) / 2; |
|
400 } |
|
401 |
|
402 virtual void add(const Key& key) { |
|
403 if (size(Parent::getNotifier()->id(key) + 1) >= (int)values.size()) { |
|
404 values.resize(size(Parent::getNotifier()->id(key) + 1)); |
|
405 } |
|
406 } |
|
407 |
|
408 virtual void erase(const Key&) {} |
|
409 |
|
410 virtual void build() { |
|
411 values.resize(size(Parent::getNotifier()->maxId() + 1)); |
|
412 } |
|
413 |
|
414 virtual void clear() { |
|
415 values.clear(); |
|
416 } |
|
417 |
|
418 private: |
|
419 std::vector<Value> values; |
|
420 }; |
|
421 |
|
422 } |
|
423 |
|
424 #endif |
|