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