From 35a460725b4fe3c6b97405d9906fdd4e282251c7 Mon Sep 17 00:00:00 2001 From: Tiago de Paula Peixoto Date: Sun, 2 Jan 2022 16:54:52 +0100 Subject: [PATCH 1/3] vf2_sub_graph_iso.hpp: fix bug when subgraph is filtered This fixes a bug when num_vertices() returns a value that does not match the actual number of vertices. This happens for instances of filtered_graph<>. The fix involves looping over the graph to count the actual number of vertices. The performance overhead is negligible. --- include/boost/graph/vf2_sub_graph_iso.hpp | 33 ++++++++++++++++++----- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/include/boost/graph/vf2_sub_graph_iso.hpp b/include/boost/graph/vf2_sub_graph_iso.hpp index 77f7496bd..15f2ad3de 100644 --- a/include/boost/graph/vf2_sub_graph_iso.hpp +++ b/include/boost/graph/vf2_sub_graph_iso.hpp @@ -75,6 +75,14 @@ template < typename Graph1, typename Graph2 > struct vf2_print_callback namespace detail { + template + typename graph_traits::vertices_size_type get_num_vertices(Graph& g) + { + typename graph_traits::vertices_size_type N = 0; + BGL_FORALL_VERTICES_T(v, g, Graph) + N++; + return N; + } // State associated with a single graph (graph_this) template < typename GraphThis, typename GraphOther, typename IndexMapThis, @@ -446,6 +454,8 @@ namespace detail base_state< Graph1, Graph2, IndexMap1, IndexMap2 > state1_; base_state< Graph2, Graph1, IndexMap2, IndexMap1 > state2_; + graph1_size_type NV1_; + // Three helper functions used in Feasibility and Valid functions to // test terminal set counts when testing for: // - graph sub-graph monomorphism, or @@ -484,6 +494,7 @@ namespace detail , vertex_comp_(vertex_comp) , state1_(graph1, graph2, index_map1, index_map2) , state2_(graph2, graph1, index_map2, index_map1) + , NV1_(get_num_vertices(graph1)) { } @@ -702,7 +713,7 @@ namespace detail // Returns true if a mapping was found bool success() const { - return state1_.count() == num_vertices(graph1_); + return state1_.count() == NV1_; } // Returns true if a state is valid @@ -754,7 +765,7 @@ namespace detail typename IndexMap2, typename VertexOrder1, typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, typename SubGraphIsoMapCallback, problem_selector problem_selection > - bool match(const Graph1& graph1, const Graph2& graph2, + bool match(const Graph1&, const Graph2& graph2, SubGraphIsoMapCallback user_callback, const VertexOrder1& vertex_order1, state< Graph1, Graph2, IndexMap1, IndexMap2, EdgeEquivalencePredicate, VertexEquivalencePredicate, SubGraphIsoMapCallback, @@ -976,14 +987,19 @@ namespace detail (BinaryPredicateConcept< VertexEquivalencePredicate, vertex_small_type, vertex_large_type >)); + typename graph_traits< GraphSmall >::vertices_size_type num_vertices_small + = get_num_vertices(graph_small); + typename graph_traits< GraphLarge >::vertices_size_type num_vertices_large + = get_num_vertices(graph_large); + // Vertex order requirements BOOST_CONCEPT_ASSERT((ContainerConcept< VertexOrderSmall >)); typedef typename VertexOrderSmall::value_type order_value_type; BOOST_STATIC_ASSERT( (is_same< vertex_small_type, order_value_type >::value)); - BOOST_ASSERT(num_vertices(graph_small) == vertex_order_small.size()); + BOOST_ASSERT(num_vertices_small == vertex_order_small.size()); - if (num_vertices(graph_small) > num_vertices(graph_large)) + if (num_vertices_small > num_vertices_large) return false; typename graph_traits< GraphSmall >::edges_size_type num_edges_small @@ -1182,13 +1198,18 @@ bool vf2_graph_iso(const Graph1& graph1, const Graph2& graph2, BOOST_CONCEPT_ASSERT((BinaryPredicateConcept< VertexEquivalencePredicate, vertex1_type, vertex2_type >)); + typename graph_traits< Graph1 >::vertices_size_type num_vertices1 + = detail::get_num_vertices(graph1); + typename graph_traits< Graph2 >::vertices_size_type num_vertices2 + = detail::get_num_vertices(graph2); + // Vertex order requirements BOOST_CONCEPT_ASSERT((ContainerConcept< VertexOrder1 >)); typedef typename VertexOrder1::value_type order_value_type; BOOST_STATIC_ASSERT((is_same< vertex1_type, order_value_type >::value)); - BOOST_ASSERT(num_vertices(graph1) == vertex_order1.size()); + BOOST_ASSERT(num_vertices1 == vertex_order1.size()); - if (num_vertices(graph1) != num_vertices(graph2)) + if (num_vertices1 != num_vertices2) return false; typename graph_traits< Graph1 >::edges_size_type num_edges1 From 3354d3dbb03a50e1f61029033b7a856aaaf39818 Mon Sep 17 00:00:00 2001 From: Tiago de Paula Peixoto Date: Tue, 4 Jan 2022 09:14:15 +0100 Subject: [PATCH 2/3] vf2_sub_graph_iso.hpp: change get_num_vertices() to O(1) for unfiltered graphs --- include/boost/graph/vf2_sub_graph_iso.hpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/boost/graph/vf2_sub_graph_iso.hpp b/include/boost/graph/vf2_sub_graph_iso.hpp index 15f2ad3de..2a28bba69 100644 --- a/include/boost/graph/vf2_sub_graph_iso.hpp +++ b/include/boost/graph/vf2_sub_graph_iso.hpp @@ -78,10 +78,9 @@ namespace detail template typename graph_traits::vertices_size_type get_num_vertices(Graph& g) { - typename graph_traits::vertices_size_type N = 0; - BGL_FORALL_VERTICES_T(v, g, Graph) - N++; - return N; + typedef typename graph_traits::vertex_iterator iter; + std::pair vs = vertices(g); + return std::distance(vs.first, vs.second); } // State associated with a single graph (graph_this) From 1405d9428453a488891410da3bc21891cad72e23 Mon Sep 17 00:00:00 2001 From: "Jeremy W. Murphy" Date: Wed, 13 Sep 2023 11:19:53 +1000 Subject: [PATCH 3/3] Change identifier style --- include/boost/graph/vf2_sub_graph_iso.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/include/boost/graph/vf2_sub_graph_iso.hpp b/include/boost/graph/vf2_sub_graph_iso.hpp index 2a28bba69..ae1f67f29 100644 --- a/include/boost/graph/vf2_sub_graph_iso.hpp +++ b/include/boost/graph/vf2_sub_graph_iso.hpp @@ -76,7 +76,7 @@ template < typename Graph1, typename Graph2 > struct vf2_print_callback namespace detail { template - typename graph_traits::vertices_size_type get_num_vertices(Graph& g) + typename graph_traits::vertices_size_type get_num_vertices(const Graph& g) { typedef typename graph_traits::vertex_iterator iter; std::pair vs = vertices(g); @@ -453,7 +453,7 @@ namespace detail base_state< Graph1, Graph2, IndexMap1, IndexMap2 > state1_; base_state< Graph2, Graph1, IndexMap2, IndexMap1 > state2_; - graph1_size_type NV1_; + graph1_size_type num_vertices1_; // Three helper functions used in Feasibility and Valid functions to // test terminal set counts when testing for: @@ -493,7 +493,7 @@ namespace detail , vertex_comp_(vertex_comp) , state1_(graph1, graph2, index_map1, index_map2) , state2_(graph2, graph1, index_map2, index_map1) - , NV1_(get_num_vertices(graph1)) + , num_vertices1_(get_num_vertices(graph1)) { } @@ -712,7 +712,7 @@ namespace detail // Returns true if a mapping was found bool success() const { - return state1_.count() == NV1_; + return state1_.count() == num_vertices1_; } // Returns true if a state is valid