[Lemon-commits] [lemon_svn] deba: r2268 - hugo/trunk/lemon

Lemon SVN svn at lemon.cs.elte.hu
Mon Nov 6 20:51:23 CET 2006


Author: deba
Date: Mon Oct 24 19:03:02 2005
New Revision: 2268

Modified:
   hugo/trunk/lemon/topology.h

Log:
Bug fix in connectedComponents
Strongly connected components



Modified: hugo/trunk/lemon/topology.h
==============================================================================
--- hugo/trunk/lemon/topology.h	(original)
+++ hugo/trunk/lemon/topology.h	Mon Oct 24 19:03:02 2005
@@ -18,6 +18,7 @@
 #define LEMON_TOPOLOGY_H
 
 #include <lemon/dfs.h>
+#include <lemon/bfs.h>
 #include <lemon/graph_utils.h>
 
 #include <lemon/concept/graph.h>
@@ -220,19 +221,19 @@
   ///
   ///\param g The graph. In must be undirected.
   ///\return The number of components
-  ///\todo Test required
-  template<class UGraph>
-  int numberOfComponents(const UGraph &g)
-  {
-    int c=0;
-    Bfs<Graph> bfs(g);
+  template <class UndirGraph>
+  int countConnectedComponents(const UndirGraph &g) {
+    checkConcept<concept::UndirGraph, UndirGraph>();
+    int c = 0;
+    Bfs<UndirGraph> bfs(g);
     bfs.init();
-    for(typename Graph::NodeIt n(g);n!=INVALID;++n)
+    for(typename UndirGraph::NodeIt n(g); n != INVALID; ++n) {
       if(!bfs.reached(n)) {
-	c++;
 	bfs.addSource(n);
 	bfs.start();
+	++c;
       }
+    }
     return c;
   }
 
@@ -248,23 +249,173 @@
   ///set continuously.
   ///\return The number of components
   ///\todo Test required
-  template<class UGraph, class WMap>
-  int connectedComponents(const UGraph &g, WMap &comp)
-  {
-    int c=0;
-    Bfs<Graph> bfs(g);
+  template <class UndirGraph, class IntNodeMap>
+  int connectedComponents(const UndirGraph &g, IntNodeMap &comp) {
+    checkConcept<concept::UndirGraph, UndirGraph>();
+    checkConcept<concept::WriteMap<typename UndirGraph::Node, int>, 
+      IntNodeMap>();
+    int c = 0;
+    Bfs<UndirGraph> bfs(g);
     bfs.init();
-    for(typename Graph::NodeIt n(g);n!=INVALID;++n)
+    for(typename UndirGraph::NodeIt n(g); n != INVALID; ++n) {
       if(!bfs.reached(n)) {
 	bfs.addSource(n);
-	while ( bfs.nextNode()!=INVALID ) {
-	  comp[bfs.nextNode()]=c;
-	  processNextNode();
-	  c++;
+	while (!bfs.emptyQueue()) {
+	  comp[bfs.nextNode()] = c;
+	  bfs.processNextNode();
+	}
+	++c;
       }
+    }
     return c;
   }
 
+  namespace _components_bits {
+
+    template <typename Key, typename IntMap>
+    struct FillWriteMap : public MapBase<Key, bool> {
+    public:
+      FillWriteMap(IntMap& _map, int& _comp) 
+	: map(_map), comp(_comp) {}
+      void set(Key key, bool value) {
+	if (value) { map.set(key, comp); }
+      }
+    private:
+      IntMap& map;
+      int& comp;
+    };
+
+    template <typename Key, typename Container = std::vector<Key> >
+    struct BackInserterWriteMap : public MapBase<Key, bool> {
+    public:
+      BackInserterWriteMap(Container& _container) 
+	: container(_container) {}
+      void set(Key key, bool value) {
+	if (value) { container.push_back(key); }
+      }
+    private:
+      Container& container;
+    };
+
+  }
+
+  /// \brief Count the strongly connected components of a directed graph
+  ///
+  /// Count the strongly connected components of a directed graph
+  ///
+  /// \param g The graph.
+  /// \return The number of components
+  template <typename Graph>
+  int countStronglyConnectedComponents(const Graph& graph) {
+    checkConcept<concept::StaticGraph, Graph>();
+
+    using namespace _components_bits;
+
+    typedef typename Graph::Node Node;
+    typedef typename Graph::Edge Edge;
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::EdgeIt EdgeIt;
+    
+
+    typename Dfs<Graph>::
+      template DefProcessedMap<BackInserterWriteMap<Node> >::
+      Create dfs(graph);
+
+    std::vector<Node> nodes;
+    BackInserterWriteMap<Node> processed(nodes);
+    dfs.processedMap(processed);
+
+    dfs.init();
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+	dfs.addSource(it);
+	dfs.start();
+      }
+    }
+
+    typedef RevGraphAdaptor<const Graph> RGraph;
+
+    RGraph rgraph(graph);
+
+    Dfs<RGraph> rdfs(rgraph);
+
+    int num = 0;
+
+    rdfs.init();
+    for (typename std::vector<Node>::reverse_iterator 
+	   it = nodes.rbegin(); it != nodes.rend(); ++it) {
+      if (!rdfs.reached(*it)) {
+	rdfs.addSource(*it);
+	rdfs.start();
+	++num;
+      }
+    }
+    return num;
+  }
+
+  /// \brief Find the strongly connected components of a directed graph
+  ///
+  /// Find the strongly connected components of a directed graph
+  ///
+  /// \param g The graph.
+  /// \retval comp A writable node map. The values will be set from 0 to
+  /// the number of the strongly connected components minus one. Each values 
+  /// of the map will be set exactly once, the values of a certain component 
+  /// will be set continuously.
+  /// \return The number of components
+  template <typename Graph, typename IntNodeMap>
+  int stronglyConnectedComponents(const Graph& graph, IntNodeMap& comp) {
+    checkConcept<concept::StaticGraph, Graph>();
+    checkConcept<concept::WriteMap<typename Graph::Node, int>, IntNodeMap>();
+
+    using namespace _components_bits;
+
+    typedef typename Graph::Node Node;
+    typedef typename Graph::Edge Edge;
+    typedef typename Graph::NodeIt NodeIt;
+    typedef typename Graph::EdgeIt EdgeIt;
+    
+
+    typename Dfs<Graph>::
+      template DefProcessedMap<BackInserterWriteMap<Node> >::
+      Create dfs(graph);
+
+    std::vector<Node> nodes;
+    BackInserterWriteMap<Node> processed(nodes);
+    dfs.processedMap(processed);
+
+    dfs.init();
+    for (NodeIt it(graph); it != INVALID; ++it) {
+      if (!dfs.reached(it)) {
+	dfs.addSource(it);
+	dfs.start();
+      }
+    }
+
+    typedef RevGraphAdaptor<const Graph> RGraph;
+
+    RGraph rgraph(graph);
+
+    typename Dfs<RGraph>::
+      template DefProcessedMap<FillWriteMap<Node, IntNodeMap> >::
+      Create rdfs(rgraph);
+
+    int num = 0;
+    FillWriteMap<Node, IntNodeMap> rprocessed(comp, num);
+    rdfs.processedMap(rprocessed);
+
+    rdfs.init();
+    for (typename std::vector<Node>::reverse_iterator 
+	   it = nodes.rbegin(); it != nodes.rend(); ++it) {
+      if (!rdfs.reached(*it)) {
+	rdfs.addSource(*it);
+	rdfs.start();
+	++num;
+      }
+    }
+    return num;
+  }
+
 } //namespace lemon
 
 #endif //LEMON_TOPOLOGY_H



More information about the Lemon-commits mailing list