lemon/bits/vector_map.h
author Peter Kovacs <kpeter@inf.elte.hu>
Fri, 03 Apr 2009 18:59:15 +0200
changeset 608 6ac5d9ae1d3d
parent 440 88ed40ad0d4f
child 617 4137ef9aacc6
permissions -rw-r--r--
Support real types + numerical stability fix in NS (#254)

- Real types are supported by appropriate inicialization.
- A feature of the XTI spanning tree structure is removed to ensure
numerical stability (could cause problems using integer types).
The node potentials are updated always on the lower subtree,
in order to prevent overflow problems.
The former method isn't notably faster during to our tests.
alpar@209
     1
/* -*- mode: C++; indent-tabs-mode: nil; -*-
deba@57
     2
 *
alpar@209
     3
 * This file is a part of LEMON, a generic C++ optimization library.
deba@57
     4
 *
alpar@440
     5
 * Copyright (C) 2003-2009
deba@57
     6
 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
deba@57
     7
 * (Egervary Research Group on Combinatorial Optimization, EGRES).
deba@57
     8
 *
deba@57
     9
 * Permission to use, modify and distribute this software is granted
deba@57
    10
 * provided that this copyright notice appears in all copies. For
deba@57
    11
 * precise terms see the accompanying LICENSE file.
deba@57
    12
 *
deba@57
    13
 * This software is provided "AS IS" with no warranty of any kind,
deba@57
    14
 * express or implied, and with no claim as to its suitability for any
deba@57
    15
 * purpose.
deba@57
    16
 *
deba@57
    17
 */
deba@57
    18
deba@57
    19
#ifndef LEMON_BITS_VECTOR_MAP_H
deba@57
    20
#define LEMON_BITS_VECTOR_MAP_H
deba@57
    21
deba@57
    22
#include <vector>
deba@57
    23
#include <algorithm>
deba@57
    24
deba@220
    25
#include <lemon/core.h>
deba@57
    26
#include <lemon/bits/alteration_notifier.h>
deba@57
    27
deba@57
    28
#include <lemon/concept_check.h>
deba@57
    29
#include <lemon/concepts/maps.h>
deba@57
    30
kpeter@314
    31
//\ingroup graphbits
kpeter@314
    32
//
kpeter@314
    33
//\file
kpeter@314
    34
//\brief Vector based graph maps.
deba@57
    35
namespace lemon {
deba@57
    36
kpeter@314
    37
  // \ingroup graphbits
kpeter@314
    38
  //
kpeter@314
    39
  // \brief Graph map based on the std::vector storage.
kpeter@314
    40
  //
kpeter@361
    41
  // The VectorMap template class is graph map structure that automatically
kpeter@361
    42
  // updates the map when a key is added to or erased from the graph.
kpeter@361
    43
  // This map type uses std::vector to store the values.
kpeter@314
    44
  //
kpeter@314
    45
  // \tparam _Graph The graph this map is attached to.
kpeter@314
    46
  // \tparam _Item The item type of the graph items.
kpeter@314
    47
  // \tparam _Value The value type of the map.
deba@57
    48
  template <typename _Graph, typename _Item, typename _Value>
alpar@209
    49
  class VectorMap
deba@57
    50
    : public ItemSetTraits<_Graph, _Item>::ItemNotifier::ObserverBase {
deba@57
    51
  private:
alpar@209
    52
kpeter@314
    53
    // The container type of the map.
alpar@209
    54
    typedef std::vector<_Value> Container;
deba@57
    55
deba@57
    56
  public:
deba@57
    57
kpeter@314
    58
    // The graph type of the map.
deba@57
    59
    typedef _Graph Graph;
kpeter@314
    60
    // The item type of the map.
deba@57
    61
    typedef _Item Item;
kpeter@314
    62
    // The reference map tag.
deba@57
    63
    typedef True ReferenceMapTag;
deba@57
    64
kpeter@314
    65
    // The key type of the map.
deba@57
    66
    typedef _Item Key;
kpeter@314
    67
    // The value type of the map.
deba@57
    68
    typedef _Value Value;
deba@57
    69
kpeter@314
    70
    // The notifier type.
deba@57
    71
    typedef typename ItemSetTraits<_Graph, _Item>::ItemNotifier Notifier;
deba@57
    72
kpeter@314
    73
    // The map type.
deba@57
    74
    typedef VectorMap Map;
kpeter@314
    75
    // The base class of the map.
deba@57
    76
    typedef typename Notifier::ObserverBase Parent;
deba@57
    77
kpeter@314
    78
    // The reference type of the map;
deba@57
    79
    typedef typename Container::reference Reference;
kpeter@314
    80
    // The const reference type of the map;
deba@57
    81
    typedef typename Container::const_reference ConstReference;
deba@57
    82
deba@57
    83
kpeter@314
    84
    // \brief Constructor to attach the new map into the notifier.
kpeter@314
    85
    //
kpeter@314
    86
    // It constructs a map and attachs it into the notifier.
kpeter@314
    87
    // It adds all the items of the graph to the map.
deba@57
    88
    VectorMap(const Graph& graph) {
deba@57
    89
      Parent::attach(graph.notifier(Item()));
deba@57
    90
      container.resize(Parent::notifier()->maxId() + 1);
deba@57
    91
    }
deba@57
    92
kpeter@314
    93
    // \brief Constructor uses given value to initialize the map.
kpeter@314
    94
    //
kpeter@314
    95
    // It constructs a map uses a given value to initialize the map.
kpeter@314
    96
    // It adds all the items of the graph to the map.
deba@57
    97
    VectorMap(const Graph& graph, const Value& value) {
deba@57
    98
      Parent::attach(graph.notifier(Item()));
deba@57
    99
      container.resize(Parent::notifier()->maxId() + 1, value);
deba@57
   100
    }
deba@57
   101
kpeter@263
   102
  private:
kpeter@314
   103
    // \brief Copy constructor
kpeter@314
   104
    //
kpeter@314
   105
    // Copy constructor.
deba@57
   106
    VectorMap(const VectorMap& _copy) : Parent() {
deba@57
   107
      if (_copy.attached()) {
alpar@209
   108
        Parent::attach(*_copy.notifier());
alpar@209
   109
        container = _copy.container;
deba@57
   110
      }
deba@57
   111
    }
deba@57
   112
kpeter@314
   113
    // \brief Assign operator.
kpeter@314
   114
    //
kpeter@314
   115
    // This operator assigns for each item in the map the
kpeter@314
   116
    // value mapped to the same item in the copied map.
kpeter@314
   117
    // The parameter map should be indiced with the same
kpeter@314
   118
    // itemset because this assign operator does not change
kpeter@314
   119
    // the container of the map.
deba@57
   120
    VectorMap& operator=(const VectorMap& cmap) {
deba@57
   121
      return operator=<VectorMap>(cmap);
deba@57
   122
    }
deba@57
   123
deba@57
   124
kpeter@314
   125
    // \brief Template assign operator.
kpeter@314
   126
    //
kpeter@503
   127
    // The given parameter should conform to the ReadMap
kpeter@314
   128
    // concecpt and could be indiced by the current item set of
kpeter@314
   129
    // the NodeMap. In this case the value for each item
kpeter@314
   130
    // is assigned by the value of the given ReadMap.
deba@57
   131
    template <typename CMap>
deba@57
   132
    VectorMap& operator=(const CMap& cmap) {
deba@57
   133
      checkConcept<concepts::ReadMap<Key, _Value>, CMap>();
deba@57
   134
      const typename Parent::Notifier* nf = Parent::notifier();
deba@57
   135
      Item it;
deba@57
   136
      for (nf->first(it); it != INVALID; nf->next(it)) {
deba@57
   137
        set(it, cmap[it]);
deba@57
   138
      }
deba@57
   139
      return *this;
deba@57
   140
    }
alpar@209
   141
deba@57
   142
  public:
deba@57
   143
kpeter@314
   144
    // \brief The subcript operator.
kpeter@314
   145
    //
kpeter@314
   146
    // The subscript operator. The map can be subscripted by the
kpeter@314
   147
    // actual items of the graph.
deba@57
   148
    Reference operator[](const Key& key) {
deba@57
   149
      return container[Parent::notifier()->id(key)];
alpar@209
   150
    }
alpar@209
   151
kpeter@314
   152
    // \brief The const subcript operator.
kpeter@314
   153
    //
kpeter@314
   154
    // The const subscript operator. The map can be subscripted by the
kpeter@314
   155
    // actual items of the graph.
deba@57
   156
    ConstReference operator[](const Key& key) const {
deba@57
   157
      return container[Parent::notifier()->id(key)];
deba@57
   158
    }
deba@57
   159
deba@57
   160
kpeter@314
   161
    // \brief The setter function of the map.
kpeter@314
   162
    //
kpeter@314
   163
    // It the same as operator[](key) = value expression.
deba@57
   164
    void set(const Key& key, const Value& value) {
deba@57
   165
      (*this)[key] = value;
deba@57
   166
    }
deba@57
   167
deba@57
   168
  protected:
deba@57
   169
kpeter@314
   170
    // \brief Adds a new key to the map.
kpeter@314
   171
    //
kpeter@361
   172
    // It adds a new key to the map. It is called by the observer notifier
kpeter@314
   173
    // and it overrides the add() member function of the observer base.
deba@57
   174
    virtual void add(const Key& key) {
deba@57
   175
      int id = Parent::notifier()->id(key);
deba@57
   176
      if (id >= int(container.size())) {
alpar@209
   177
        container.resize(id + 1);
deba@57
   178
      }
deba@57
   179
    }
deba@57
   180
kpeter@314
   181
    // \brief Adds more new keys to the map.
kpeter@314
   182
    //
kpeter@361
   183
    // It adds more new keys to the map. It is called by the observer notifier
kpeter@314
   184
    // and it overrides the add() member function of the observer base.
deba@57
   185
    virtual void add(const std::vector<Key>& keys) {
deba@57
   186
      int max = container.size() - 1;
deba@57
   187
      for (int i = 0; i < int(keys.size()); ++i) {
deba@57
   188
        int id = Parent::notifier()->id(keys[i]);
deba@57
   189
        if (id >= max) {
deba@57
   190
          max = id;
deba@57
   191
        }
deba@57
   192
      }
deba@57
   193
      container.resize(max + 1);
deba@57
   194
    }
deba@57
   195
kpeter@314
   196
    // \brief Erase a key from the map.
kpeter@314
   197
    //
kpeter@361
   198
    // Erase a key from the map. It is called by the observer notifier
kpeter@314
   199
    // and it overrides the erase() member function of the observer base.
deba@57
   200
    virtual void erase(const Key& key) {
deba@57
   201
      container[Parent::notifier()->id(key)] = Value();
deba@57
   202
    }
deba@57
   203
kpeter@314
   204
    // \brief Erase more keys from the map.
kpeter@314
   205
    //
kpeter@361
   206
    // It erases more keys from the map. It is called by the observer notifier
kpeter@314
   207
    // and it overrides the erase() member function of the observer base.
deba@57
   208
    virtual void erase(const std::vector<Key>& keys) {
deba@57
   209
      for (int i = 0; i < int(keys.size()); ++i) {
alpar@209
   210
        container[Parent::notifier()->id(keys[i])] = Value();
deba@57
   211
      }
deba@57
   212
    }
alpar@209
   213
kpeter@361
   214
    // \brief Build the map.
kpeter@314
   215
    //
kpeter@361
   216
    // It builds the map. It is called by the observer notifier
kpeter@314
   217
    // and it overrides the build() member function of the observer base.
alpar@209
   218
    virtual void build() {
deba@57
   219
      int size = Parent::notifier()->maxId() + 1;
deba@57
   220
      container.reserve(size);
deba@57
   221
      container.resize(size);
deba@57
   222
    }
deba@57
   223
kpeter@314
   224
    // \brief Clear the map.
kpeter@314
   225
    //
kpeter@361
   226
    // It erases all items from the map. It is called by the observer notifier
kpeter@314
   227
    // and it overrides the clear() member function of the observer base.
alpar@209
   228
    virtual void clear() {
deba@57
   229
      container.clear();
deba@57
   230
    }
alpar@209
   231
deba@57
   232
  private:
alpar@209
   233
deba@57
   234
    Container container;
deba@57
   235
deba@57
   236
  };
deba@57
   237
deba@57
   238
}
deba@57
   239
deba@57
   240
#endif