lemon/matrix_maps.h
author deba
Wed, 01 Mar 2006 10:25:30 +0000
changeset 1991 d7442141d9ef
parent 1875 98698b69a902
child 1993 2115143eceea
permissions -rw-r--r--
The graph adadptors can be alteration observed.
In most cases it uses the adapted graph alteration notifiers.
Only special case is now the UndirGraphAdaptor, where
we have to proxy the signals from the graph.

The SubBidirGraphAdaptor is removed, because it doest not
gives more feature than the EdgeSubGraphAdaptor<UndirGraphAdaptor<Graph>>.

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