From a53afa3f85b63218dc8d95ca42d83d8f07c76c1e Mon Sep 17 00:00:00 2001 From: Jeremy Siek Date: Thu, 16 Aug 2001 18:57:48 +0000 Subject: [PATCH] made condensation graph separate [SVN r10879] --- .../boost/graph/create_condensation_graph.hpp | 74 +++++++++++++++++++ include/boost/graph/transitive_closure.hpp | 30 ++------ 2 files changed, 81 insertions(+), 23 deletions(-) create mode 100644 include/boost/graph/create_condensation_graph.hpp diff --git a/include/boost/graph/create_condensation_graph.hpp b/include/boost/graph/create_condensation_graph.hpp new file mode 100644 index 00000000..10ceed68 --- /dev/null +++ b/include/boost/graph/create_condensation_graph.hpp @@ -0,0 +1,74 @@ +#ifndef BOOST_CREATE_CONDENSATION_GRAPH_HPP +#define BOOST_CREATE_CONDENSATION_GRAPH_HPP + +#include +#include + +namespace boost { + + template + void create_condensation_graph(const Graph& g, + const ComponentLists& components, + ComponentNumberMap component_number, + CondensationGraph& cg, + EdgeMultiplicityMap edge_mult_map) + { + typedef typename graph_traits::vertex_descriptor vertex; + typedef typename graph_traits::vertices_size_type size_type; + typedef typename graph_traits::vertex_descriptor + cg_vertex; + std::vector to_cg_vertex(components.size()); + for (size_type s = 0; s < components.size(); ++s) + to_cg_vertex[s] = add_vertex(cg); + + for (size_type si = 0; si < components.size(); ++si) { + cg_vertex s = to_cg_vertex[si]; + std::vector adj; + for (size_type i = 0; i < components[si].size(); ++i) { + vertex u = components[s][i]; + typename graph_traits::adjacency_iterator v, v_end; + for (tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) { + cg_vertex t = to_cg_vertex[component_number[*v]]; + if (s != t) // Avoid loops in the condensation graph + adj.push_back(t); + } + } + std::sort(adj.begin(), adj.end()); + if (! adj.empty()) { + size_type i = 0; + cg_vertex t = adj[i]; + typename graph_traits::edge_descriptor e; + bool inserted; + tie(e, inserted) = add_edge(s, t, cg); + put(edge_mult_map, e, 1); + ++i; + while (i < adj.size()) { + if (adj[i] == t) + put(edge_mult_map, e, get(edge_mult_map, e) + 1); + else { + t = adj[i]; + tie(e, inserted) = add_edge(s, t, cg); + put(edge_mult_map, e, 1); + } + ++i; + } + } + } + } + + template + void create_condensation_graph(const Graph& g, + const ComponentLists& components, + ComponentNumberMap component_number, + CondensationGraph& cg) + { + create_condensation_graph(g, components, component_number, cg, + dummy_property_map()); + } + +} // namespace boost + +#endif // BOOST_CREATE_CONDENSATION_GRAPH_HPP diff --git a/include/boost/graph/transitive_closure.hpp b/include/boost/graph/transitive_closure.hpp index 34cbf1cf..19389a1a 100644 --- a/include/boost/graph/transitive_closure.hpp +++ b/include/boost/graph/transitive_closure.hpp @@ -15,6 +15,7 @@ #include #include #include +#include // For a description of the implementation see ../doc/transitive_closure.pdf. @@ -74,6 +75,7 @@ namespace boost { typedef typename property_traits::value_type size_type; typedef typename graph_traits::adjacency_iterator adjacency_iterator; + typedef size_type cg_vertex; function_requires< VertexListGraphConcept >(); function_requires< AdjacencyGraphConcept >(); @@ -81,44 +83,26 @@ namespace boost { function_requires< EdgeMutableGraphConcept >(); function_requires< ReadablePropertyMapConcept >(); - // Compute strongly connected components of the graph - typedef size_type cg_vertex; std::vector component_number_vec(num_vertices(g)); iterator_property_map component_number(&component_number_vec[0], index_map); int num_scc = strong_components(g, component_number, vertex_index_map(index_map)); + std::vector< std::vector > components; build_component_lists(g, num_scc, component_number, components); - // Construct the condensation graph typedef std::vector< std::vector > CG_t; - CG_t CG(num_scc); - for (cg_vertex s = 0; s < components.size(); ++s) { - std::vector adj; - for (size_type i = 0; i < components[s].size(); ++i) { - vertex u = components[s][i]; - adjacency_iterator v, v_end; - for (tie(v, v_end) = adjacent_vertices(u, g); v != v_end; ++v) { - cg_vertex t = component_number[*v]; - if (s != t) // Avoid loops in the condensation graph - adj.push_back(t); - } - } - std::sort(adj.begin(), adj.end()); - std::vector::iterator - di = std::unique(adj.begin(), adj.end()); - if (di != adj.end()) - adj.erase(di, adj.end()); - CG[s] = adj; - } + CG_t CG; + create_condensation_graph(g, components, component_number, CG); - // topological sort the condensation graph std::vector topo_order; std::vector topo_number(num_vertices(CG)); + topological_sort(CG, std::back_inserter(topo_order), vertex_index_map(identity_property_map())); + std::reverse(topo_order.begin(), topo_order.end()); size_type n = 0; for (std::vector::iterator i = topo_order.begin();