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