lemon/matrix_maps.h
author deba
Mon, 27 Feb 2006 10:17:33 +0000
changeset 1985 8782ff6fd98a
parent 1875 98698b69a902
child 1993 2115143eceea
permissions -rw-r--r--
Bug fix
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