diff --git a/doc/subgraph.html b/doc/subgraph.html index 09d07b30..90c6019c 100644 --- a/doc/subgraph.html +++ b/doc/subgraph.html @@ -76,9 +76,9 @@ built in to the adjacency_list. We will be building the graph and subgraphs in Figure 1, so we will need a total of six vertices.
-typedef adjacency_list_traitsTraits; -typedef subgraph< adjacency_list > > Graph; +typedef adjacency_list_traits< vecS, vecS, directedS > Traits; +typedef subgraph< adjacency_list< vecS, vecS, directedS, + no_property, property< edge_index_t, int > > > Graph; const int N = 6; Graph G0(N); diff --git a/include/boost/graph/graph_traits.hpp b/include/boost/graph/graph_traits.hpp index fd1b0415..257438f5 100644 --- a/include/boost/graph/graph_traits.hpp +++ b/include/boost/graph/graph_traits.hpp @@ -217,6 +217,11 @@ namespace boost { //?? not the right place ?? Lee typedef boost::forward_traversal_tag multi_pass_input_iterator_tag; + // Forward declare graph_bundle_t property name (from + // boost/graph/properties.hpp, which includes this file) for + // bundled_result. + enum graph_bundle_t {graph_bundle}; + template struct graph_property_type { typedef typename G::graph_property_type type; @@ -261,6 +266,14 @@ namespace boost { typedef typename bundler::type type; }; + template + class bundled_result { + typedef typename graph_traits ::vertex_descriptor Vertex; + typedef graph_bundle_type bundler; + public: + typedef typename bundler::type type; + }; + } } // namespace graph::detail namespace graph_detail { diff --git a/include/boost/graph/isomorphism.hpp b/include/boost/graph/isomorphism.hpp index 9461dc31..f5869026 100644 --- a/include/boost/graph/isomorphism.hpp +++ b/include/boost/graph/isomorphism.hpp @@ -284,18 +284,30 @@ namespace boost { typedef size_type result_type; degree_vertex_invariant(const InDegreeMap& in_degree_map, const Graph& g) - : m_in_degree_map(in_degree_map), m_g(g) { } + : m_in_degree_map(in_degree_map), + m_max_vertex_in_degree(0), + m_max_vertex_out_degree(0), + m_g(g) { + BGL_FORALL_VERTICES_T(v, g, Graph) { + m_max_vertex_in_degree = + (std::max)(m_max_vertex_in_degree, get(m_in_degree_map, v)); + m_max_vertex_out_degree = + (std::max)(m_max_vertex_out_degree, out_degree(v, g)); + } + } size_type operator()(vertex_t v) const { - return (num_vertices(m_g) + 1) * out_degree(v, m_g) + return (m_max_vertex_in_degree + 1) * out_degree(v, m_g) + get(m_in_degree_map, v); } // The largest possible vertex invariant number size_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { - return num_vertices(m_g) * num_vertices(m_g) + num_vertices(m_g); + return (m_max_vertex_in_degree + 2) * m_max_vertex_out_degree + 1; } private: InDegreeMap m_in_degree_map; + size_type m_max_vertex_in_degree; + size_type m_max_vertex_out_degree; const Graph& m_g; }; diff --git a/include/boost/graph/properties.hpp b/include/boost/graph/properties.hpp index f4c57ea2..dd7a7357 100644 --- a/include/boost/graph/properties.hpp +++ b/include/boost/graph/properties.hpp @@ -126,7 +126,8 @@ namespace boost { BOOST_DEF_PROPERTY(graph, visitor); // These tags are used for property bundles - BOOST_DEF_PROPERTY(graph, bundle); + // BOOST_DEF_PROPERTY(graph, bundle); -- needed in graph_traits.hpp, so enum is defined there + BOOST_INSTALL_PROPERTY(graph, bundle); BOOST_DEF_PROPERTY(vertex, bundle); BOOST_DEF_PROPERTY(edge, bundle); diff --git a/include/boost/graph/reverse_graph.hpp b/include/boost/graph/reverse_graph.hpp index 30d303b1..4067f2c2 100644 --- a/include/boost/graph/reverse_graph.hpp +++ b/include/boost/graph/reverse_graph.hpp @@ -90,12 +90,6 @@ class reverse_graph { typename graph::detail::bundled_result ::type const& operator[](Descriptor x) const { return m_g[x]; } - - typename boost::graph_property_type ::type& operator[](graph_bundle_t) - { return get_property(*this); } - - typename boost::graph_property_type ::type const& operator[](graph_bundle_t) const - { return get_property(*this); } #endif // BOOST_GRAPH_NO_BUNDLED_PROPERTIES static vertex_descriptor null_vertex() diff --git a/include/boost/graph/subgraph.hpp b/include/boost/graph/subgraph.hpp index 9e091941..2b702a80 100644 --- a/include/boost/graph/subgraph.hpp +++ b/include/boost/graph/subgraph.hpp @@ -78,12 +78,12 @@ class subgraph { typedef graph_traits Traits; typedef std::list *> ChildrenList; public: -// Graph requirements -typedef typename Traits::vertex_descriptor vertex_descriptor; -typedef typename Traits::edge_descriptor edge_descriptor; -typedef typename Traits::directed_category directed_category; -typedef typename Traits::edge_parallel_category edge_parallel_category; -typedef typename Traits::traversal_category traversal_category; + // Graph requirements + typedef typename Traits::vertex_descriptor vertex_descriptor; + typedef typename Traits::edge_descriptor edge_descriptor; + typedef typename Traits::directed_category directed_category; + typedef typename Traits::edge_parallel_category edge_parallel_category; + typedef typename Traits::traversal_category traversal_category; // IncidenceGraph requirements typedef typename Traits::out_edge_iterator out_edge_iterator; @@ -196,12 +196,22 @@ typedef typename Traits::traversal_category traversal_category; std::pair find_vertex(vertex_descriptor u_global) const { if (is_root()) return std::make_pair(u_global, true); - typename std::map ::const_iterator - i = m_local_vertex.find(u_global); + typename LocalVertexMap::const_iterator i = m_local_vertex.find(u_global); bool valid = i != m_local_vertex.end(); return std::make_pair((valid ? (*i).second : null_vertex()), valid); } + // Is edge e (of the root graph) contained in this subgraph? + // If so, return the matching local edge. + std::pair + find_edge(edge_descriptor e_global) const { + if (is_root()) return std::make_pair(e_global, true); + typename LocalEdgeMap::const_iterator i = + m_local_edge.find(get(get(edge_index, root().m_graph), e_global)); + bool valid = i != m_local_edge.end(); + return std::make_pair((valid ? (*i).second : edge_descriptor()), valid); + } + // Return the parent graph. subgraph& parent() { return *m_parent; } const subgraph& parent() const { return *m_parent; } @@ -617,38 +627,18 @@ namespace detail { //------------------------------------------------------------------------- // implementation of remove_edge(e,g) - template - void remove_edge_recur_down(Edge e_global, subgraph & g); - template + template void children_remove_edge(Edge e_global, Children& c) { for(typename Children::iterator i = c.begin(); i != c.end(); ++i) { - if((*i)->find_vertex(source(e_global, **i)).second && - (*i)->find_vertex(target(e_global, **i)).second) - { - remove_edge_recur_down(source(e_global, **i), - target(e_global, **i), - **i); + std::pair ::edge_descriptor, bool> found = + (*i)->find_edge(e_global); + if (!found.second) { + continue; } - } - } - - template - void remove_edge_recur_down(Edge e_global, subgraph & g) - { - remove_edge(g.global_to_local(e_global), g.m_graph); - children_remove_edge(e_global, g.m_children); - } - - template - void remove_edge_recur_up(Edge e_global, subgraph & g) - { - if (g.is_root()) { - remove_edge(e_global, g.m_graph); - children_remove_edge(e_global, g.m_children); - } else { - remove_edge_recur_up(e_global, *g.m_parent); + children_remove_edge (e_global, (*i)->m_children); + remove_edge(found.first, (*i)->m_graph); } } @@ -672,11 +662,14 @@ template void remove_edge(typename subgraph ::edge_descriptor e, subgraph & g) { - if(g.is_root()) { - detail::remove_edge_recur_up(e, g); - } else { - detail::remove_edge_recur_up(g.local_to_global(e), g); - } + typename subgraph ::edge_descriptor e_global = g.local_to_global(e); +#ifndef NDEBUG + std::pair ::edge_descriptor, bool> fe = g.find_edge(e_global); + assert(fe.second && fe.first == e); +#endif //NDEBUG + subgraph &root = g.root(); // chase to root + detail::children_remove_edge (e_global, root.m_children); + remove_edge(e_global, root.m_graph); // kick edge from root } // This is slow, but there may not be a good way to do it safely otherwise @@ -691,7 +684,7 @@ remove_edge_if(Predicate p, subgraph & g) { if (p(*ep.first)) { any_removed = true; remove_edge(*ep.first, g); - continue; /* Since iterators may be invalidated */ + break; /* Since iterators may be invalidated */ } } if (!any_removed) break; diff --git a/include/boost/graph/transitive_reduction.hpp b/include/boost/graph/transitive_reduction.hpp index 44dfee98..f7cb34b8 100644 --- a/include/boost/graph/transitive_reduction.hpp +++ b/include/boost/graph/transitive_reduction.hpp @@ -99,7 +99,7 @@ transitive_reduction(const Graph& g, GraphTR& tr, { //and run through all vertices in topological order typename std::vector ::reverse_iterator - rit = topo_order.rbegin(); + rit = topo_order.rbegin(), rend = topo_order.rend(); for(; rit != rend; ++rit ) { //looking if they are successors of *it