| 567 | | |
| 568 | | return comp_term_sets(term_in1_count, term_in2_count, |
| 569 | | boost::mpl::int_<problem_selection>()) && |
| 570 | | comp_term_sets(term_out1_count, term_out2_count, |
| 571 | | boost::mpl::int_<problem_selection>()) && |
| 572 | | comp_term_sets(rest1_count, rest2_count, |
| 573 | | boost::mpl::int_<problem_selection>()); |
| | 577 | |
| | 578 | if (problem_selection != subgraph_mono) { // subgraph_iso and isomorphism |
| | 579 | return comp_term_sets(term_in1_count, term_in2_count, |
| | 580 | boost::mpl::int_<problem_selection>()) && |
| | 581 | comp_term_sets(term_out1_count, term_out2_count, |
| | 582 | boost::mpl::int_<problem_selection>()) && |
| | 583 | comp_term_sets(rest1_count, rest2_count, |
| | 584 | boost::mpl::int_<problem_selection>()); |
| | 585 | } else { // subgraph_mono |
| | 586 | return comp_term_sets(term_in1_count, term_in2_count, |
| | 587 | boost::mpl::int_<problem_selection>()) && |
| | 588 | comp_term_sets(term_out1_count, term_out2_count, |
| | 589 | boost::mpl::int_<problem_selection>()) && |
| | 590 | comp_term_sets(term_in1_count + term_out1_count + rest1_count, |
| | 591 | term_in2_count + term_out2_count + rest2_count, |
| | 592 | boost::mpl::int_<problem_selection>()); |
| | 593 | } |
| | 813 | // Enumerates all graph sub-graph mono-/iso-morphism mappings between graphs |
| | 814 | // graph_small and graph_large. Continues until user_callback returns true or the |
| | 815 | // search space has been fully explored. |
| | 816 | template <problem_selector problem_selection, |
| | 817 | typename GraphSmall, |
| | 818 | typename GraphLarge, |
| | 819 | typename IndexMapSmall, |
| | 820 | typename IndexMapLarge, |
| | 821 | typename VertexOrderSmall, |
| | 822 | typename EdgeEquivalencePredicate, |
| | 823 | typename VertexEquivalencePredicate, |
| | 824 | typename SubGraphIsoMapCallback> |
| | 825 | bool vf2_subgraph_morphism(const GraphSmall& graph_small, const GraphLarge& graph_large, |
| | 826 | SubGraphIsoMapCallback user_callback, |
| | 827 | IndexMapSmall index_map_small, IndexMapLarge index_map_large, |
| | 828 | const VertexOrderSmall& vertex_order_small, |
| | 829 | EdgeEquivalencePredicate edge_comp, |
| | 830 | VertexEquivalencePredicate vertex_comp) { |
| | 831 | |
| | 832 | // Graph requirements |
| | 833 | BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<GraphSmall> )); |
| | 834 | BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<GraphSmall> )); |
| | 835 | BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept<GraphSmall> )); |
| | 836 | BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept<GraphSmall> )); |
| | 837 | |
| | 838 | BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<GraphLarge> )); |
| | 839 | BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<GraphLarge> )); |
| | 840 | BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept<GraphLarge> )); |
| | 841 | BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept<GraphLarge> )); |
| | 842 | |
| | 843 | typedef typename graph_traits<GraphSmall>::vertex_descriptor vertex_small_type; |
| | 844 | typedef typename graph_traits<GraphLarge>::vertex_descriptor vertex_large_type; |
| | 845 | |
| | 846 | typedef typename graph_traits<GraphSmall>::vertices_size_type size_type_small; |
| | 847 | typedef typename graph_traits<GraphLarge>::vertices_size_type size_type_large; |
| | 848 | |
| | 849 | // Property map requirements |
| | 850 | BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<IndexMapSmall, vertex_small_type> )); |
| | 851 | typedef typename property_traits<IndexMapSmall>::value_type IndexMapSmallValue; |
| | 852 | BOOST_STATIC_ASSERT(( is_convertible<IndexMapSmallValue, size_type_small>::value )); |
| | 853 | |
| | 854 | BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<IndexMapLarge, vertex_large_type> )); |
| | 855 | typedef typename property_traits<IndexMapLarge>::value_type IndexMapLargeValue; |
| | 856 | BOOST_STATIC_ASSERT(( is_convertible<IndexMapLargeValue, size_type_large>::value )); |
| | 857 | |
| | 858 | // Edge & vertex requirements |
| | 859 | typedef typename graph_traits<GraphSmall>::edge_descriptor edge_small_type; |
| | 860 | typedef typename graph_traits<GraphLarge>::edge_descriptor edge_large_type; |
| | 861 | |
| | 862 | BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept<EdgeEquivalencePredicate, |
| | 863 | edge_small_type, edge_large_type> )); |
| | 864 | |
| | 865 | BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept<VertexEquivalencePredicate, |
| | 866 | vertex_small_type, vertex_large_type> )); |
| | 867 | |
| | 868 | // Vertex order requirements |
| | 869 | BOOST_CONCEPT_ASSERT(( ContainerConcept<VertexOrderSmall> )); |
| | 870 | typedef typename VertexOrderSmall::value_type order_value_type; |
| | 871 | BOOST_STATIC_ASSERT(( is_same<vertex_small_type, order_value_type>::value )); |
| | 872 | BOOST_ASSERT( num_vertices(graph_small) == vertex_order_small.size() ); |
| | 873 | |
| | 874 | if (num_vertices(graph_small) > num_vertices(graph_large)) |
| | 875 | return false; |
| | 876 | |
| | 877 | typename graph_traits<GraphSmall>::edges_size_type num_edges_small = num_edges(graph_small); |
| | 878 | typename graph_traits<GraphLarge>::edges_size_type num_edges_large = num_edges(graph_large); |
| | 879 | |
| | 880 | // Double the number of edges for undirected graphs: each edge counts as |
| | 881 | // in-edge and out-edge |
| | 882 | if (is_undirected(graph_small)) num_edges_small *= 2; |
| | 883 | if (is_undirected(graph_large)) num_edges_large *= 2; |
| | 884 | if (num_edges_small > num_edges_large) |
| | 885 | return false; |
| | 886 | |
| | 887 | if ((num_vertices(graph_small) == 0) && (num_vertices(graph_large) == 0)) |
| | 888 | return true; |
| | 889 | |
| | 890 | detail::state<GraphSmall, GraphLarge, IndexMapSmall, IndexMapLarge, |
| | 891 | EdgeEquivalencePredicate, VertexEquivalencePredicate, |
| | 892 | SubGraphIsoMapCallback, problem_selection> |
| | 893 | s(graph_small, graph_large, index_map_small, index_map_large, edge_comp, vertex_comp); |
| | 894 | |
| | 895 | return detail::match(graph_small, graph_large, user_callback, vertex_order_small, s); |
| | 896 | } |
| | 897 | |
| | 913 | |
| | 914 | // Enumerates all graph sub-graph monomorphism mappings between graphs |
| | 915 | // graph_small and graph_large. Continues until user_callback returns true or the |
| | 916 | // search space has been fully explored. |
| | 917 | template <typename GraphSmall, |
| | 918 | typename GraphLarge, |
| | 919 | typename IndexMapSmall, |
| | 920 | typename IndexMapLarge, |
| | 921 | typename VertexOrderSmall, |
| | 922 | typename EdgeEquivalencePredicate, |
| | 923 | typename VertexEquivalencePredicate, |
| | 924 | typename SubGraphIsoMapCallback> |
| | 925 | bool vf2_subgraph_mono(const GraphSmall& graph_small, const GraphLarge& graph_large, |
| | 926 | SubGraphIsoMapCallback user_callback, |
| | 927 | IndexMapSmall index_map_small, IndexMapLarge index_map_large, |
| | 928 | const VertexOrderSmall& vertex_order_small, |
| | 929 | EdgeEquivalencePredicate edge_comp, |
| | 930 | VertexEquivalencePredicate vertex_comp) { |
| | 931 | return detail::vf2_subgraph_morphism<detail::subgraph_mono> |
| | 932 | (graph_small, graph_large, |
| | 933 | user_callback, |
| | 934 | index_map_small, index_map_large, |
| | 935 | vertex_order_small, |
| | 936 | edge_comp, |
| | 937 | vertex_comp); |
| | 938 | } |
| | 939 | |
| | 940 | |
| | 941 | // All default interface for vf2_subgraph_iso |
| | 942 | template <typename GraphSmall, |
| | 943 | typename GraphLarge, |
| | 944 | typename SubGraphIsoMapCallback> |
| | 945 | bool vf2_subgraph_mono(const GraphSmall& graph_small, const GraphLarge& graph_large, |
| | 946 | SubGraphIsoMapCallback user_callback) { |
| | 947 | return vf2_subgraph_mono(graph_small, graph_large, user_callback, |
| | 948 | get(vertex_index, graph_small), get(vertex_index, graph_large), |
| | 949 | vertex_order_by_mult(graph_small), |
| | 950 | always_equivalent(), always_equivalent()); |
| | 951 | } |
| | 952 | |
| | 953 | |
| | 954 | // Named parameter interface of vf2_subgraph_iso |
| | 955 | template <typename GraphSmall, |
| | 956 | typename GraphLarge, |
| | 957 | typename VertexOrderSmall, |
| | 958 | typename SubGraphIsoMapCallback, |
| | 959 | typename Param, |
| | 960 | typename Tag, |
| | 961 | typename Rest> |
| | 962 | bool vf2_subgraph_mono(const GraphSmall& graph_small, const GraphLarge& graph_large, |
| | 963 | SubGraphIsoMapCallback user_callback, |
| | 964 | const VertexOrderSmall& vertex_order_small, |
| | 965 | const bgl_named_params<Param, Tag, Rest>& params) { |
| | 966 | return vf2_subgraph_mono(graph_small, graph_large, user_callback, |
| | 967 | choose_const_pmap(get_param(params, vertex_index1), |
| | 968 | graph_small, vertex_index), |
| | 969 | choose_const_pmap(get_param(params, vertex_index2), |
| | 970 | graph_large, vertex_index), |
| | 971 | vertex_order_small, |
| | 972 | choose_param(get_param(params, edges_equivalent_t()), |
| | 973 | always_equivalent()), |
| | 974 | choose_param(get_param(params, vertices_equivalent_t()), |
| | 975 | always_equivalent()) |
| | 976 | ); |
| | 977 | } |
| 826 | | |
| 827 | | // Graph requirements |
| 828 | | BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<GraphSmall> )); |
| 829 | | BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<GraphSmall> )); |
| 830 | | BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept<GraphSmall> )); |
| 831 | | BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept<GraphSmall> )); |
| 832 | | |
| 833 | | BOOST_CONCEPT_ASSERT(( BidirectionalGraphConcept<GraphLarge> )); |
| 834 | | BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<GraphLarge> )); |
| 835 | | BOOST_CONCEPT_ASSERT(( EdgeListGraphConcept<GraphLarge> )); |
| 836 | | BOOST_CONCEPT_ASSERT(( AdjacencyMatrixConcept<GraphLarge> )); |
| 837 | | |
| 838 | | typedef typename graph_traits<GraphSmall>::vertex_descriptor vertex_small_type; |
| 839 | | typedef typename graph_traits<GraphLarge>::vertex_descriptor vertex_large_type; |
| 840 | | |
| 841 | | typedef typename graph_traits<GraphSmall>::vertices_size_type size_type_small; |
| 842 | | typedef typename graph_traits<GraphLarge>::vertices_size_type size_type_large; |
| 843 | | |
| 844 | | // Property map requirements |
| 845 | | BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<IndexMapSmall, vertex_small_type> )); |
| 846 | | typedef typename property_traits<IndexMapSmall>::value_type IndexMapSmallValue; |
| 847 | | BOOST_STATIC_ASSERT(( is_convertible<IndexMapSmallValue, size_type_small>::value )); |
| 848 | | |
| 849 | | BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<IndexMapLarge, vertex_large_type> )); |
| 850 | | typedef typename property_traits<IndexMapLarge>::value_type IndexMapLargeValue; |
| 851 | | BOOST_STATIC_ASSERT(( is_convertible<IndexMapLargeValue, size_type_large>::value )); |
| 852 | | |
| 853 | | // Edge & vertex requirements |
| 854 | | typedef typename graph_traits<GraphSmall>::edge_descriptor edge_small_type; |
| 855 | | typedef typename graph_traits<GraphLarge>::edge_descriptor edge_large_type; |
| 856 | | |
| 857 | | BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept<EdgeEquivalencePredicate, |
| 858 | | edge_small_type, edge_large_type> )); |
| 859 | | |
| 860 | | BOOST_CONCEPT_ASSERT(( BinaryPredicateConcept<VertexEquivalencePredicate, |
| 861 | | vertex_small_type, vertex_large_type> )); |
| 862 | | |
| 863 | | // Vertex order requirements |
| 864 | | BOOST_CONCEPT_ASSERT(( ContainerConcept<VertexOrderSmall> )); |
| 865 | | typedef typename VertexOrderSmall::value_type order_value_type; |
| 866 | | BOOST_STATIC_ASSERT(( is_same<vertex_small_type, order_value_type>::value )); |
| 867 | | BOOST_ASSERT( num_vertices(graph_small) == vertex_order_small.size() ); |
| 868 | | |
| 869 | | if (num_vertices(graph_small) > num_vertices(graph_large)) |
| 870 | | return false; |
| 871 | | |
| 872 | | typename graph_traits<GraphSmall>::edges_size_type num_edges_small = num_edges(graph_small); |
| 873 | | typename graph_traits<GraphLarge>::edges_size_type num_edges_large = num_edges(graph_large); |
| 874 | | |
| 875 | | // Double the number of edges for undirected graphs: each edge counts as |
| 876 | | // in-edge and out-edge |
| 877 | | if (is_undirected(graph_small)) num_edges_small *= 2; |
| 878 | | if (is_undirected(graph_large)) num_edges_large *= 2; |
| 879 | | if (num_edges_small > num_edges_large) |
| 880 | | return false; |
| 881 | | |
| 882 | | if ((num_vertices(graph_small) == 0) && (num_vertices(graph_large) == 0)) |
| 883 | | return true; |
| 884 | | |
| 885 | | detail::state<GraphSmall, GraphLarge, IndexMapSmall, IndexMapLarge, |
| 886 | | EdgeEquivalencePredicate, VertexEquivalencePredicate, |
| 887 | | SubGraphIsoMapCallback, detail::subgraph_iso> |
| 888 | | s(graph_small, graph_large, index_map_small, index_map_large, edge_comp, vertex_comp); |
| 889 | | |
| 890 | | return detail::match(graph_small, graph_large, user_callback, vertex_order_small, s); |
| | 997 | return detail::vf2_subgraph_morphism<detail::subgraph_iso> |
| | 998 | (graph_small, graph_large, |
| | 999 | user_callback, |
| | 1000 | index_map_small, index_map_large, |
| | 1001 | vertex_order_small, |
| | 1002 | edge_comp, |
| | 1003 | vertex_comp); |