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