klao@946: /* -*- C++ -*- klao@946: * src/lemon/graph_utils.h - Part of LEMON, a generic C++ optimization library klao@946: * klao@946: * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport klao@946: * (Egervary Combinatorial Optimization Research Group, 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 klao@946: klao@946: #include klao@977: #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: alpar@947: /// \addtogroup gutils alpar@947: /// @{ 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@946: /// \brief Function to count the symmetric edges in the graph. klao@946: /// klao@946: /// This function counts the symmetric 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@946: template klao@946: inline int countSymEdges(const Graph& _g) { klao@946: return countItems(_g); klao@946: } klao@946: klao@977: 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, alpar@967: typename Graph::Node u, typename Graph::Node v, alpar@967: typename Graph::Edge prev = INVALID) alpar@967: { alpar@967: typename Graph::OutEdgeIt e(g,prev); alpar@967: if(prev==INVALID) g.first(e,u); alpar@967: else ++e; alpar@986: while(e!=INVALID && g.source(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: klao@946: template < klao@946: typename _DestinationGraph, klao@946: typename _SourceGraph, klao@946: typename _NodeBijection klao@946: =typename _SourceGraph::template NodeMap, klao@946: typename _EdgeBijection klao@946: =typename _SourceGraph::template EdgeMap klao@946: > klao@946: class GraphCopy { klao@946: public: klao@946: klao@946: typedef _DestinationGraph DestinationGraph; klao@946: typedef _SourceGraph SourceGraph; klao@946: klao@946: typedef _NodeBijection NodeBijection; klao@946: typedef _EdgeBijection EdgeBijection; klao@946: klao@946: protected: klao@946: klao@946: NodeBijection node_bijection; klao@946: EdgeBijection edge_bijection; klao@946: klao@946: public: klao@946: klao@946: GraphCopy(DestinationGraph& _d, const SourceGraph& _s) { klao@946: copyGraph(_d, _s, node_bijection, edge_bijection); klao@946: } klao@946: klao@946: const NodeBijection& getNodeBijection() const { klao@946: return node_bijection; klao@946: } klao@946: klao@946: const EdgeBijection& getEdgeBijection() const { klao@946: return edge_bijection; klao@946: } klao@946: klao@946: }; alpar@947: alpar@947: /// @} alpar@947: alpar@947: } //END OF NAMESPACE LEMON klao@946: klao@946: #endif