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 <iterator>
klao@946: 
klao@946: #include <lemon/invalid.h>
klao@977: #include <lemon/utility.h>
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 <typename Graph, typename ItemIt>
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 <typename Graph>
klao@977:   inline
klao@977:   typename enable_if<typename Graph::NodeNumTag, int>::type
klao@977:   _countNodes(const Graph &g) {
klao@977:     return g.nodeNum();
klao@977:   }
klao@977: 
klao@977:   template <typename Graph>
klao@977:   inline int _countNodes(Wrap<Graph> w) {
klao@977:     return countItems<Graph, typename Graph::NodeIt>(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 <typename Graph>
klao@977:   inline int countNodes(const Graph& g) {
klao@977:     return _countNodes<Graph>(g);
klao@977:   }
klao@977: 
klao@977:   // Edge counting:
klao@977: 
klao@977:   template <typename Graph>
klao@977:   inline
klao@977:   typename enable_if<typename Graph::EdgeNumTag, int>::type
klao@977:   _countEdges(const Graph &g) {
klao@977:     return g.edgeNum();
klao@977:   }
klao@977: 
klao@977:   template <typename Graph>
klao@977:   inline int _countEdges(Wrap<Graph> w) {
klao@977:     return countItems<Graph, typename Graph::EdgeIt>(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 <typename Graph>
klao@977:   inline int countEdges(const Graph& g) {
klao@977:     return _countEdges<Graph>(g);
klao@946:   }
klao@946: 
klao@1053:   // Undirected edge counting:
klao@1053: 
klao@1053:   template <typename Graph>
klao@1053:   inline
klao@1053:   typename enable_if<typename Graph::EdgeNumTag, int>::type
klao@1053:   _countUndirEdges(const Graph &g) {
klao@1053:     return g.undirEdgeNum();
klao@1053:   }
klao@1053: 
klao@1053:   template <typename Graph>
klao@1053:   inline int _countUndirEdges(Wrap<Graph> w) {
klao@1053:     return countItems<Graph, typename Graph::UndirEdgeIt>(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 <typename Graph>
klao@1053:   inline int countUndirEdges(const Graph& g) {
klao@1053:     return _countUndirEdges<Graph>(g);
klao@946:   }
klao@946: 
klao@977: 
klao@1053: 
klao@946:   template <typename Graph, typename DegIt>
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 <typename Graph>
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 <typename Graph>
klao@946:   inline int countOutEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946:     return countNodeDegree<Graph, typename Graph::OutEdgeIt>(_g, _n);
klao@946:   }
klao@946: 
alpar@964:   ///\e
alpar@964: 
alpar@964:   ///\todo Please document.
alpar@964:   ///
klao@946:   template <typename Graph>
klao@946:   inline int countInEdges(const Graph& _g,  const typename Graph::Node& _n) {
klao@946:     return countNodeDegree<Graph, typename Graph::InEdgeIt>(_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<typename _DestinationGraph::Node>,
klao@946:     typename _EdgeBijection 
klao@946:     =typename _SourceGraph::template EdgeMap<typename _DestinationGraph::Edge>
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