klao@946: /* -*- C++ -*- ladanyi@1435: * lemon/graph_utils.h - Part of LEMON, a generic C++ optimization library klao@946: * alpar@1164: * Copyright (C) 2005 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport alpar@1359: * (Egervary Research Group on Combinatorial Optimization, EGRES). klao@946: * klao@946: * Permission to use, modify and distribute this software is granted klao@946: * provided that this copyright notice appears in all copies. For klao@946: * precise terms see the accompanying LICENSE file. klao@946: * klao@946: * This software is provided "AS IS" with no warranty of any kind, klao@946: * express or implied, and with no claim as to its suitability for any klao@946: * purpose. klao@946: * klao@946: */ klao@946: klao@946: #ifndef LEMON_GRAPH_UTILS_H klao@946: #define LEMON_GRAPH_UTILS_H klao@946: klao@946: #include deba@1419: #include alpar@1402: #include klao@946: klao@946: #include klao@977: #include deba@1413: #include alpar@1459: #include klao@946: alpar@947: ///\ingroup gutils klao@946: ///\file alpar@947: ///\brief Graph utilities. klao@946: /// alpar@964: ///\todo Please alpar@964: ///revise the documentation. alpar@964: /// klao@946: klao@946: klao@946: namespace lemon { klao@946: deba@1267: /// \addtogroup gutils deba@1267: /// @{ alpar@947: klao@946: /// \brief Function to count the items in the graph. klao@946: /// klao@946: /// This function counts the items in the graph. klao@946: /// The complexity of the function is O(n) because klao@946: /// it iterates on all of the items. klao@946: klao@946: template klao@977: inline int countItems(const Graph& g) { klao@946: int num = 0; klao@977: for (ItemIt it(g); it != INVALID; ++it) { klao@946: ++num; klao@946: } klao@946: return num; klao@946: } klao@946: klao@977: // Node counting: klao@977: klao@977: template klao@977: inline klao@977: typename enable_if::type klao@977: _countNodes(const Graph &g) { klao@977: return g.nodeNum(); klao@977: } klao@977: klao@977: template klao@977: inline int _countNodes(Wrap w) { klao@977: return countItems(w.value); klao@977: } klao@977: klao@946: /// \brief Function to count the nodes in the graph. klao@946: /// klao@946: /// This function counts the nodes in the graph. klao@946: /// The complexity of the function is O(n) but for some alpar@964: /// graph structure it is specialized to run in O(1). klao@977: /// klao@977: /// \todo refer how to specialize it klao@946: klao@946: template klao@977: inline int countNodes(const Graph& g) { klao@977: return _countNodes(g); klao@977: } klao@977: klao@977: // Edge counting: klao@977: klao@977: template klao@977: inline klao@977: typename enable_if::type klao@977: _countEdges(const Graph &g) { klao@977: return g.edgeNum(); klao@977: } klao@977: klao@977: template klao@977: inline int _countEdges(Wrap w) { klao@977: return countItems(w.value); klao@946: } klao@946: klao@946: /// \brief Function to count the edges in the graph. klao@946: /// klao@946: /// This function counts the edges in the graph. klao@946: /// The complexity of the function is O(e) but for some alpar@964: /// graph structure it is specialized to run in O(1). klao@977: klao@946: template klao@977: inline int countEdges(const Graph& g) { klao@977: return _countEdges(g); klao@946: } klao@946: klao@1053: // Undirected edge counting: klao@1053: klao@1053: template klao@1053: inline klao@1053: typename enable_if::type klao@1053: _countUndirEdges(const Graph &g) { klao@1053: return g.undirEdgeNum(); klao@1053: } klao@1053: klao@1053: template klao@1053: inline int _countUndirEdges(Wrap w) { klao@1053: return countItems(w.value); klao@1053: } klao@1053: klao@1053: /// \brief Function to count the edges in the graph. klao@946: /// klao@1053: /// This function counts the edges in the graph. klao@946: /// The complexity of the function is O(e) but for some alpar@964: /// graph structure it is specialized to run in O(1). klao@1053: klao@946: template klao@1053: inline int countUndirEdges(const Graph& g) { klao@1053: return _countUndirEdges(g); klao@946: } klao@946: klao@977: klao@1053: klao@946: template klao@946: inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) { klao@946: int num = 0; klao@946: for (DegIt it(_g, _n); it != INVALID; ++it) { klao@946: ++num; klao@946: } klao@946: return num; klao@946: } alpar@967: alpar@967: /// Finds an edge between two nodes of a graph. alpar@967: alpar@967: /// Finds an edge from node \c u to node \c v in graph \c g. alpar@967: /// alpar@967: /// If \c prev is \ref INVALID (this is the default value), then alpar@967: /// it finds the first edge from \c u to \c v. Otherwise it looks for alpar@967: /// the next edge from \c u to \c v after \c prev. alpar@967: /// \return The found edge or \ref INVALID if there is no such an edge. alpar@967: /// alpar@967: /// Thus you can iterate through each edge from \c u to \c v as it follows. alpar@967: /// \code alpar@967: /// for(Edge e=findEdge(g,u,v);e!=INVALID;e=findEdge(g,u,v,e)) { alpar@967: /// ... alpar@967: /// } alpar@967: /// \endcode alpar@967: /// \todo We may want to use the \ref concept::GraphBase "GraphBase" alpar@967: /// interface here... alpar@967: /// \bug Untested ... alpar@967: template alpar@967: typename Graph::Edge findEdge(const Graph &g, deba@1267: typename Graph::Node u, typename Graph::Node v, deba@1267: typename Graph::Edge prev = INVALID) alpar@967: { alpar@967: typename Graph::OutEdgeIt e(g,prev); alpar@1079: // if(prev==INVALID) g.first(e,u); alpar@1079: if(prev==INVALID) e=typename Graph::OutEdgeIt(g,u); alpar@967: else ++e; alpar@1079: while(e!=INVALID && g.target(e)!=v) ++e; alpar@967: return e; alpar@967: } alpar@964: alpar@964: ///\e klao@946: alpar@964: ///\todo Please document. alpar@964: /// klao@946: template klao@946: inline int countOutEdges(const Graph& _g, const typename Graph::Node& _n) { klao@946: return countNodeDegree(_g, _n); klao@946: } klao@946: alpar@964: ///\e alpar@964: alpar@964: ///\todo Please document. alpar@964: /// klao@946: template klao@946: inline int countInEdges(const Graph& _g, const typename Graph::Node& _n) { klao@946: return countNodeDegree(_g, _n); klao@946: } klao@946: klao@946: // graph copy klao@946: klao@946: template < klao@946: typename DestinationGraph, klao@946: typename SourceGraph, klao@946: typename NodeBijection> klao@946: void copyNodes(DestinationGraph& _d, const SourceGraph& _s, klao@946: NodeBijection& _nb) { klao@946: for (typename SourceGraph::NodeIt it(_s); it != INVALID; ++it) { klao@946: _nb[it] = _d.addNode(); klao@946: } klao@946: } klao@946: klao@946: template < klao@946: typename DestinationGraph, klao@946: typename SourceGraph, klao@946: typename NodeBijection, klao@946: typename EdgeBijection> klao@946: void copyEdges(DestinationGraph& _d, const SourceGraph& _s, klao@946: const NodeBijection& _nb, EdgeBijection& _eb) { klao@946: for (typename SourceGraph::EdgeIt it(_s); it != INVALID; ++it) { alpar@986: _eb[it] = _d.addEdge(_nb[_s.source(it)], _nb[_s.target(it)]); klao@946: } klao@946: } klao@946: klao@946: template < klao@946: typename DestinationGraph, klao@946: typename SourceGraph, klao@946: typename NodeBijection, klao@946: typename EdgeBijection> klao@946: void copyGraph(DestinationGraph& _d, const SourceGraph& _s, klao@946: NodeBijection& _nb, EdgeBijection& _eb) { klao@946: nodeCopy(_d, _s, _nb); klao@946: edgeCopy(_d, _s, _nb, _eb); klao@946: } klao@946: deba@1267: template < klao@946: typename _DestinationGraph, klao@946: typename _SourceGraph, klao@946: typename _NodeBijection klao@946: =typename _SourceGraph::template NodeMap, klao@946: typename _EdgeBijection deba@1267: = typename _SourceGraph::template EdgeMap deba@1267: > deba@1267: class GraphCopy { deba@1267: public: deba@1267: deba@1267: typedef _DestinationGraph DestinationGraph; deba@1267: typedef _SourceGraph SourceGraph; klao@946: deba@1267: typedef _NodeBijection NodeBijection; deba@1267: typedef _EdgeBijection EdgeBijection; deba@1267: deba@1267: protected: deba@1267: deba@1267: NodeBijection node_bijection; deba@1267: EdgeBijection edge_bijection; klao@946: deba@1267: public: deba@1267: deba@1267: GraphCopy(DestinationGraph& _d, const SourceGraph& _s) { deba@1267: copyGraph(_d, _s, node_bijection, edge_bijection); deba@1267: } deba@1267: deba@1267: const NodeBijection& getNodeBijection() const { deba@1267: return node_bijection; deba@1267: } klao@946: deba@1267: const EdgeBijection& getEdgeBijection() const { deba@1267: return edge_bijection; deba@1267: } deba@1267: deba@1267: }; klao@946: klao@946: deba@1267: template deba@1419: class ItemSetTraits {}; deba@1192: deba@1192: template deba@1267: class ItemSetTraits<_Graph, typename _Graph::Node> { deba@1192: public: deba@1192: deba@1192: typedef _Graph Graph; alpar@947: deba@1192: typedef typename Graph::Node Item; deba@1192: typedef typename Graph::NodeIt ItemIt; deba@1192: deba@1192: template deba@1192: class Map : public Graph::template NodeMap<_Value> { deba@1192: public: deba@1192: typedef typename Graph::template NodeMap<_Value> Parent; deba@1192: typedef typename Parent::Value Value; deba@1192: deba@1192: Map(const Graph& _graph) : Parent(_graph) {} deba@1192: Map(const Graph& _graph, const Value& _value) deba@1192: : Parent(_graph, _value) {} deba@1192: }; deba@1192: deba@1192: }; deba@1192: deba@1192: template deba@1267: class ItemSetTraits<_Graph, typename _Graph::Edge> { deba@1192: public: deba@1192: deba@1192: typedef _Graph Graph; deba@1192: deba@1192: typedef typename Graph::Edge Item; deba@1192: typedef typename Graph::EdgeIt ItemIt; deba@1192: deba@1192: template deba@1192: class Map : public Graph::template EdgeMap<_Value> { deba@1192: public: deba@1192: typedef typename Graph::template EdgeMap<_Value> Parent; deba@1192: typedef typename Parent::Value Value; deba@1192: deba@1192: Map(const Graph& _graph) : Parent(_graph) {} deba@1192: Map(const Graph& _graph, const Value& _value) deba@1192: : Parent(_graph, _value) {} deba@1192: }; deba@1192: deba@1192: }; deba@1192: deba@1267: template deba@1267: class ItemSetTraits<_Graph, typename _Graph::UndirEdge> { deba@1267: public: deba@1267: deba@1267: typedef _Graph Graph; deba@1267: deba@1267: typedef typename Graph::UndirEdge Item; deba@1267: typedef typename Graph::UndirEdgeIt ItemIt; deba@1267: deba@1267: template deba@1267: class Map : public Graph::template UndirEdgeMap<_Value> { deba@1267: public: deba@1267: typedef typename Graph::template UndirEdgeMap<_Value> Parent; deba@1267: typedef typename Parent::Value Value; deba@1267: deba@1267: Map(const Graph& _graph) : Parent(_graph) {} deba@1267: Map(const Graph& _graph, const Value& _value) deba@1267: : Parent(_graph, _value) {} deba@1267: }; deba@1267: deba@1267: }; deba@1192: deba@1192: /// @} alpar@1402: alpar@1402: /// \addtogroup graph_maps alpar@1402: /// @{ alpar@1402: alpar@1402: template alpar@1402: struct ReferenceMapTraits { alpar@1402: typedef typename Map::Value Value; alpar@1402: typedef typename Map::Value& Reference; alpar@1402: typedef const typename Map::Value& ConstReference; alpar@1402: typedef typename Map::Value* Pointer; alpar@1402: typedef const typename Map::Value* ConstPointer; alpar@1402: }; alpar@1402: alpar@1402: template alpar@1402: struct ReferenceMapTraits< alpar@1402: Map, alpar@1402: typename enable_if::type alpar@1402: > { alpar@1402: typedef typename Map::Value Value; alpar@1402: typedef typename Map::Reference Reference; alpar@1402: typedef typename Map::ConstReference ConstReference; alpar@1402: typedef typename Map::Pointer Pointer; alpar@1402: typedef typename Map::ConstPointer ConstPointer; alpar@1402: }; alpar@1402: deba@1413: /// Provides an immutable and unique id for each item in the graph. deba@1413: deba@1413: /// The IdMap class provides an unique and immutable mapping for each item deba@1413: /// in the graph. deba@1413: /// deba@1413: template deba@1413: class IdMap { deba@1413: public: deba@1413: typedef _Graph Graph; deba@1413: typedef int Value; deba@1413: typedef _Item Item; deba@1413: typedef _Item Key; deba@1413: deba@1419: typedef True NeedCopy; deba@1419: deba@1413: /// \brief Constructor. deba@1413: /// deba@1413: /// Constructor for creating id map. deba@1413: IdMap(const Graph& _graph) : graph(&_graph) {} deba@1413: deba@1413: /// \brief Gives back the \e id of the item. deba@1413: /// deba@1413: /// Gives back the immutable and unique \e id of the map. deba@1413: int operator[](const Item& item) const { return graph->id(item);} deba@1413: deba@1413: deba@1413: private: deba@1413: const Graph* graph; deba@1413: deba@1413: public: deba@1413: deba@1413: /// \brief The class represents the inverse of the map. deba@1413: /// deba@1413: /// The class represents the inverse of the map. deba@1413: /// \see inverse() deba@1413: class InverseMap { deba@1413: public: deba@1419: deba@1419: typedef True NeedCopy; deba@1419: deba@1413: /// \brief Constructor. deba@1413: /// deba@1413: /// Constructor for creating an id-to-item map. deba@1413: InverseMap(const Graph& _graph) : graph(&_graph) {} deba@1413: deba@1413: /// \brief Constructor. deba@1413: /// deba@1413: /// Constructor for creating an id-to-item map. deba@1413: InverseMap(const IdMap& idMap) : graph(idMap.graph) {} deba@1413: deba@1413: /// \brief Gives back the given item from its id. deba@1413: /// deba@1413: /// Gives back the given item from its id. deba@1413: /// deba@1413: Item operator[](int id) const { return graph->fromId(id, Item());} deba@1413: private: deba@1413: const Graph* graph; deba@1413: }; deba@1413: deba@1413: /// \brief Gives back the inverse of the map. deba@1413: /// deba@1413: /// Gives back the inverse of the map. deba@1413: InverseMap inverse() const { return InverseMap(*graph);} deba@1413: deba@1413: }; deba@1413: deba@1413: alpar@1402: /// \brief General inversable graph-map type. alpar@1402: alpar@1402: /// This type provides simple inversable map functions. alpar@1402: /// The InversableMap wraps an arbitrary ReadWriteMap alpar@1402: /// and if a key is setted to a new value then store it alpar@1402: /// in the inverse map. alpar@1402: /// \param _Graph The graph type. alpar@1402: /// \param _Map The map to extend with inversable functionality. alpar@1402: template < alpar@1402: typename _Graph, alpar@1402: typename _Item, alpar@1402: typename _Value, alpar@1402: typename _Map deba@1413: = typename ItemSetTraits<_Graph, _Item>::template Map<_Value>::Parent alpar@1402: > deba@1413: class InvertableMap : protected _Map { alpar@1402: alpar@1402: public: alpar@1402: alpar@1402: typedef _Map Map; alpar@1402: typedef _Graph Graph; deba@1413: deba@1413: /// The key type of InvertableMap (Node, Edge, UndirEdge). alpar@1402: typedef typename _Map::Key Key; deba@1413: /// The value type of the InvertableMap. alpar@1402: typedef typename _Map::Value Value; alpar@1402: alpar@1402: /// \brief Constructor. alpar@1402: /// deba@1413: /// Construct a new InvertableMap for the graph. alpar@1402: /// deba@1413: InvertableMap(const Graph& graph) : Map(graph) {} alpar@1402: alpar@1402: /// \brief The setter function of the map. alpar@1402: /// deba@1413: /// Sets the mapped value. alpar@1402: void set(const Key& key, const Value& val) { alpar@1402: Value oldval = Map::operator[](key); deba@1413: typename Container::iterator it = invMap.find(oldval); alpar@1402: if (it != invMap.end() && it->second == key) { alpar@1402: invMap.erase(it); alpar@1402: } alpar@1402: invMap.insert(make_pair(val, key)); alpar@1402: Map::set(key, val); alpar@1402: } alpar@1402: alpar@1402: /// \brief The getter function of the map. alpar@1402: /// alpar@1402: /// It gives back the value associated with the key. deba@1413: const Value operator[](const Key& key) const { alpar@1402: return Map::operator[](key); alpar@1402: } alpar@1402: alpar@1402: /// \brief Add a new key to the map. alpar@1402: /// alpar@1402: /// Add a new key to the map. It is called by the alpar@1402: /// \c AlterationNotifier. alpar@1402: virtual void add(const Key& key) { alpar@1402: Map::add(key); alpar@1402: } alpar@1402: alpar@1402: /// \brief Erase the key from the map. alpar@1402: /// alpar@1402: /// Erase the key to the map. It is called by the alpar@1402: /// \c AlterationNotifier. alpar@1402: virtual void erase(const Key& key) { alpar@1402: Value val = Map::operator[](key); deba@1413: typename Container::iterator it = invMap.find(val); alpar@1402: if (it != invMap.end() && it->second == key) { alpar@1402: invMap.erase(it); alpar@1402: } alpar@1402: Map::erase(key); alpar@1402: } alpar@1402: alpar@1402: /// \brief Clear the keys from the map and inverse map. alpar@1402: /// alpar@1402: /// Clear the keys from the map and inverse map. It is called by the alpar@1402: /// \c AlterationNotifier. alpar@1402: virtual void clear() { alpar@1402: invMap.clear(); alpar@1402: Map::clear(); alpar@1402: } alpar@1402: deba@1413: private: deba@1413: deba@1413: typedef std::map Container; deba@1413: Container invMap; deba@1413: deba@1413: public: deba@1413: deba@1413: /// \brief The inverse map type. deba@1413: /// deba@1413: /// The inverse of this map. The subscript operator of the map deba@1413: /// gives back always the item what was last assigned to the value. deba@1413: class InverseMap { deba@1413: public: deba@1413: /// \brief Constructor of the InverseMap. deba@1413: /// deba@1413: /// Constructor of the InverseMap. deba@1413: InverseMap(const InvertableMap& _inverted) : inverted(_inverted) {} deba@1413: deba@1413: /// The value type of the InverseMap. deba@1413: typedef typename InvertableMap::Key Value; deba@1413: /// The key type of the InverseMap. deba@1413: typedef typename InvertableMap::Value Key; deba@1413: deba@1413: /// \brief Subscript operator. deba@1413: /// deba@1413: /// Subscript operator. It gives back always the item deba@1413: /// what was last assigned to the value. deba@1413: Value operator[](const Key& key) const { deba@1413: typename Container::const_iterator it = inverted.invMap.find(key); deba@1413: return it->second; deba@1413: } deba@1413: deba@1413: private: deba@1413: const InvertableMap& inverted; deba@1413: }; deba@1413: alpar@1402: /// \brief It gives back the just readeable inverse map. alpar@1402: /// alpar@1402: /// It gives back the just readeable inverse map. deba@1413: InverseMap inverse() const { deba@1413: return InverseMap(*this); alpar@1402: } alpar@1402: alpar@1402: deba@1413: alpar@1402: }; alpar@1402: alpar@1402: /// \brief Provides a mutable, continuous and unique descriptor for each alpar@1402: /// item in the graph. alpar@1402: /// alpar@1402: /// The DescriptorMap class provides a mutable, continuous and immutable deba@1413: /// mapping for each item in the graph. The value for an item may mutated deba@1413: /// on each operation when the an item erased or added to graph. alpar@1402: /// alpar@1402: /// \param _Graph The graph class the \c DescriptorMap belongs to. alpar@1402: /// \param _Item The Item is the Key of the Map. It may be Node, Edge or alpar@1402: /// UndirEdge. alpar@1402: /// \param _Map A ReadWriteMap mapping from the item type to integer. alpar@1402: template < alpar@1402: typename _Graph, alpar@1402: typename _Item, deba@1413: typename _Map deba@1413: = typename ItemSetTraits<_Graph, _Item>::template Map::Parent alpar@1402: > alpar@1402: class DescriptorMap : protected _Map { alpar@1402: alpar@1402: typedef _Item Item; alpar@1402: typedef _Map Map; alpar@1402: alpar@1402: public: alpar@1402: /// The graph class of DescriptorMap. alpar@1402: typedef _Graph Graph; alpar@1402: alpar@1402: /// The key type of DescriptorMap (Node, Edge, UndirEdge). alpar@1402: typedef typename _Map::Key Key; alpar@1402: /// The value type of DescriptorMap. alpar@1402: typedef typename _Map::Value Value; alpar@1402: alpar@1402: /// \brief Constructor. alpar@1402: /// deba@1413: /// Constructor for descriptor map. alpar@1402: DescriptorMap(const Graph& _graph) : Map(_graph) { alpar@1402: build(); alpar@1402: } alpar@1402: alpar@1402: /// \brief Add a new key to the map. alpar@1402: /// alpar@1402: /// Add a new key to the map. It is called by the alpar@1402: /// \c AlterationNotifier. alpar@1402: virtual void add(const Item& item) { alpar@1402: Map::add(item); alpar@1402: Map::set(item, invMap.size()); alpar@1402: invMap.push_back(item); alpar@1402: } alpar@1402: alpar@1402: /// \brief Erase the key from the map. alpar@1402: /// alpar@1402: /// Erase the key to the map. It is called by the alpar@1402: /// \c AlterationNotifier. alpar@1402: virtual void erase(const Item& item) { alpar@1402: Map::set(invMap.back(), Map::operator[](item)); alpar@1402: invMap[Map::operator[](item)] = invMap.back(); deba@1413: invMap.pop_back(); alpar@1402: Map::erase(item); alpar@1402: } alpar@1402: alpar@1402: /// \brief Build the unique map. alpar@1402: /// alpar@1402: /// Build the unique map. It is called by the alpar@1402: /// \c AlterationNotifier. alpar@1402: virtual void build() { alpar@1402: Map::build(); alpar@1402: Item it; alpar@1402: const typename Map::Graph* graph = Map::getGraph(); alpar@1402: for (graph->first(it); it != INVALID; graph->next(it)) { alpar@1402: Map::set(it, invMap.size()); alpar@1402: invMap.push_back(it); alpar@1402: } alpar@1402: } alpar@1402: alpar@1402: /// \brief Clear the keys from the map. alpar@1402: /// alpar@1402: /// Clear the keys from the map. It is called by the alpar@1402: /// \c AlterationNotifier. alpar@1402: virtual void clear() { alpar@1402: invMap.clear(); alpar@1402: Map::clear(); alpar@1402: } alpar@1402: alpar@1402: /// \brief Gives back the \e descriptor of the item. alpar@1402: /// alpar@1402: /// Gives back the mutable and unique \e descriptor of the map. alpar@1402: int operator[](const Item& item) const { alpar@1402: return Map::operator[](item); alpar@1402: } alpar@1402: deba@1413: private: deba@1413: deba@1413: typedef std::vector Container; deba@1413: Container invMap; deba@1413: deba@1413: public: deba@1413: /// \brief The inverse map type. deba@1413: /// deba@1413: /// The inverse map type. deba@1413: class InverseMap { deba@1413: public: deba@1413: /// \brief Constructor of the InverseMap. deba@1413: /// deba@1413: /// Constructor of the InverseMap. deba@1413: InverseMap(const DescriptorMap& _inverted) deba@1413: : inverted(_inverted) {} deba@1413: deba@1413: deba@1413: /// The value type of the InverseMap. deba@1413: typedef typename DescriptorMap::Key Value; deba@1413: /// The key type of the InverseMap. deba@1413: typedef typename DescriptorMap::Value Key; deba@1413: deba@1413: /// \brief Subscript operator. deba@1413: /// deba@1413: /// Subscript operator. It gives back the item deba@1413: /// that the descriptor belongs to currently. deba@1413: Value operator[](const Key& key) const { deba@1413: return inverted.invMap[key]; deba@1413: } deba@1470: deba@1470: /// \brief Size of the map. deba@1470: /// deba@1470: /// Returns the size of the map. deba@1470: unsigned size() const { deba@1470: return inverted.invMap.size(); deba@1470: } deba@1413: deba@1413: private: deba@1413: const DescriptorMap& inverted; deba@1413: }; deba@1413: alpar@1402: /// \brief Gives back the inverse of the map. alpar@1402: /// alpar@1402: /// Gives back the inverse of the map. alpar@1402: const InverseMap inverse() const { deba@1413: return InverseMap(*this); alpar@1402: } alpar@1402: }; alpar@1402: alpar@1402: /// \brief Returns the source of the given edge. alpar@1402: /// alpar@1402: /// The SourceMap gives back the source Node of the given edge. alpar@1402: /// \author Balazs Dezso alpar@1402: template alpar@1402: class SourceMap { alpar@1402: public: deba@1419: deba@1419: typedef True NeedCopy; deba@1419: alpar@1402: typedef typename Graph::Node Value; alpar@1402: typedef typename Graph::Edge Key; alpar@1402: alpar@1402: /// \brief Constructor alpar@1402: /// alpar@1402: /// Constructor alpar@1402: /// \param _graph The graph that the map belongs to. alpar@1402: SourceMap(const Graph& _graph) : graph(_graph) {} alpar@1402: alpar@1402: /// \brief The subscript operator. alpar@1402: /// alpar@1402: /// The subscript operator. alpar@1402: /// \param edge The edge alpar@1402: /// \return The source of the edge alpar@1402: Value operator[](const Key& edge) { alpar@1402: return graph.source(edge); alpar@1402: } alpar@1402: alpar@1402: private: alpar@1402: const Graph& graph; alpar@1402: }; alpar@1402: alpar@1402: /// \brief Returns a \ref SourceMap class alpar@1402: /// alpar@1402: /// This function just returns an \ref SourceMap class. alpar@1402: /// \relates SourceMap alpar@1402: template alpar@1402: inline SourceMap sourceMap(const Graph& graph) { alpar@1402: return SourceMap(graph); alpar@1402: } alpar@1402: alpar@1402: /// \brief Returns the target of the given edge. alpar@1402: /// alpar@1402: /// The TargetMap gives back the target Node of the given edge. alpar@1402: /// \author Balazs Dezso alpar@1402: template alpar@1402: class TargetMap { alpar@1402: public: deba@1419: deba@1419: typedef True NeedCopy; deba@1419: alpar@1402: typedef typename Graph::Node Value; alpar@1402: typedef typename Graph::Edge Key; alpar@1402: alpar@1402: /// \brief Constructor alpar@1402: /// alpar@1402: /// Constructor alpar@1402: /// \param _graph The graph that the map belongs to. alpar@1402: TargetMap(const Graph& _graph) : graph(_graph) {} alpar@1402: alpar@1402: /// \brief The subscript operator. alpar@1402: /// alpar@1402: /// The subscript operator. alpar@1402: /// \param edge The edge alpar@1402: /// \return The target of the edge alpar@1402: Value operator[](const Key& key) { alpar@1402: return graph.target(key); alpar@1402: } alpar@1402: alpar@1402: private: alpar@1402: const Graph& graph; alpar@1402: }; alpar@1402: alpar@1402: /// \brief Returns a \ref TargetMap class alpar@1402: alpar@1402: /// This function just returns an \ref TargetMap class. alpar@1402: /// \relates TargetMap alpar@1402: template alpar@1402: inline TargetMap targetMap(const Graph& graph) { alpar@1402: return TargetMap(graph); alpar@1402: } alpar@1402: deba@1419: /// \brief Returns the "forward" directed edge view of undirected edge. deba@1419: /// deba@1419: /// Returns the "forward" directed edge view of undirected edge. deba@1419: /// \author Balazs Dezso deba@1419: template deba@1419: class ForwardMap { deba@1419: public: deba@1419: deba@1419: typedef True NeedCopy; deba@1419: deba@1419: typedef typename Graph::Edge Value; deba@1419: typedef typename Graph::UndirEdge Key; deba@1419: deba@1419: /// \brief Constructor deba@1419: /// deba@1419: /// Constructor deba@1419: /// \param _graph The graph that the map belongs to. deba@1419: ForwardMap(const Graph& _graph) : graph(_graph) {} deba@1419: deba@1419: /// \brief The subscript operator. deba@1419: /// deba@1419: /// The subscript operator. deba@1419: /// \param key An undirected edge deba@1419: /// \return The "forward" directed edge view of undirected edge deba@1419: Value operator[](const Key& key) const { deba@1419: return graph.edgeWithSource(key, graph.source(key)); deba@1419: } deba@1419: deba@1419: private: deba@1419: const Graph& graph; deba@1419: }; deba@1419: deba@1419: /// \brief Returns a \ref ForwardMap class deba@1419: deba@1419: /// This function just returns an \ref ForwardMap class. deba@1419: /// \relates ForwardMap deba@1419: template deba@1419: inline ForwardMap forwardMap(const Graph& graph) { deba@1419: return ForwardMap(graph); deba@1419: } deba@1419: deba@1419: /// \brief Returns the "backward" directed edge view of undirected edge. deba@1419: /// deba@1419: /// Returns the "backward" directed edge view of undirected edge. deba@1419: /// \author Balazs Dezso deba@1419: template deba@1419: class BackwardMap { deba@1419: public: deba@1419: typedef True NeedCopy; deba@1419: deba@1419: typedef typename Graph::Edge Value; deba@1419: typedef typename Graph::UndirEdge Key; deba@1419: deba@1419: /// \brief Constructor deba@1419: /// deba@1419: /// Constructor deba@1419: /// \param _graph The graph that the map belongs to. deba@1419: BackwardMap(const Graph& _graph) : graph(_graph) {} deba@1419: deba@1419: /// \brief The subscript operator. deba@1419: /// deba@1419: /// The subscript operator. deba@1419: /// \param key An undirected edge deba@1419: /// \return The "backward" directed edge view of undirected edge deba@1419: Value operator[](const Key& key) const { deba@1419: return graph.edgeWithSource(key, graph.target(key)); deba@1419: } deba@1419: deba@1419: private: deba@1419: const Graph& graph; deba@1419: }; deba@1419: deba@1419: /// \brief Returns a \ref BackwardMap class deba@1419: deba@1419: /// This function just returns an \ref BackwardMap class. deba@1419: /// \relates BackwardMap deba@1419: template deba@1419: inline BackwardMap backwardMap(const Graph& graph) { deba@1419: return BackwardMap(graph); deba@1419: } deba@1419: alpar@1402: alpar@1453: alpar@1459: /// Map of the node in-degrees. alpar@1453: alpar@1459: ///This map returns the in-degree of a node. Ones it is constructed, alpar@1459: ///the degrees are stored in a standard NodeMap, so each query is done alpar@1459: ///in constant time. On the other hand, the values updates automatically alpar@1459: ///whenever the graph changes. alpar@1453: /// alpar@1459: ///\sa OutDegMap alpar@1453: template alpar@1453: class InDegMap : alpar@1459: protected _Graph::template NodeMap, alpar@1459: protected AlterationNotifier::ObserverBase alpar@1453: { alpar@1459: const _Graph& graph; alpar@1453: public: alpar@1453: typedef int Value; alpar@1453: typedef typename _Graph::Node Key; alpar@1453: alpar@1453: /// \brief Constructor. alpar@1453: /// alpar@1453: /// Constructor for creating in-degree map. alpar@1459: InDegMap(const _Graph& _graph) : ladanyi@1467: _Graph::template NodeMap(_graph,0), alpar@1459: graph(_graph) alpar@1453: { alpar@1459: AlterationNotifier alpar@1459: ::ObserverBase::attach(graph.getNotifier(typename _Graph::Edge())); alpar@1453: klao@1454: for(typename _Graph::NodeIt n(graph);n!=INVALID;++n) klao@1454: for(typename _Graph::InEdgeIt e(graph,n);e!=INVALID;++e) alpar@1459: _Graph::template NodeMap::operator[](graph.target(e))++; alpar@1453: } alpar@1453: alpar@1459: virtual ~InDegMap() alpar@1453: { alpar@1459: AlterationNotifier:: alpar@1453: ObserverBase::detach(); alpar@1453: } alpar@1453: alpar@1459: /// Gives back the in-degree of a Node. alpar@1459: int operator[](const Key& k) const { alpar@1459: return _Graph::template NodeMap::operator[](k); alpar@1459: } alpar@1453: alpar@1453: protected: alpar@1453: virtual void add(const typename _Graph::Node& n) { alpar@1459: _Graph::template NodeMap::add(n); alpar@1459: _Graph::template NodeMap::operator[](n)=0; klao@1454: } alpar@1459: virtual void erase(const typename _Graph::Node&n) alpar@1453: { alpar@1459: _Graph::template NodeMap::erase(n); alpar@1453: } klao@1454: virtual void add(const typename _Graph::Edge& e) { alpar@1459: _Graph::template NodeMap::operator[](graph.target(e))++; klao@1454: } klao@1454: virtual void erase(const typename _Graph::Edge& e) { alpar@1459: _Graph::template NodeMap::operator[](graph.target(e))--; alpar@1453: } alpar@1453: alpar@1506: ///\e alpar@1506: alpar@1506: ///\bug Unimplemented alpar@1506: /// alpar@1459: virtual void build() {} alpar@1506: ///\e alpar@1506: alpar@1506: ///\bug Unimplemented alpar@1506: /// alpar@1459: virtual void clear() {} alpar@1459: alpar@1459: }; alpar@1459: alpar@1459: alpar@1459: /// Map of the node out-degrees. alpar@1459: alpar@1459: ///This map returns the out-degree of a node. One it is constructed, alpar@1459: ///the degrees are stored in a standard NodeMap, so each query is done alpar@1459: ///in constant time. On the other hand, the values updates automatically alpar@1459: ///whenever the graph changes. alpar@1459: /// alpar@1459: ///\sa OutDegMap alpar@1459: template alpar@1459: class OutDegMap : alpar@1459: protected _Graph::template NodeMap, alpar@1459: protected AlterationNotifier::ObserverBase alpar@1459: { alpar@1459: const _Graph& graph; alpar@1459: public: alpar@1459: typedef int Value; alpar@1459: typedef typename _Graph::Node Key; alpar@1459: alpar@1459: /// \brief Constructor. alpar@1459: /// alpar@1459: /// Constructor for creating out-degree map. alpar@1459: OutDegMap(const _Graph& _graph) : ladanyi@1467: _Graph::template NodeMap(_graph,0), alpar@1459: graph(_graph) alpar@1459: { alpar@1459: AlterationNotifier alpar@1459: ::ObserverBase::attach(graph.getNotifier(typename _Graph::Edge())); alpar@1459: alpar@1459: for(typename _Graph::NodeIt n(graph);n!=INVALID;++n) alpar@1459: for(typename _Graph::InEdgeIt e(graph,n);e!=INVALID;++e) alpar@1459: _Graph::template NodeMap::operator[](graph.source(e))++; alpar@1459: } alpar@1459: alpar@1459: ~OutDegMap() alpar@1459: { alpar@1459: AlterationNotifier:: alpar@1459: ObserverBase::detach(); alpar@1459: } alpar@1459: alpar@1459: /// Gives back the in-degree of a Node. alpar@1459: int operator[](const Key& k) const { alpar@1459: return _Graph::template NodeMap::operator[](k); alpar@1459: } alpar@1459: alpar@1459: protected: alpar@1459: virtual void add(const typename _Graph::Node& n) { alpar@1459: _Graph::template NodeMap::add(n); alpar@1459: _Graph::template NodeMap::operator[](n)=0; alpar@1459: } alpar@1459: virtual void erase(const typename _Graph::Node&n) alpar@1459: { alpar@1459: _Graph::template NodeMap::erase(n); alpar@1459: } alpar@1459: virtual void add(const typename _Graph::Edge& e) { alpar@1459: _Graph::template NodeMap::operator[](graph.source(e))++; alpar@1459: } alpar@1459: virtual void erase(const typename _Graph::Edge& e) { alpar@1459: _Graph::template NodeMap::operator[](graph.source(e))--; alpar@1459: } alpar@1459: alpar@1506: ///\e alpar@1506: alpar@1506: ///\bug Unimplemented alpar@1506: /// alpar@1459: virtual void build() {} alpar@1506: ///\e alpar@1506: alpar@1506: ///\bug Unimplemented alpar@1506: /// alpar@1459: virtual void clear() {} alpar@1453: alpar@1453: }; alpar@1453: alpar@1453: alpar@1453: alpar@1453: alpar@1402: /// @} alpar@1402: alpar@947: } //END OF NAMESPACE LEMON klao@946: klao@946: #endif