src/lemon/graph_utils.h
author alpar
Tue, 15 Feb 2005 14:54:25 +0000
changeset 1146 ebab0e5ec8b2
parent 1053 90f8696360b2
child 1164 80bb73097736
permissions -rw-r--r--
Doc improvements.
     1 /* -*- C++ -*-
     2  * src/lemon/graph_utils.h - Part of LEMON, a generic C++ optimization library
     3  *
     4  * Copyright (C) 2004 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
     5  * (Egervary Combinatorial Optimization Research Group, EGRES).
     6  *
     7  * Permission to use, modify and distribute this software is granted
     8  * provided that this copyright notice appears in all copies. For
     9  * precise terms see the accompanying LICENSE file.
    10  *
    11  * This software is provided "AS IS" with no warranty of any kind,
    12  * express or implied, and with no claim as to its suitability for any
    13  * purpose.
    14  *
    15  */
    16 
    17 #ifndef LEMON_GRAPH_UTILS_H
    18 #define LEMON_GRAPH_UTILS_H
    19 
    20 #include <iterator>
    21 
    22 #include <lemon/invalid.h>
    23 #include <lemon/utility.h>
    24 
    25 ///\ingroup gutils
    26 ///\file
    27 ///\brief Graph utilities.
    28 ///
    29 ///\todo Please
    30 ///revise the documentation.
    31 ///
    32 
    33 
    34 namespace lemon {
    35 
    36 /// \addtogroup gutils
    37 /// @{
    38 
    39   /// \brief Function to count the items in the graph.
    40   ///
    41   /// This function counts the items in the graph.
    42   /// The complexity of the function is O(n) because
    43   /// it iterates on all of the items.
    44 
    45   template <typename Graph, typename ItemIt>
    46   inline int countItems(const Graph& g) {
    47     int num = 0;
    48     for (ItemIt it(g); it != INVALID; ++it) {
    49       ++num;
    50     }
    51     return num;
    52   }
    53 
    54   // Node counting:
    55 
    56   template <typename Graph>
    57   inline
    58   typename enable_if<typename Graph::NodeNumTag, int>::type
    59   _countNodes(const Graph &g) {
    60     return g.nodeNum();
    61   }
    62 
    63   template <typename Graph>
    64   inline int _countNodes(Wrap<Graph> w) {
    65     return countItems<Graph, typename Graph::NodeIt>(w.value);
    66   }
    67 
    68   /// \brief Function to count the nodes in the graph.
    69   ///
    70   /// This function counts the nodes in the graph.
    71   /// The complexity of the function is O(n) but for some
    72   /// graph structure it is specialized to run in O(1).
    73   ///
    74   /// \todo refer how to specialize it
    75 
    76   template <typename Graph>
    77   inline int countNodes(const Graph& g) {
    78     return _countNodes<Graph>(g);
    79   }
    80 
    81   // Edge counting:
    82 
    83   template <typename Graph>
    84   inline
    85   typename enable_if<typename Graph::EdgeNumTag, int>::type
    86   _countEdges(const Graph &g) {
    87     return g.edgeNum();
    88   }
    89 
    90   template <typename Graph>
    91   inline int _countEdges(Wrap<Graph> w) {
    92     return countItems<Graph, typename Graph::EdgeIt>(w.value);
    93   }
    94 
    95   /// \brief Function to count the edges in the graph.
    96   ///
    97   /// This function counts the edges in the graph.
    98   /// The complexity of the function is O(e) but for some
    99   /// graph structure it is specialized to run in O(1).
   100 
   101   template <typename Graph>
   102   inline int countEdges(const Graph& g) {
   103     return _countEdges<Graph>(g);
   104   }
   105 
   106   // Undirected edge counting:
   107 
   108   template <typename Graph>
   109   inline
   110   typename enable_if<typename Graph::EdgeNumTag, int>::type
   111   _countUndirEdges(const Graph &g) {
   112     return g.undirEdgeNum();
   113   }
   114 
   115   template <typename Graph>
   116   inline int _countUndirEdges(Wrap<Graph> w) {
   117     return countItems<Graph, typename Graph::UndirEdgeIt>(w.value);
   118   }
   119 
   120   /// \brief Function to count the edges in the graph.
   121   ///
   122   /// This function counts the edges in the graph.
   123   /// The complexity of the function is O(e) but for some
   124   /// graph structure it is specialized to run in O(1).
   125 
   126   template <typename Graph>
   127   inline int countUndirEdges(const Graph& g) {
   128     return _countUndirEdges<Graph>(g);
   129   }
   130 
   131 
   132 
   133   template <typename Graph, typename DegIt>
   134   inline int countNodeDegree(const Graph& _g, const typename Graph::Node& _n) {
   135     int num = 0;
   136     for (DegIt it(_g, _n); it != INVALID; ++it) {
   137       ++num;
   138     }
   139     return num;
   140   }
   141 
   142   /// Finds an edge between two nodes of a graph.
   143 
   144   /// Finds an edge from node \c u to node \c v in graph \c g.
   145   ///
   146   /// If \c prev is \ref INVALID (this is the default value), then
   147   /// it finds the first edge from \c u to \c v. Otherwise it looks for
   148   /// the next edge from \c u to \c v after \c prev.
   149   /// \return The found edge or \ref INVALID if there is no such an edge.
   150   ///
   151   /// Thus you can iterate through each edge from \c u to \c v as it follows.
   152   /// \code
   153   /// for(Edge e=findEdge(g,u,v);e!=INVALID;e=findEdge(g,u,v,e)) {
   154   ///   ...
   155   /// }
   156   /// \endcode
   157   /// \todo We may want to use the \ref concept::GraphBase "GraphBase"
   158   /// interface here...
   159   /// \bug Untested ...
   160   template <typename Graph>
   161   typename Graph::Edge findEdge(const Graph &g,
   162 		typename Graph::Node u, typename Graph::Node v,
   163 		typename Graph::Edge prev = INVALID) 
   164   {
   165     typename Graph::OutEdgeIt e(g,prev);
   166     //    if(prev==INVALID) g.first(e,u);
   167     if(prev==INVALID) e=typename Graph::OutEdgeIt(g,u);
   168     else ++e;
   169     while(e!=INVALID && g.target(e)!=v) ++e;
   170     return e;
   171   }
   172   
   173   ///\e
   174 
   175   ///\todo Please document.
   176   ///
   177   template <typename Graph>
   178   inline int countOutEdges(const Graph& _g,  const typename Graph::Node& _n) {
   179     return countNodeDegree<Graph, typename Graph::OutEdgeIt>(_g, _n);
   180   }
   181 
   182   ///\e
   183 
   184   ///\todo Please document.
   185   ///
   186   template <typename Graph>
   187   inline int countInEdges(const Graph& _g,  const typename Graph::Node& _n) {
   188     return countNodeDegree<Graph, typename Graph::InEdgeIt>(_g, _n);
   189   }
   190 
   191   // graph copy
   192 
   193   template <
   194     typename DestinationGraph, 
   195     typename SourceGraph, 
   196     typename NodeBijection>
   197   void copyNodes(DestinationGraph& _d, const SourceGraph& _s, 
   198 		 NodeBijection& _nb) {    
   199     for (typename SourceGraph::NodeIt it(_s); it != INVALID; ++it) {
   200       _nb[it] = _d.addNode();
   201     }
   202   }
   203 
   204   template <
   205     typename DestinationGraph, 
   206     typename SourceGraph, 
   207     typename NodeBijection,
   208     typename EdgeBijection>
   209   void copyEdges(DestinationGraph& _d, const SourceGraph& _s,
   210 		 const NodeBijection& _nb, EdgeBijection& _eb) {    
   211     for (typename SourceGraph::EdgeIt it(_s); it != INVALID; ++it) {
   212       _eb[it] = _d.addEdge(_nb[_s.source(it)], _nb[_s.target(it)]);
   213     }
   214   }
   215 
   216   template <
   217     typename DestinationGraph, 
   218     typename SourceGraph, 
   219     typename NodeBijection,
   220     typename EdgeBijection>
   221   void copyGraph(DestinationGraph& _d, const SourceGraph& _s, 
   222 		 NodeBijection& _nb, EdgeBijection& _eb) {
   223     nodeCopy(_d, _s, _nb);
   224     edgeCopy(_d, _s, _nb, _eb);
   225   }
   226  
   227    template <
   228     typename _DestinationGraph, 
   229     typename _SourceGraph, 
   230     typename _NodeBijection 
   231     =typename _SourceGraph::template NodeMap<typename _DestinationGraph::Node>,
   232     typename _EdgeBijection 
   233     =typename _SourceGraph::template EdgeMap<typename _DestinationGraph::Edge>
   234    >
   235    class GraphCopy {
   236    public:
   237 
   238      typedef _DestinationGraph DestinationGraph;
   239      typedef _SourceGraph SourceGraph;
   240 
   241      typedef _NodeBijection NodeBijection;
   242      typedef _EdgeBijection EdgeBijection;
   243 
   244    protected:          
   245 
   246      NodeBijection node_bijection;
   247      EdgeBijection edge_bijection;     
   248 
   249    public:
   250      
   251      GraphCopy(DestinationGraph& _d, const SourceGraph& _s) {
   252        copyGraph(_d, _s, node_bijection, edge_bijection);
   253      }
   254 
   255      const NodeBijection& getNodeBijection() const {
   256        return node_bijection;
   257      }
   258 
   259      const EdgeBijection& getEdgeBijection() const {
   260        return edge_bijection;
   261      }
   262      
   263    };
   264 
   265 /// @}
   266   
   267 } //END OF NAMESPACE LEMON
   268 
   269 #endif