3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
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.
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
19 #ifndef LEMON_MATRIX_MAPS_H
20 #define LEMON_MATRIX_MAPS_H
24 #include <lemon/bits/utility.h>
25 #include <lemon/maps.h>
30 /// \brief Maps indexed with pairs of items.
32 /// \todo This file has the same name as the concept file in concept/,
33 /// and this is not easily detectable in docs...
36 /// \brief Map for the coloumn view of the matrix
38 /// Map for the coloumn view of the matrix.
39 template <typename _MatrixMap>
40 class MatrixRowMap : public MapTraits<_MatrixMap> {
42 typedef _MatrixMap MatrixMap;
43 typedef typename MatrixMap::SecondKey Key;
44 typedef typename MatrixMap::Value Value;
47 MatrixRowMap(MatrixMap& _matrix, typename MatrixMap::FirstKey _row)
48 : matrix(_matrix), row(_row) {}
50 /// \brief Subscription operator
52 /// Subscription operator.
53 typename MapTraits<MatrixMap>::ReturnValue
55 return matrix(row, col);
58 /// \brief Setter function
61 void set(Key col, const Value& val) {
62 matrix.set(row, col, val);
65 /// \brief Subscription operator
67 /// Subscription operator.
68 typename MapTraits<MatrixMap>::ConstReturnValue
69 operator[](Key col) const {
70 return matrix(row, col);
75 typename MatrixMap::FirstKey row;
78 /// \brief Map for the row view of the matrix
80 /// Map for the row view of the matrix.
81 template <typename _MatrixMap>
82 class ConstMatrixRowMap : public MapTraits<_MatrixMap> {
84 typedef _MatrixMap MatrixMap;
85 typedef typename MatrixMap::SecondKey Key;
86 typedef typename MatrixMap::Value Value;
89 ConstMatrixRowMap(const MatrixMap& _matrix,
90 typename MatrixMap::FirstKey _row)
91 : matrix(_matrix), row(_row) {}
93 /// \brief Subscription operator
95 /// Subscription operator.
96 typename MapTraits<MatrixMap>::ConstReturnValue
97 operator[](Key col) const {
98 return matrix(row, col);
102 const MatrixMap& matrix;
103 typename MatrixMap::FirstKey row;
106 /// \brief Gives back a row view of the matrix map
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);
115 template <typename MatrixMap>
116 ConstMatrixRowMap<MatrixMap>
117 matrixRowMap(const MatrixMap& matrixMap, typename MatrixMap::FirstKey row) {
118 return ConstMatrixRowMap<MatrixMap>(matrixMap, row);
121 /// \brief Map for the row view of the matrix
123 /// Map for the row view of the matrix.
124 template <typename _MatrixMap>
125 class MatrixColMap : public MapTraits<_MatrixMap> {
127 typedef _MatrixMap MatrixMap;
128 typedef typename MatrixMap::FirstKey Key;
129 typedef typename MatrixMap::Value Value;
131 MatrixColMap(MatrixMap& _matrix, typename MatrixMap::SecondKey _col)
132 : matrix(_matrix), col(_col) {}
134 /// \brief Subscription operator
136 /// Subscription operator.
137 typename MapTraits<MatrixMap>::ReturnValue
138 operator[](Key row) {
139 return matrix(row, col);
142 /// \brief Setter function
145 void set(Key row, const Value& val) {
146 matrix.set(row, col, val);
149 /// \brief Subscription operator
151 /// Subscription operator.
152 typename MapTraits<MatrixMap>::ConstReturnValue
153 operator[](Key row) const {
154 return matrix(row, col);
159 typename MatrixMap::SecondKey col;
162 /// \brief Map for the col view of the matrix
164 /// Map for the col view of the matrix.
165 template <typename _MatrixMap>
166 class ConstMatrixColMap : public MapTraits<_MatrixMap> {
168 typedef _MatrixMap MatrixMap;
169 typedef typename MatrixMap::FirstKey Key;
170 typedef typename MatrixMap::Value Value;
172 ConstMatrixColMap(const MatrixMap& _matrix,
173 typename MatrixMap::SecondKey _col)
174 : matrix(_matrix), col(_col) {}
176 /// \brief Subscription operator
178 /// Subscription operator.
179 typename MapTraits<MatrixMap>::ConstReturnValue
180 operator[](Key row) const {
181 return matrix(row, col);
185 const MatrixMap& matrix;
186 typename MatrixMap::SecondKey col;
189 /// \brief Gives back a col view of the matrix map
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);
198 template <typename MatrixMap>
199 ConstMatrixColMap<MatrixMap>
200 matrixColMap(const MatrixMap& matrixMap, typename MatrixMap::SecondKey col) {
201 return ConstMatrixColMap<MatrixMap>(matrixMap, col);
204 /// \brief Container for store values for each ordered pair of graph items
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
210 template <typename _Graph, typename _Item, typename _Value>
211 class DynamicMatrixMap
212 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
214 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase
217 typedef _Graph Graph;
220 typedef _Item FirstKey;
221 typedef _Item SecondKey;
222 typedef _Value Value;
224 typedef True ReferenceMapTag;
228 typedef std::vector<Value> Container;
232 typedef typename Container::reference Reference;
233 typedef typename Container::const_reference ConstReference;
235 /// \brief Creates an item matrix for the given graph
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()));
243 /// \brief Creates an item matrix for the given graph
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()));
252 /// \brief Gives back the value assigned to the \c first - \c second
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))];
261 /// \brief Gives back the value assigned to the \c first - \c second
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))];
270 /// \brief Setter function for the matrix map.
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;
280 static int index(int i, int j) {
284 return i * i + i + j;
288 static int size(int s) {
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));
298 virtual void erase(const Key&) {}
300 virtual void build() {
301 values.resize(size(Parent::getNotifier()->maxId() + 1));
304 virtual void clear() {
309 std::vector<Value> values;
312 /// \brief Container for store values for each unordered pair of graph items
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
318 template <typename _Graph, typename _Item, typename _Value>
319 class DynamicSymMatrixMap
320 : protected ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
322 typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase
325 typedef _Graph Graph;
328 typedef _Item FirstKey;
329 typedef _Item SecondKey;
330 typedef _Value Value;
332 typedef True ReferenceMapTag;
336 typedef std::vector<Value> Container;
340 typedef typename Container::reference Reference;
341 typedef typename Container::const_reference ConstReference;
343 /// \brief Creates an item matrix for the given graph
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()));
351 /// \brief Creates an item matrix for the given graph
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()));
360 /// \brief Gives back the value assigned to the \c first - \c second
363 /// Gives back the value assigned to the \c first - \c second unordered
365 ConstReference operator()(const Key& first, const Key& second) const {
366 return values[index(Parent::getNotifier()->id(first),
367 Parent::getNotifier()->id(second))];
370 /// \brief Gives back the value assigned to the \c first - \c second
373 /// Gives back the value assigned to the \c first - \c second unordered
375 Reference operator()(const Key& first, const Key& second) {
376 return values[index(Parent::getNotifier()->id(first),
377 Parent::getNotifier()->id(second))];
380 /// \brief Setter function for the matrix map.
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;
390 static int index(int i, int j) {
392 return j * (j + 1) / 2 + i;
394 return i * (i + 1) / 2 + j;
398 static int size(int s) {
399 return s * (s + 1) / 2;
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));
408 virtual void erase(const Key&) {}
410 virtual void build() {
411 values.resize(size(Parent::getNotifier()->maxId() + 1));
414 virtual void clear() {
419 std::vector<Value> values;