[Lemon-commits] [lemon_svn] deba: r2506 - hugo/trunk/lemon

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:53:10 CET 2006


Author: deba
Date: Tue Jan 31 20:33:48 2006
New Revision: 2506

Modified:
   hugo/trunk/lemon/graph_utils.h
   hugo/trunk/lemon/iterable_maps.h

Log:
New iterable map with comparable values
	it uses linked lists and balanced binary tree
	
IterableBoolMap has ItemIt type as the other iterable maps

InvertableMap got ValueIterator




Modified: hugo/trunk/lemon/graph_utils.h
==============================================================================
--- hugo/trunk/lemon/graph_utils.h	(original)
+++ hugo/trunk/lemon/graph_utils.h	Tue Jan 31 20:33:48 2006
@@ -886,9 +886,15 @@
   /// The InvertableMap wraps an arbitrary ReadWriteMap 
   /// and if a key is set to a new value then store it
   /// in the inverse map.
+  ///
+  /// The values of the map can be accessed
+  /// with stl compatible forward iterator.
+  ///
   /// \param _Graph The graph type.
   /// \param _Item The item type of the graph.
   /// \param _Value The value type of the map.
+  ///
+  /// \see IterableValueMap
 #ifndef DOXYGEN
   /// \param _Map A ReadWriteMap mapping from the item type to integer.
   template <
@@ -899,22 +905,83 @@
   template <typename _Graph, typename _Item, typename _Value>
 #endif
   class InvertableMap : protected _Map {
-
   public:
- 
-    typedef _Map Map;
-    typedef _Graph Graph;
 
     /// The key type of InvertableMap (Node, Edge, UEdge).
     typedef typename _Map::Key Key;
     /// The value type of the InvertableMap.
     typedef typename _Map::Value Value;
 
+  private:
+    
+    typedef _Map Map;
+    typedef _Graph Graph;
+
+    typedef std::map<Value, Key> Container;
+    Container invMap;    
+
+  public:
+ 
+
+
     /// \brief Constructor.
     ///
     /// Construct a new InvertableMap for the graph.
     ///
     InvertableMap(const Graph& graph) : Map(graph) {} 
+
+    /// \brief Forward iterator for values.
+    ///
+    /// This iterator is an stl compatible forward
+    /// iterator on the values of the map. The values can
+    /// be accessed in the [beginValue, endValue) range.
+    ///
+    class ValueIterator 
+      : public std::iterator<std::forward_iterator_tag, Value> {
+      friend class InvertableMap;
+    private:
+      ValueIterator(typename Container::const_iterator _it) 
+        : it(_it) {}
+    public:
+      
+      ValueIterator() {}
+
+      ValueIterator& operator++() { ++it; return *this; }
+      ValueIterator operator++(int) { 
+        ValueIterator tmp(*this); 
+        operator++();
+        return tmp; 
+      }
+
+      const Value& operator*() const { return it->first; }
+      const Value* operator->() const { return &(it->first); }
+
+      bool operator==(ValueIterator jt) const { return it == jt.it; }
+      bool operator!=(ValueIterator jt) const { return it != jt.it; }
+      
+    private:
+      typename Container::const_iterator it;
+    };
+
+    /// \brief Returns an iterator to the first value.
+    ///
+    /// Returns an stl compatible iterator to the 
+    /// first value of the map. The values of the
+    /// map can be accessed in the [beginValue, endValue)
+    /// range.
+    ValueIterator beginValue() const {
+      return ValueIterator(invMap.begin());
+    }
+
+    /// \brief Returns an iterator after the last value.
+    ///
+    /// Returns an stl compatible iterator after the 
+    /// last value of the map. The values of the
+    /// map can be accessed in the [beginValue, endValue)
+    /// range.
+    ValueIterator endValue() const {
+      return ValueIterator(invMap.end());
+    }
     
     /// \brief The setter function of the map.
     ///
@@ -932,7 +999,8 @@
     /// \brief The getter function of the map.
     ///
     /// It gives back the value associated with the key.
-    Value operator[](const Key& key) const {
+    typename MapTraits<Map>::ConstReturnValue 
+    operator[](const Key& key) const {
       return Map::operator[](key);
     }
 
@@ -975,11 +1043,6 @@
       Map::clear();
     }
 
-  private:
-    
-    typedef std::map<Value, Key> Container;
-    Container invMap;    
-
   public:
 
     /// \brief The inverse map type.
@@ -1140,6 +1203,13 @@
 
   public:
 
+    /// \brief Returns the maximal value plus one.
+    ///
+    /// Returns the maximal value plus one in the map.
+    unsigned int size() const {
+      return invMap.size();
+    }
+
     /// \brief Swaps the position of the two items in the map.
     ///
     /// Swaps the position of the two items in the map.
@@ -1193,7 +1263,7 @@
       /// \brief Size of the map.
       ///
       /// Returns the size of the map.
-      int size() const {
+      unsigned int size() const {
 	return inverted.invMap.size();
       }
       
@@ -1447,6 +1517,7 @@
 	Parent::add(key);
 	Parent::set(key, 0);
       }
+
       virtual void add(const std::vector<Key>& keys) {
 	Parent::add(keys);
 	for (int i = 0; i < (int)keys.size(); ++i) {
@@ -1487,10 +1558,22 @@
       ++deg[graph.target(edge)];
     }
 
+    virtual void add(const std::vector<Edge>& edges) {
+      for (int i = 0; i < (int)edges.size(); ++i) {
+        ++deg[graph.target(edges[i])];
+      }
+    }
+
     virtual void erase(const Edge& edge) {
       --deg[graph.target(edge)];
     }
 
+    virtual void erase(const std::vector<Edge>& edges) {
+      for (int i = 0; i < (int)edges.size(); ++i) {
+        --deg[graph.target(edges[i])];
+      }
+    }
+
     virtual void build() {
       for(typename _Graph::NodeIt it(graph); it != INVALID; ++it) {
 	deg[it] = countInEdges(graph, it);
@@ -1591,10 +1674,22 @@
       ++deg[graph.source(edge)];
     }
 
+    virtual void add(const std::vector<Edge>& edges) {
+      for (int i = 0; i < (int)edges.size(); ++i) {
+        ++deg[graph.source(edges[i])];
+      }
+    }
+
     virtual void erase(const Edge& edge) {
       --deg[graph.source(edge)];
     }
 
+    virtual void erase(const std::vector<Edge>& edges) {
+      for (int i = 0; i < (int)edges.size(); ++i) {
+        --deg[graph.source(edges[i])];
+      }
+    }
+
     virtual void build() {
       for(typename _Graph::NodeIt it(graph); it != INVALID; ++it) {
 	deg[it] = countOutEdges(graph, it);

Modified: hugo/trunk/lemon/iterable_maps.h
==============================================================================
--- hugo/trunk/lemon/iterable_maps.h	(original)
+++ hugo/trunk/lemon/iterable_maps.h	Tue Jan 31 20:33:48 2006
@@ -16,7 +16,11 @@
 
 #include <lemon/traits.h>
 #include <lemon/invalid.h>
+
 #include <vector>
+#include <map>
+
+#include <iterator>
 #include <limits>
 
 ///\ingroup maps
@@ -29,7 +33,7 @@
 
 namespace lemon {
 
-  ///\ingroup maps
+  ///\ingroup graph_maps
   ///
   /// \brief Dynamic iterable bool map.
   ///
@@ -45,35 +49,35 @@
     : protected ItemSetTraits<_Graph, _Item>::template Map<int>::Parent {
   private:
     typedef _Graph Graph;
-    typedef _Item Item;
     
-    typedef typename ItemSetTraits<Graph, Item>::ItemIt ItemIt;
-    typedef typename ItemSetTraits<Graph, Item>
+    typedef typename ItemSetTraits<Graph, _Item>::ItemIt KeyIt;
+    typedef typename ItemSetTraits<Graph, _Item>
     ::template Map<int>::Parent Parent;
     
-    std::vector<Item> array;
+    std::vector<_Item> array;
     int sep;
 
     const Graph& graph;
 
-  private:
-
-    int position(const Item& item) const {
-      return Parent::operator[](item);
-    }
-
   public:
 
     /// Indicates that the map if reference map.
     typedef True ReferenceMapTag;
 
     /// The key type
-    typedef Item Key;
+    typedef _Item Key;
     /// The value type
     typedef bool Value;
     /// The const reference type.    
     typedef const Value& ConstReference;
 
+  private:
+
+    int position(const Key& key) const {
+      return Parent::operator[](key);
+    }
+
+  public:
 
     /// \brief Refernce to the value of the map.
     ///
@@ -121,7 +125,7 @@
     /// Constructor of the Map with a default value.
     IterableBoolMap(const Graph& _graph, bool def = false) 
       : Parent(_graph), graph(_graph) {
-      for (ItemIt it(graph); it != INVALID; ++it) {
+      for (KeyIt it(graph); it != INVALID; ++it) {
         Parent::set(it, array.size());
         array.push_back(it);
       }
@@ -131,51 +135,51 @@
     /// \brief Const subscript operator of the map.
     ///
     /// Const subscript operator of the map.
-    bool operator[](const Item& item) const {
-      return position(item) < sep;
+    bool operator[](const Key& key) const {
+      return position(key) < sep;
     }
 
     /// \brief Subscript operator of the map.
     ///
     /// Subscript operator of the map.
-    Reference operator[](const Item& item) {
-      return Reference(*this, item);
+    Reference operator[](const Key& key) {
+      return Reference(*this, key);
     }
 
     /// \brief Set operation of the map.
     ///
     /// Set operation of the map.
-    void set(const Item& item, bool value) {
-      int pos = position(item);
+    void set(const Key& key, bool value) {
+      int pos = position(key);
       if (value) {
         if (pos < sep) return;
-        Item tmp = array[sep];
-        array[sep] = item;
-        Parent::set(item, sep);
+        Key tmp = array[sep];
+        array[sep] = key;
+        Parent::set(key, sep);
         array[pos] = tmp;
         Parent::set(tmp, pos); 
         ++sep;
       } else {
         if (pos >= sep) return;
         --sep;
-        Item tmp = array[sep];
-        array[sep] = item;
-        Parent::set(item, sep);
+        Key tmp = array[sep];
+        array[sep] = key;
+        Parent::set(key, sep);
         array[pos] = tmp;
         Parent::set(tmp, pos);
       }
     }
 
-    /// \brief Returns the number of the items mapped to true.
+    /// \brief Returns the number of the keys mapped to true.
     ///
-    /// Returns the number of the items mapped to true.
+    /// Returns the number of the keys mapped to true.
     int trueNum() const {
       return sep;
     } 
     
-    /// \brief Returns the number of the items mapped to false.
+    /// \brief Returns the number of the keys mapped to false.
     ///
-    /// Returns the number of the items mapped to false.
+    /// Returns the number of the keys mapped to false.
     int falseNum() const {
       return array.size() - sep;
     }
@@ -184,12 +188,12 @@
     ///
     /// Iterator for the keys mapped to true. It works
     /// like a graph item iterator in the map, it can be converted
-    /// the item type of the map, incremented with \c ++ operator, and
-    /// if the iterator leave the last valid item it will be equal to 
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leave the last valid key it will be equal to 
     /// \c INVALID.
-    class TrueIt : public Item {
+    class TrueIt : public Key {
     public:
-      typedef Item Parent;
+      typedef Key Parent;
       
       /// \brief Creates an iterator.
       ///
@@ -202,7 +206,7 @@
 
       /// \brief Invalid constructor \& conversion.
       ///
-      /// This constructor initializes the item to be invalid.
+      /// This constructor initializes the key to be invalid.
       /// \sa Invalid for more details.
       TrueIt(Invalid) : Parent(INVALID), map(0) {}
 
@@ -224,12 +228,12 @@
     ///
     /// Iterator for the keys mapped to false. It works
     /// like a graph item iterator in the map, it can be converted
-    /// the item type of the map, incremented with \c ++ operator, and
-    /// if the iterator leave the last valid item it will be equal to 
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leave the last valid key it will be equal to 
     /// \c INVALID.
-    class FalseIt : public Item {
+    class FalseIt : public Key {
     public:
-      typedef Item Parent;
+      typedef Key Parent;
       
       /// \brief Creates an iterator.
       ///
@@ -237,12 +241,12 @@
       /// keys which mapped to false.
       /// \param map The IterableIntMap
       FalseIt(const IterableBoolMap& _map) 
-        : Parent(_map.sep < _map.array.size() ? _map.array.back() : INVALID), 
-          map(&_map) {}
+        : Parent(_map.sep < (int)_map.array.size() ? 
+                 _map.array.back() : INVALID), map(&_map) {}
 
       /// \brief Invalid constructor \& conversion.
       ///
-      /// This constructor initializes the item to be invalid.
+      /// This constructor initializes the key to be invalid.
       /// \sa Invalid for more details.
       FalseIt(Invalid) : Parent(INVALID), map(0) {}
 
@@ -259,24 +263,66 @@
       const IterableBoolMap* map;
     };
 
+    /// \brief Iterator for the keys mapped to a given value.
+    ///
+    /// Iterator for the keys mapped to a given value. It works
+    /// like a graph item iterator in the map, it can be converted
+    /// the key type of the map, incremented with \c ++ operator, and
+    /// if the iterator leave the last valid key it will be equal to 
+    /// \c INVALID.
+    class ItemIt : public Key {
+    public:
+      typedef Key Parent;
+      
+      /// \brief Creates an iterator.
+      ///
+      /// Creates an iterator. It iterates on the 
+      /// keys which mapped to false.
+      /// \param map The IterableIntMap
+      /// \param value Which elements should be iterated.
+      ItemIt(const IterableBoolMap& _map, bool value) 
+        : Parent(value ? (_map.sep > 0 ? _map.array[_map.sep - 1] : INVALID) :
+                 (_map.sep < (int)_map.array.size() ? 
+                  _map.array.back() : INVALID)), map(&_map) {}
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the key to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), map(0) {}
+
+      /// \brief Increment operator.
+      ///
+      /// Increment Operator.
+      ItemIt& operator++() {
+        int pos = map->position(*this);
+        int sep = pos >= map->sep ? map->sep : 0;
+        Parent::operator=(pos > sep ? map->array[pos - 1] : INVALID);
+        return *this;
+      }
+
+    private:
+      const IterableBoolMap* map;
+    };
+
   protected:
     
-    virtual void add(const Item& item) {
-      Parent::add(item);
-      Parent::set(item, array.size());
-      array.push_back(item);
+    virtual void add(const Key& key) {
+      Parent::add(key);
+      Parent::set(key, array.size());
+      array.push_back(key);
     }
 
-    virtual void add(const std::vector<Item>& items) {
-      Parent::add(items);
-      for (int i = 0; i < (int)items.size(); ++i) {
-        Parent::set(items[i], array.size());
-        array.push_back(items[i]);
+    virtual void add(const std::vector<Key>& keys) {
+      Parent::add(keys);
+      for (int i = 0; i < (int)keys.size(); ++i) {
+        Parent::set(keys[i], array.size());
+        array.push_back(keys[i]);
       }
     }
 
-    virtual void erase(const Item& item) {
-      int pos = position(item); 
+    virtual void erase(const Key& key) {
+      int pos = position(key); 
       if (pos < sep) {
         --sep;
         Parent::set(array[sep], pos);
@@ -289,12 +335,12 @@
         array[pos] = array.back();
         array.pop_back();
       }
-      Parent::erase(item);
+      Parent::erase(key);
     }
 
-    virtual void erase(const std::vector<Item>& items) {
-      for (int i = 0; i < (int)items.size(); ++i) {
-        int pos = position(items[i]); 
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < (int)keys.size(); ++i) {
+        int pos = position(keys[i]); 
         if (pos < sep) {
           --sep;
           Parent::set(array[sep], pos);
@@ -308,12 +354,12 @@
           array.pop_back();
         }
       }
-      Parent::erase(items);
+      Parent::erase(keys);
     }    
 
     virtual void build() {
       Parent::build();
-      for (ItemIt it(graph); it != INVALID; ++it) {
+      for (KeyIt it(graph); it != INVALID; ++it) {
         Parent::set(it, array.size());
         array.push_back(it);
       }
@@ -339,7 +385,7 @@
     };
   }
 
-  ///\ingroup maps
+  ///\ingroup graph_maps
   ///
   /// \brief Dynamic iterable integer map.
   ///
@@ -514,8 +560,8 @@
     /// \brief Gives back the maximal value plus one.
     ///
     /// Gives back the maximal value plus one.
-    int size() const {
-      return (int)first.size();
+    unsigned int size() const {
+      return first.size();
     }
     
     /// \brief Set operation of the map.
@@ -594,7 +640,7 @@
     }
 
     virtual void erase(const std::vector<Key>& keys) {
-      for (int i = 0; i < keys.size(); ++i) {
+      for (int i = 0; i < (int)keys.size(); ++i) {
         unlace(keys[i]);
       }
       Parent::erase(keys);
@@ -609,5 +655,240 @@
     std::vector<_Item> first;
   };
 
+  namespace _iterable_maps_bits {
+    template <typename Item, typename Value>
+    struct IterableValueMapNode {
+      IterableValueMapNode(Value _value = Value()) : value(_value) {}
+      Item prev, next;
+      Value value;
+    };
+  }
+
+  ///\ingroup graph_maps
+  ///
+  /// \brief Dynamic iterable map for comparable values.
+  ///
+  /// This class provides a special graph map type which can store
+  /// for each graph item(node, edge, etc.) a value. For each
+  /// value it is possible to iterate on the keys which mapped to the 
+  /// given value. The type stores for each value a linked list with
+  /// the items which mapped to the value, and the values are stored
+  /// in balanced binary tree. The values of the map can be accessed
+  /// with stl compatible forward iterator.
+  ///
+  /// This type is not reference map so it cannot be modified with
+  /// the subscription operator.
+  ///
+  /// \see InvertableMap
+  /// 
+  /// \param _Graph The graph type.
+  /// \param _Item One of the graph's item type, the key of the map.
+  /// \param _Value Any comparable value type.
+  template <typename _Graph, typename _Item, typename _Value>
+  class IterableValueMap : protected ItemSetTraits<_Graph, _Item> 
+  ::template Map<_iterable_maps_bits::IterableValueMapNode<_Item, _Value> >
+  ::Parent {
+  public:
+    typedef typename ItemSetTraits<_Graph, _Item> 
+    ::template Map<_iterable_maps_bits::IterableValueMapNode<_Item, _Value> >
+    ::Parent Parent;
+
+    /// The key type
+    typedef _Item Key;
+    /// The value type
+    typedef _Value Value;
+    /// The graph type
+    typedef _Graph Graph;
+
+    /// \brief Constructor of the Map with a given value.
+    ///
+    /// Constructor of the Map with a given value.
+    explicit IterableValueMap(const Graph& graph, 
+                              const Value& value = Value()) 
+      : Parent(graph, _iterable_maps_bits::IterableValueMapNode<_Item, 
+               _Value>(value)) {
+      for (typename Parent::ItemIt it(*this); it != INVALID; ++it) {
+        lace(it);
+      }
+    }
+
+  private:
+    
+    void unlace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      if (node.prev != INVALID) {
+	Parent::operator[](node.prev).next = node.next;	
+      } else {
+        if (node.next != INVALID) {
+          first[node.value] = node.next;
+        } else {
+          first.erase(node.value);
+        }
+      }
+      if (node.next != INVALID) {
+	Parent::operator[](node.next).prev = node.prev;
+      }
+    }
+
+    void lace(const Key& key) {
+      typename Parent::Value& node = Parent::operator[](key);
+      typename std::map<Value, Key>::iterator it = first.find(node.value);
+      if (it == first.end()) {
+        node.prev = node.next = INVALID;
+        if (node.next != INVALID) {
+          Parent::operator[](node.next).prev = key;	
+        }
+        first.insert(make_pair(node.value, key));
+      } else {
+        node.prev = INVALID;
+        node.next = it->second;
+        if (node.next != INVALID) {
+          Parent::operator[](node.next).prev = key;	
+        }
+        it->second = key;
+      }
+    }
+
+  public:
+
+    /// \brief Forward iterator for values.
+    ///
+    /// This iterator is an stl compatible forward
+    /// iterator on the values of the map. The values can
+    /// be accessed in the [beginValue, endValue) range.
+    ///
+    class ValueIterator 
+      : public std::iterator<std::forward_iterator_tag, Value> {
+      friend class IterableValueMap;
+    private:
+      ValueIterator(typename std::map<Value, Key>::const_iterator _it) 
+        : it(_it) {}
+    public:
+      
+      ValueIterator() {}
+
+      ValueIterator& operator++() { ++it; return *this; }
+      ValueIterator operator++(int) { 
+        ValueIterator tmp(*this); 
+        operator++();
+        return tmp; 
+      }
+
+      const Value& operator*() const { return it->first; }
+      const Value* operator->() const { return &(it->first); }
+
+      bool operator==(ValueIterator jt) const { return it == jt.it; }
+      bool operator!=(ValueIterator jt) const { return it != jt.it; }
+      
+    private:
+      typename std::map<Value, Key>::const_iterator it;
+    };
+
+    /// \brief Returns an iterator to the first value.
+    ///
+    /// Returns an stl compatible iterator to the 
+    /// first value of the map. The values of the
+    /// map can be accessed in the [beginValue, endValue)
+    /// range.
+    ValueIterator beginValue() const {
+      return ValueIterator(first.begin());
+    }
+
+    /// \brief Returns an iterator after the last value.
+    ///
+    /// Returns an stl compatible iterator after the 
+    /// last value of the map. The values of the
+    /// map can be accessed in the [beginValue, endValue)
+    /// range.
+    ValueIterator endValue() const {
+      return ValueIterator(first.end());
+    }
+
+    /// \brief Set operation of the map.
+    ///
+    /// Set operation of the map.
+    void set(const Key& key, const Value& value) {
+      unlace(key);
+      Parent::operator[](key).value = value;
+      lace(key);
+    }
+
+    /// \brief Const subscript operator of the map.
+    ///
+    /// Const subscript operator of the map.
+    const Value& operator[](const Key& key) const {
+      return Parent::operator[](key).value;
+    }
+
+    /// \brief Iterator for the keys with the same value.
+    ///
+    /// Iterator for the keys with the same value. It works
+    /// like a graph item iterator in the map, it can be converted
+    /// the item type of the map, incremented with \c ++ operator, and
+    /// if the iterator leave the last valid item it will be equal to 
+    /// \c INVALID.
+    class ItemIt : public _Item {
+    public:
+      typedef _Item Parent;
+
+      /// \brief Invalid constructor \& conversion.
+      ///
+      /// This constructor initializes the item to be invalid.
+      /// \sa Invalid for more details.
+      ItemIt(Invalid) : Parent(INVALID), _map(0) {}
+
+      /// \brief Creates an iterator with a value.
+      ///
+      /// Creates an iterator with a value. It iterates on the 
+      /// keys which have the given value.
+      /// \param map The IterableValueMap
+      /// \param value The value
+      ItemIt(const IterableValueMap& map, const Value& value) : _map(&map) {
+        typename std::map<Value, Key>::const_iterator it = 
+          map.first.find(value); 
+	if (it == map.first.end()) {	  
+	  Parent::operator=(INVALID);
+	} else {
+	  Parent::operator=(it->second);
+	}
+      } 
+
+      /// \brief Increment operator.
+      ///
+      /// Increment Operator.
+      ItemIt& operator++() {
+	Parent::operator=(_map->IterableValueMap::Parent::
+			  operator[](static_cast<Parent&>(*this)).next);
+	return *this;
+      }
+
+
+    private:
+      const IterableValueMap* _map;
+    };
+
+  protected:
+    
+    virtual void erase(const Key& key) {
+      unlace(key);
+      Parent::erase(key);
+    }
+
+    virtual void erase(const std::vector<Key>& keys) {
+      for (int i = 0; i < (int)keys.size(); ++i) {
+        unlace(keys[i]);
+      }
+      Parent::erase(keys);
+    }
+
+    virtual void clear() {
+      first.clear();
+      Parent::clear();
+    }
+
+  private:
+    std::map<Value, Key> first;
+  };
+
   /// @}
 }



More information about the Lemon-commits mailing list