[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