# HG changeset patch # User deba # Date 1128518147 0 # Node ID eb90e3d6bddc0299d3f171d7b79b5b952e37b512 # Parent 44d495c659b54a09cec5e7234aa699fcd33077ae Proper sized map type diff -r 44d495c659b5 -r eb90e3d6bddc lemon/bits/array_map.h --- a/lemon/bits/array_map.h Mon Oct 03 14:22:10 2005 +0000 +++ b/lemon/bits/array_map.h Wed Oct 05 13:15:47 2005 +0000 @@ -48,6 +48,7 @@ typedef _Item Item; public: + typedef True AdaptibleTag; /// The graph type of the maps. typedef _Graph Graph; @@ -69,6 +70,8 @@ public: + /// \brief Graph and Registry initialized map constructor. + /// /// Graph and Registry initialized map constructor. ArrayMap(const Graph& _g) : graph(&_g) { Item it; @@ -80,10 +83,9 @@ } } - /// Constructor to use default value to initialize the map. - - /// It constrates a map and initialize all of the the map. - + /// \brief Constructor to use default value to initialize the map. + /// + /// It constructs a map and initialize all of the the map. ArrayMap(const Graph& _g, const Value& _v) : graph(&_g) { Item it; attach(_g.getNotifier(_Item())); @@ -94,8 +96,9 @@ } } - /// Constructor to copy a map of the same map type. - + /// \brief Constructor to copy a map of the same map type. + /// + /// Constructor to copy a map of the same map type. ArrayMap(const ArrayMap& copy) : Parent(), graph(copy.graph) { if (copy.attached()) { attach(*copy.getRegistry()); @@ -137,35 +140,37 @@ public: - ///The subscript operator. The map can be subscripted by the - ///actual keys of the graph. - + /// \brief The subscript operator. + /// + /// The subscript operator. The map can be subscripted by the + /// actual keys of the graph. Value& operator[](const Key& key) { int id = graph->id(key); return values[id]; } - - ///The const subscript operator. The map can be subscripted by the - ///actual keys of the graph. - + /// \brief The const subscript operator. + /// + /// The const subscript operator. The map can be subscripted by the + /// actual keys of the graph. const Value& operator[](const Key& key) const { int id = graph->id(key); return values[id]; } - + + /// \brief Setter function of the map. + /// /// Setter function of the map. Equivalent with map[key] = val. /// This is a compatibility feature with the not dereferable maps. - void set(const Key& key, const Value& val) { (*this)[key] = val; } protected: - + /// Add a new key to the map. It called by the map registry. - - void add(const Key& key) { + + virtual void add(const Key& key) { int id = graph->id(key); if (id >= capacity) { int new_capacity = (capacity == 0 ? 1 : capacity); @@ -188,7 +193,7 @@ allocator.construct(&(values[id]), Value()); } - void add(const std::vector& keys) { + virtual void add(const std::vector& keys) { int max_id = -1; for (int i = 0; i < (int)keys.size(); ++i) { int id = graph->id(keys[i]); @@ -229,19 +234,19 @@ /// Erase a key from the map. It called by the map registry. - void erase(const Key& key) { + virtual void erase(const Key& key) { int id = graph->id(key); allocator.destroy(&(values[id])); } - void erase(const std::vector& keys) { + virtual void erase(const std::vector& keys) { for (int i = 0; i < (int)keys.size(); ++i) { int id = graph->id(keys[i]); allocator.destroy(&(values[id])); } } - void build() { + virtual void build() { allocate_memory(); Item it; for (graph->first(it); it != INVALID; graph->next(it)) { @@ -250,7 +255,7 @@ } } - void clear() { + virtual void clear() { if (capacity != 0) { Item it; for (graph->first(it); it != INVALID; graph->next(it)) { diff -r 44d495c659b5 -r eb90e3d6bddc lemon/bits/default_map.h --- a/lemon/bits/default_map.h Mon Oct 03 14:22:10 2005 +0000 +++ b/lemon/bits/default_map.h Wed Oct 05 13:15:47 2005 +0000 @@ -28,8 +28,6 @@ namespace lemon { - /// \addtogroup graphmapfactory - /// @{ template struct DefaultMapSelector { @@ -268,7 +266,6 @@ }; - /// @} } #endif diff -r 44d495c659b5 -r eb90e3d6bddc lemon/bits/static_map.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lemon/bits/static_map.h Wed Oct 05 13:15:47 2005 +0000 @@ -0,0 +1,348 @@ +/* -*- C++ -*- + * lemon/static_map.h - Part of LEMON, a generic C++ optimization library + * + * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport + * (Egervary Research Group on Combinatorial Optimization, EGRES). + * + * Permission to use, modify and distribute this software is granted + * provided that this copyright notice appears in all copies. For + * precise terms see the accompanying LICENSE file. + * + * This software is provided "AS IS" with no warranty of any kind, + * express or implied, and with no claim as to its suitability for any + * purpose. + * + */ + +#ifndef LEMON_STATIC_MAP_H +#define LEMON_STATIC_MAP_H + +#include +#include + +#include +#include +#include +#include +#include +#include + +/// \ingroup graphmaps +/// +///\file +///\brief Static sized graph maps. + +namespace lemon { + + /// \ingroup graphmaps + /// + /// \brief Graph map with static sized storage. + /// + /// The StaticMap template class is graph map structure what + /// does not update automatically the map when a key is added to or + /// erased from the map rather it throws an exception. This map factory + /// uses the allocators to implement the container functionality. + /// + /// \param Registry The AlterationNotifier that will notify this map. + /// \param Item The item type of the graph items. + /// \param Value The value type of the map. + /// + /// \author Balazs Dezso + + + template + class StaticMap : public AlterationNotifier<_Item>::ObserverBase { + public: + + /// \brief Exception class for unsupported exceptions. + class UnsupportedOperation : public lemon::LogicError { + public: + virtual const char* exceptionName() const { + return "lemon::StaticMap::UnsupportedOperation"; + } + }; + + typedef True AdaptibleTag; + + /// The graph type of the map. + typedef _Graph Graph; + /// The key type of the map. + typedef _Item Key; + /// The id map type of the map. + typedef AlterationNotifier<_Item> Registry; + /// The value type of the map. + typedef _Value Value; + + /// The map type. + typedef StaticMap Map; + /// The base class of the map. + typedef typename Registry::ObserverBase Parent; + + private: + + typedef std::vector Container; + + public: + + /// \brief Constructor to attach the new map into the registry. + /// + /// It constructs a map and attachs it into the registry. + /// It adds all the items of the graph to the map. + StaticMap(const Graph& _g) : graph(&_g) { + attach(_g.getNotifier(_Item())); + build(); + } + + /// \brief Constructor uses given value to initialize the map. + /// + /// It constructs a map uses a given value to initialize the map. + /// It adds all the items of the graph to the map. + StaticMap(const Graph& _g, const Value& _v) : graph(&_g) { + attach(_g.getNotifier(_Item())); + unsigned size = graph->maxId(_Item()) + 1; + container.reserve(size); + container.resize(size, _v); + } + + /// \brief Copy constructor + /// + /// Copy constructor. + StaticMap(const StaticMap& _copy) : Parent(), graph(_copy.getGraph()) { + if (_copy.attached()) { + attach(*_copy.getRegistry()); + container = _copy.container; + } + } + + /// \brief Destrcutor + /// + /// Destructor. + virtual ~StaticMap() { + clear(); + if (attached()) { + detach(); + } + } + + + private: + + StaticMap& operator=(const StaticMap&); + + protected: + + using Parent::attach; + using Parent::detach; + using Parent::attached; + + const Graph* getGraph() const { + return graph; + } + + public: + + typedef typename Container::reference Reference; + typedef typename Container::pointer Pointer; + typedef const Value ConstValue; + typedef typename Container::const_reference ConstReference; + typedef typename Container::const_pointer ConstPointer; + + /// \brief The subcript operator. + /// + /// The subscript operator. The map can be subscripted by the + /// actual items of the graph. + + Reference operator[](const Key& key) { + return container[graph->id(key)]; + } + + /// \brief The const subcript operator. + /// + /// The const subscript operator. The map can be subscripted by the + /// actual items of the graph. + + ConstReference operator[](const Key& key) const { + return container[graph->id(key)]; + } + + + /// \brief The setter function of the map. + /// + /// It the same as operator[](key) = value expression. + /// + void set(const Key& key, const Value& value) { + (*this)[key] = value; + } + + protected: + + /// \brief Adds a new key to the map. + /// + /// It adds a new key to the map. It called by the observer registry + /// and it overrides the add() member function of the observer base. + + void add(const Key&) { + throw UnsupportedOperation(); + } + + /// \brief Erases a key from the map. + /// + /// Erase a key from the map. It called by the observer registry + /// and it overrides the erase() member function of the observer base. + void erase(const Key&) { + throw UnsupportedOperation(); + } + + /// Buildes the map. + + /// It buildes the map. It called by the observer registry + /// and it overrides the build() member function of the observer base. + + void build() { + int size = graph->maxId(_Item()) + 1; + container.reserve(size); + container.resize(size); + } + + /// Clear the map. + + /// It erase all items from the map. It called by the observer registry + /// and it overrides the clear() member function of the observer base. + void clear() { + container.clear(); + } + + private: + + Container container; + const Graph *graph; + + }; + + /// \e + template + class StaticMappableGraphExtender : public _Base { + public: + + typedef StaticMappableGraphExtender<_Base> Graph; + typedef _Base Parent; + + typedef typename Parent::Node Node; + typedef typename Parent::NodeIt NodeIt; + + typedef typename Parent::Edge Edge; + typedef typename Parent::EdgeIt EdgeIt; + + + template + class NodeMap + : public IterableMapExtender > { + public: + typedef StaticMappableGraphExtender Graph; + typedef IterableMapExtender > Parent; + + NodeMap(const Graph& _g) + : Parent(_g) {} + NodeMap(const Graph& _g, const _Value& _v) + : Parent(_g, _v) {} + + NodeMap& operator=(const NodeMap& cmap) { + return operator=(cmap); + } + + + /// \brief Template assign operator. + /// + /// The given parameter should be conform to the ReadMap + /// concecpt and could be indiced by the current item set of + /// the NodeMap. In this case the value for each item + /// is assigned by the value of the given ReadMap. + template + NodeMap& operator=(const CMap& cmap) { + checkConcept, CMap>(); + const typename Parent::Graph* graph = Parent::getGraph(); + Node it; + for (graph->first(it); it != INVALID; graph->next(it)) { + Parent::set(it, cmap[it]); + } + return *this; + } + + }; + + template + class EdgeMap + : public IterableMapExtender > { + public: + typedef StaticMappableGraphExtender Graph; + typedef IterableMapExtender > Parent; + + EdgeMap(const Graph& _g) + : Parent(_g) {} + EdgeMap(const Graph& _g, const _Value& _v) + : Parent(_g, _v) {} + + EdgeMap& operator=(const EdgeMap& cmap) { + return operator=(cmap); + } + + template + EdgeMap& operator=(const CMap& cmap) { + checkConcept, CMap>(); + const typename Parent::Graph* graph = Parent::getGraph(); + Edge it; + for (graph->first(it); it != INVALID; graph->next(it)) { + Parent::set(it, cmap[it]); + } + return *this; + } + }; + + }; + + /// \e + template + class StaticMappableUndirGraphExtender : + public StaticMappableGraphExtender<_Base> { + public: + + typedef StaticMappableUndirGraphExtender Graph; + typedef StaticMappableGraphExtender<_Base> Parent; + + typedef typename Parent::UndirEdge UndirEdge; + + template + class UndirEdgeMap + : public IterableMapExtender > { + public: + typedef StaticMappableUndirGraphExtender Graph; + typedef IterableMapExtender< + StaticMap > Parent; + + UndirEdgeMap(const Graph& _g) + : Parent(_g) {} + UndirEdgeMap(const Graph& _g, const _Value& _v) + : Parent(_g, _v) {} + + UndirEdgeMap& operator=(const UndirEdgeMap& cmap) { + return operator=(cmap); + } + + template + UndirEdgeMap& operator=(const CMap& cmap) { + checkConcept, CMap>(); + const typename Parent::Graph* graph = Parent::getGraph(); + UndirEdge it; + for (graph->first(it); it != INVALID; graph->next(it)) { + Parent::set(it, cmap[it]); + } + return *this; + } + }; + + + }; + +} + +#endif diff -r 44d495c659b5 -r eb90e3d6bddc lemon/bits/vector_map.h --- a/lemon/bits/vector_map.h Mon Oct 03 14:22:10 2005 +0000 +++ b/lemon/bits/vector_map.h Wed Oct 05 13:15:47 2005 +0000 @@ -44,12 +44,11 @@ /// uses the std::vector to implement the container function. /// /// \param Registry The AlterationNotifier that will notify this map. - /// \param IdMap The IdMap type of the graph items. + /// \param Item The item type of the graph items. /// \param Value The value type of the map. /// /// \author Balazs Dezso - template < typename _Graph, typename _Item, @@ -57,6 +56,8 @@ > class VectorMap : public AlterationNotifier<_Item>::ObserverBase { public: + + typedef True AdaptibleTag; /// The graph type of the map. typedef _Graph Graph; @@ -93,26 +94,27 @@ typedef True FullTypeTag; - /// Constructor to attach the new map into the registry. - - /// It construates a map and attachs it into the registry. + /// \brief Constructor to attach the new map into the registry. + /// + /// It constructs a map and attachs it into the registry. /// It adds all the items of the graph to the map. - VectorMap(const Graph& _g) : graph(&_g) { attach(_g.getNotifier(_Item())); build(); } - /// Constructor uses given value to initialize the map. - - /// It construates a map uses a given value to initialize the map. + /// \brief Constructor uses given value to initialize the map. + /// + /// It constructs a map uses a given value to initialize the map. /// It adds all the items of the graph to the map. - VectorMap(const Graph& _g, const Value& _v) : graph(&_g) { attach(_g.getNotifier(_Item())); container.resize(graph->maxId(_Item()) + 1, _v); } + /// \brief Copy constructor + /// + /// Copy constructor. VectorMap(const VectorMap& _copy) : Parent(), graph(_copy.getGraph()) { if (_copy.attached()) { @@ -121,6 +123,9 @@ } } + /// \brief Destrcutor + /// + /// Destructor. virtual ~VectorMap() { if (attached()) { detach(); @@ -144,29 +149,26 @@ public: - /// The subcript operator. - + /// \brief The subcript operator. + /// /// The subscript operator. The map can be subscripted by the - /// actual items of the graph. - + /// actual items of the graph. Reference operator[](const Key& key) { return container[graph->id(key)]; } - /// The const subcript operator. - + /// \brief The const subcript operator. + /// /// The const subscript operator. The map can be subscripted by the /// actual items of the graph. - ConstReference operator[](const Key& key) const { return container[graph->id(key)]; } - /// The setter function of the map. - + /// \brief The setter function of the map. + /// /// It the same as operator[](key) = value expression. - /// void set(const Key& key, const Value& value) { (*this)[key] = value; } @@ -176,35 +178,33 @@ /// \brief Adds a new key to the map. /// /// It adds a new key to the map. It called by the observer registry - /// and it overrides the add() member function of the observer base. - - void add(const Key& key) { + /// and it overrides the add() member function of the observer base. + virtual void add(const Key& key) { int id = graph->id(key); if (id >= (int)container.size()) { container.resize(id + 1); } } - /// Erases a key from the map. - + /// \brief Erase a key from the map. + /// /// Erase a key from the map. It called by the observer registry /// and it overrides the erase() member function of the observer base. - void erase(const Key&) {} + virtual void erase(const Key&) {} - /// Buildes the map. - + /// \brief Buildes the map. + /// /// It buildes the map. It called by the observer registry /// and it overrides the build() member function of the observer base. - - void build() { + virtual void build() { container.resize(graph->maxId(_Item()) + 1); } - /// Clear the map. - + /// \brief Clear the map. + /// /// It erase all items from the map. It called by the observer registry /// and it overrides the clear() member function of the observer base. - void clear() { + virtual void clear() { container.clear(); } diff -r 44d495c659b5 -r eb90e3d6bddc lemon/full_graph.h --- a/lemon/full_graph.h Mon Oct 03 14:22:10 2005 +0000 +++ b/lemon/full_graph.h Wed Oct 05 13:15:47 2005 +0000 @@ -22,7 +22,7 @@ #include #include -#include +#include #include @@ -195,7 +195,7 @@ AlterableFullGraphBase; typedef IterableGraphExtender IterableFullGraphBase; - typedef MappableGraphExtender< + typedef StaticMappableGraphExtender< IterableGraphExtender< AlterableGraphExtender > > ExtendedFullGraphBase; @@ -298,10 +298,12 @@ /// It finds the first edge from \c u to \c v. Otherwise it looks for /// the next edge from \c u to \c v after \c prev. /// \return The found edge or INVALID if there is no such an edge. - Edge findEdge(Node u,Node v, Edge prev = INVALID) - { - return prev.id == -1 ? Edge(*this, u.id, v.id) : INVALID; + Edge findEdge(Node u, Node v, Edge prev = INVALID) const { + if (prev.id != -1 || u.id <= v.id) return -1; + return Edge(u.id * (u.id - 1) / 2 + v.id); } + + typedef True FindEdgeTag; class Node { @@ -328,8 +330,6 @@ Edge(int _id) : id(_id) {} - Edge(const UndirFullGraphBase& _graph, int source, int target) - : id(_graph._nodeNum * target+source) {} public: Edge() { } Edge (Invalid) { id = -1; } @@ -339,7 +339,7 @@ }; void first(Node& node) const { - node.id = _nodeNum-1; + node.id = _nodeNum - 1; } static void next(Node& node) { @@ -347,7 +347,7 @@ } void first(Edge& edge) const { - edge.id = _edgeNum-1; + edge.id = _edgeNum - 1; } static void next(Edge& edge) { @@ -355,31 +355,35 @@ } void firstOut(Edge& edge, const Node& node) const { - edge.id = node.id != 0 ? node.id * (node.id - 1) / 2 : -1; + int src = node.id; + int trg = 0; + edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1); } /// \todo with specialized iterators we can make faster iterating - void nextOut(Edge& e) const { - int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;; - int target = e.id - (source) * (source - 1) / 2; - ++target; - e.id = target < source ? source * (source - 1) / 2 + target : -1; + void nextOut(Edge& edge) const { + int src = source(edge).id; + int trg = target(edge).id; + ++trg; + edge.id = (trg < src ? src * (src - 1) / 2 + trg : -1); } void firstIn(Edge& edge, const Node& node) const { - edge.id = node.id * (node.id + 1) / 2 - 1; + int src = node.id + 1; + int trg = node.id; + edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1); } - void nextIn(Edge& e) const { - int source = ((int)sqrt((double)(1 + 8 * e.id)) + 1) / 2;; - int target = e.id - (source) * (source - 1) / 2; ++target; - ++source; - e.id = source < _nodeNum ? source * (source - 1) / 2 + target : -1; + void nextIn(Edge& edge) const { + int src = source(edge).id; + int trg = target(edge).id; + ++src; + edge.id = (src < _nodeNum ? src * (src - 1) / 2 + trg : -1); } }; - typedef MappableUndirGraphExtender< + typedef StaticMappableUndirGraphExtender< IterableUndirGraphExtender< AlterableUndirGraphExtender< UndirGraphExtender > > > ExtendedUndirFullGraphBase; diff -r 44d495c659b5 -r eb90e3d6bddc lemon/grid_graph.h --- a/lemon/grid_graph.h Mon Oct 03 14:22:10 2005 +0000 +++ b/lemon/grid_graph.h Wed Oct 05 13:15:47 2005 +0000 @@ -23,7 +23,7 @@ #include #include -#include +#include #include @@ -339,7 +339,7 @@ }; - typedef MappableUndirGraphExtender< + typedef StaticMappableUndirGraphExtender< IterableUndirGraphExtender< AlterableUndirGraphExtender< UndirGraphExtender > > > ExtendedGridGraphBase; diff -r 44d495c659b5 -r eb90e3d6bddc lemon/hypercube_graph.h --- a/lemon/hypercube_graph.h Mon Oct 03 14:22:10 2005 +0000 +++ b/lemon/hypercube_graph.h Wed Oct 05 13:15:47 2005 +0000 @@ -232,7 +232,7 @@ }; - typedef MappableGraphExtender< + typedef StaticMappableGraphExtender< IterableGraphExtender< AlterableGraphExtender< HyperCubeGraphBase > > > ExtendedHyperCubeGraphBase;