/
usr
/
include
/
boost
/
graph
/
/usr/include/boost/graph
mkdir
upload
Name
Size
Mode
Actions
detail/
-
0755
rm
distributed/
-
0755
rm
parallel/
-
0755
rm
planar_detail/
-
0755
rm
property_maps/
-
0755
rm
accounting.hpp
876
0644
edit
dl
rm
adjacency_iterator.hpp
2899
0644
edit
dl
rm
adjacency_list.hpp
13692
0644
edit
dl
rm
adjacency_list_io.hpp
11849
0644
edit
dl
rm
adjacency_matrix.hpp
45743
0644
edit
dl
rm
adj_list_serialize.hpp
4523
0644
edit
dl
rm
astar_search.hpp
26736
0644
edit
dl
rm
bandwidth.hpp
2992
0644
edit
dl
rm
bc_clustering.hpp
5937
0644
edit
dl
rm
bellman_ford_shortest_paths.hpp
8229
0644
edit
dl
rm
betweenness_centrality.hpp
26290
0644
edit
dl
rm
biconnected_components.hpp
16701
0644
edit
dl
rm
bipartite.hpp
13492
0644
edit
dl
rm
boyer_myrvold_planar_test.hpp
9849
0644
edit
dl
rm
boykov_kolmogorov_max_flow.hpp
47342
0644
edit
dl
rm
breadth_first_search.hpp
14751
0644
edit
dl
rm
bron_kerbosch_all_cliques.hpp
11736
0644
edit
dl
rm
buffer_concepts.hpp
2429
0644
edit
dl
rm
chrobak_payne_drawing.hpp
8641
0644
edit
dl
rm
circle_layout.hpp
1924
0644
edit
dl
rm
closeness_centrality.hpp
6057
0644
edit
dl
rm
clustering_coefficient.hpp
5726
0644
edit
dl
rm
compressed_sparse_row_graph.hpp
69887
0644
edit
dl
rm
connected_components.hpp
4134
0644
edit
dl
rm
copy.hpp
21225
0644
edit
dl
rm
core_numbers.hpp
13663
0644
edit
dl
rm
create_condensation_graph.hpp
3159
0644
edit
dl
rm
cuthill_mckee_ordering.hpp
5992
0644
edit
dl
rm
cycle_canceling.hpp
6645
0644
edit
dl
rm
dag_shortest_paths.hpp
6064
0644
edit
dl
rm
degree_centrality.hpp
4236
0644
edit
dl
rm
depth_first_search.hpp
15430
0644
edit
dl
rm
dijkstra_shortest_paths.hpp
23687
0644
edit
dl
rm
dijkstra_shortest_paths_no_color_map.hpp
9620
0644
edit
dl
rm
dimacs.hpp
10448
0644
edit
dl
rm
directed_graph.hpp
24214
0644
edit
dl
rm
dll_import_export.hpp
892
0644
edit
dl
rm
dominator_tree.hpp
17553
0644
edit
dl
rm
eccentricity.hpp
4611
0644
edit
dl
rm
edge_coloring.hpp
6809
0644
edit
dl
rm
edge_connectivity.hpp
6796
0644
edit
dl
rm
edge_list.hpp
9948
0644
edit
dl
rm
edmonds_karp_max_flow.hpp
10177
0644
edit
dl
rm
edmunds_karp_max_flow.hpp
982
0644
edit
dl
rm
erdos_renyi_generator.hpp
7257
0644
edit
dl
rm
exception.hpp
1466
0644
edit
dl
rm
exterior_property.hpp
4289
0644
edit
dl
rm
filtered_graph.hpp
20098
0644
edit
dl
rm
find_flow_cost.hpp
1859
0644
edit
dl
rm
floyd_warshall_shortest.hpp
8510
0644
edit
dl
rm
fruchterman_reingold.hpp
17325
0644
edit
dl
rm
geodesic_distance.hpp
8015
0644
edit
dl
rm
graphml.hpp
13460
0644
edit
dl
rm
graphviz.hpp
33503
0644
edit
dl
rm
graph_archetypes.hpp
11008
0644
edit
dl
rm
graph_as_tree.hpp
4532
0644
edit
dl
rm
graph_concepts.hpp
19785
0644
edit
dl
rm
graph_mutability_traits.hpp
4995
0644
edit
dl
rm
graph_selectors.hpp
1274
0644
edit
dl
rm
graph_stats.hpp
4394
0644
edit
dl
rm
graph_traits.hpp
13065
0644
edit
dl
rm
graph_utility.hpp
16182
0644
edit
dl
rm
grid_graph.hpp
33830
0644
edit
dl
rm
gursoy_atun_layout.hpp
13248
0644
edit
dl
rm
hawick_circuits.hpp
14593
0644
edit
dl
rm
howard_cycle_ratio.hpp
23107
0644
edit
dl
rm
incremental_components.hpp
8224
0644
edit
dl
rm
isomorphism.hpp
26308
0644
edit
dl
rm
is_kuratowski_subgraph.hpp
10260
0644
edit
dl
rm
is_straight_line_drawing.hpp
7230
0644
edit
dl
rm
iteration_macros.hpp
11659
0644
edit
dl
rm
iteration_macros_undef.hpp
673
0644
edit
dl
rm
johnson_all_pairs_shortest.hpp
7646
0644
edit
dl
rm
kamada_kawai_spring_layout.hpp
28048
0644
edit
dl
rm
king_ordering.hpp
12101
0644
edit
dl
rm
kruskal_min_spanning_tree.hpp
5743
0644
edit
dl
rm
labeled_graph.hpp
30914
0644
edit
dl
rm
leda_graph.hpp
28789
0644
edit
dl
rm
lookup_edge.hpp
1894
0644
edit
dl
rm
loop_erased_random_walk.hpp
4436
0644
edit
dl
rm
make_biconnected_planar.hpp
3513
0644
edit
dl
rm
make_connected.hpp
2645
0644
edit
dl
rm
make_maximal_planar.hpp
7578
0644
edit
dl
rm
matrix_as_graph.hpp
7227
0644
edit
dl
rm
maximum_adjacency_search.hpp
15125
0644
edit
dl
rm
maximum_weighted_matching.hpp
49722
0644
edit
dl
rm
max_cardinality_matching.hpp
31000
0644
edit
dl
rm
mcgregor_common_subgraphs.hpp
43470
0644
edit
dl
rm
mesh_graph_generator.hpp
5616
0644
edit
dl
rm
metis.hpp
10982
0644
edit
dl
rm
metric_tsp_approx.hpp
10809
0644
edit
dl
rm
minimum_degree_ordering.hpp
27087
0644
edit
dl
rm
named_function_params.hpp
39639
0644
edit
dl
rm
named_graph.hpp
20614
0644
edit
dl
rm
neighbor_bfs.hpp
11763
0644
edit
dl
rm
numeric_values.hpp
1814
0644
edit
dl
rm
one_bit_color_map.hpp
3277
0644
edit
dl
rm
overloading.hpp
1584
0644
edit
dl
rm
page_rank.hpp
6164
0644
edit
dl
rm
planar_canonical_ordering.hpp
7203
0644
edit
dl
rm
planar_face_traversal.hpp
6020
0644
edit
dl
rm
plod_generator.hpp
7708
0644
edit
dl
rm
point_traits.hpp
782
0644
edit
dl
rm
prim_minimum_spanning_tree.hpp
2960
0644
edit
dl
rm
profile.hpp
1327
0644
edit
dl
rm
properties.hpp
12417
0644
edit
dl
rm
property_iter_range.hpp
4345
0644
edit
dl
rm
push_relabel_max_flow.hpp
34737
0644
edit
dl
rm
random.hpp
9672
0644
edit
dl
rm
random_layout.hpp
988
0644
edit
dl
rm
random_spanning_tree.hpp
5775
0644
edit
dl
rm
read_dimacs.hpp
12080
0644
edit
dl
rm
relax.hpp
4400
0644
edit
dl
rm
reverse_graph.hpp
22402
0644
edit
dl
rm
rmat_graph_generator.hpp
19291
0644
edit
dl
rm
r_c_shortest_paths.hpp
30673
0644
edit
dl
rm
sequential_vertex_coloring.hpp
4562
0644
edit
dl
rm
simple_point.hpp
628
0644
edit
dl
rm
sloan_ordering.hpp
15540
0644
edit
dl
rm
smallest_last_ordering.hpp
5458
0644
edit
dl
rm
small_world_generator.hpp
3670
0644
edit
dl
rm
ssca_graph_generator.hpp
6564
0644
edit
dl
rm
stanford_graph.hpp
20126
0644
edit
dl
rm
stoer_wagner_min_cut.hpp
12415
0644
edit
dl
rm
strong_components.hpp
13009
0644
edit
dl
rm
st_connected.hpp
2852
0644
edit
dl
rm
subgraph.hpp
39996
0644
edit
dl
rm
successive_shortest_path_nonnegative_weights.hpp
10413
0644
edit
dl
rm
tiernan_all_cycles.hpp
12547
0644
edit
dl
rm
topological_sort.hpp
2611
0644
edit
dl
rm
topology.hpp
20389
0644
edit
dl
rm
transitive_closure.hpp
14260
0644
edit
dl
rm
transitive_reduction.hpp
5326
0644
edit
dl
rm
transpose_graph.hpp
1198
0644
edit
dl
rm
tree_traits.hpp
1338
0644
edit
dl
rm
two_bit_color_map.hpp
3510
0644
edit
dl
rm
two_graphs_common_spanning_trees.hpp
34996
0644
edit
dl
rm
undirected_dfs.hpp
10672
0644
edit
dl
rm
undirected_graph.hpp
25276
0644
edit
dl
rm
use_mpi.hpp
437
0644
edit
dl
rm
vector_as_graph.hpp
10474
0644
edit
dl
rm
vertex_and_edge_range.hpp
5528
0644
edit
dl
rm
vf2_sub_graph_iso.hpp
48585
0644
edit
dl
rm
visitors.hpp
11318
0644
edit
dl
rm
wavefront.hpp
3932
0644
edit
dl
rm
write_dimacs.hpp
2889
0644
edit
dl
rm
Edit:
/usr/include/boost/graph/mcgregor_common_subgraphs.hpp
(43470B)
//======================================================================= // Copyright 2009 Trustees of Indiana University. // Authors: Michael Hansen, Andrew Lumsdaine // // Distributed under the Boost Software License, Version 1.0. (See // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) //======================================================================= #ifndef BOOST_GRAPH_MCGREGOR_COMMON_SUBGRAPHS_HPP #define BOOST_GRAPH_MCGREGOR_COMMON_SUBGRAPHS_HPP #include <algorithm> #include <vector> #include <stack> #include <boost/make_shared.hpp> #include <boost/graph/adjacency_list.hpp> #include <boost/graph/filtered_graph.hpp> #include <boost/graph/graph_utility.hpp> #include <boost/graph/iteration_macros.hpp> #include <boost/graph/properties.hpp> #include <boost/property_map/shared_array_property_map.hpp> namespace boost { namespace detail { // Traits associated with common subgraphs, used mainly to keep a // consistent type for the correspondence maps. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond > struct mcgregor_common_subgraph_traits { typedef typename graph_traits< GraphFirst >::vertex_descriptor vertex_first_type; typedef typename graph_traits< GraphSecond >::vertex_descriptor vertex_second_type; typedef shared_array_property_map< vertex_second_type, VertexIndexMapFirst > correspondence_map_first_to_second_type; typedef shared_array_property_map< vertex_first_type, VertexIndexMapSecond > correspondence_map_second_to_first_type; }; } // namespace detail // ========================================================================== // Binary function object that returns true if the values for item1 // in property_map1 and item2 in property_map2 are equivalent. template < typename PropertyMapFirst, typename PropertyMapSecond > struct property_map_equivalent { property_map_equivalent(const PropertyMapFirst property_map1, const PropertyMapSecond property_map2) : m_property_map1(property_map1), m_property_map2(property_map2) { } template < typename ItemFirst, typename ItemSecond > bool operator()(const ItemFirst item1, const ItemSecond item2) { return (get(m_property_map1, item1) == get(m_property_map2, item2)); } private: const PropertyMapFirst m_property_map1; const PropertyMapSecond m_property_map2; }; // Returns a property_map_equivalent object that compares the values // of property_map1 and property_map2. template < typename PropertyMapFirst, typename PropertyMapSecond > property_map_equivalent< PropertyMapFirst, PropertyMapSecond > make_property_map_equivalent( const PropertyMapFirst property_map1, const PropertyMapSecond property_map2) { return (property_map_equivalent< PropertyMapFirst, PropertyMapSecond >( property_map1, property_map2)); } // Binary function object that always returns true. Used when // vertices or edges are always equivalent (i.e. have no labels). struct always_equivalent { template < typename ItemFirst, typename ItemSecond > bool operator()(const ItemFirst&, const ItemSecond&) { return (true); } }; // ========================================================================== namespace detail { // Return true if new_vertex1 and new_vertex2 can extend the // subgraph represented by correspondence_map_1_to_2 and // correspondence_map_2_to_1. The vertices_equivalent and // edges_equivalent predicates are used to test vertex and edge // equivalency between the two graphs. template < typename GraphFirst, typename GraphSecond, typename CorrespondenceMapFirstToSecond, typename CorrespondenceMapSecondToFirst, typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate > bool can_extend_graph(const GraphFirst& graph1, const GraphSecond& graph2, CorrespondenceMapFirstToSecond correspondence_map_1_to_2, CorrespondenceMapSecondToFirst /*correspondence_map_2_to_1*/, typename graph_traits< GraphFirst >::vertices_size_type subgraph_size, typename graph_traits< GraphFirst >::vertex_descriptor new_vertex1, typename graph_traits< GraphSecond >::vertex_descriptor new_vertex2, EdgeEquivalencePredicate edges_equivalent, VertexEquivalencePredicate vertices_equivalent, bool only_connected_subgraphs) { typedef typename graph_traits< GraphSecond >::vertex_descriptor VertexSecond; typedef typename graph_traits< GraphFirst >::edge_descriptor EdgeFirst; typedef typename graph_traits< GraphSecond >::edge_descriptor EdgeSecond; // Check vertex equality if (!vertices_equivalent(new_vertex1, new_vertex2)) { return (false); } // Vertices match and graph is empty, so we can extend the subgraph if (subgraph_size == 0) { return (true); } bool has_one_edge = false; // Verify edges with existing sub-graph BGL_FORALL_VERTICES_T(existing_vertex1, graph1, GraphFirst) { VertexSecond existing_vertex2 = get(correspondence_map_1_to_2, existing_vertex1); // Skip unassociated vertices if (existing_vertex2 == graph_traits< GraphSecond >::null_vertex()) { continue; } // NOTE: This will not work with parallel edges, since the // first matching edge is always chosen. EdgeFirst edge_to_new1, edge_from_new1; bool edge_to_new_exists1 = false, edge_from_new_exists1 = false; EdgeSecond edge_to_new2, edge_from_new2; bool edge_to_new_exists2 = false, edge_from_new_exists2 = false; // Search for edge from existing to new vertex (graph1) BGL_FORALL_OUTEDGES_T(existing_vertex1, edge1, graph1, GraphFirst) { if (target(edge1, graph1) == new_vertex1) { edge_to_new1 = edge1; edge_to_new_exists1 = true; break; } } // Search for edge from existing to new vertex (graph2) BGL_FORALL_OUTEDGES_T(existing_vertex2, edge2, graph2, GraphSecond) { if (target(edge2, graph2) == new_vertex2) { edge_to_new2 = edge2; edge_to_new_exists2 = true; break; } } // Make sure edges from existing to new vertices are equivalent if ((edge_to_new_exists1 != edge_to_new_exists2) || ((edge_to_new_exists1 && edge_to_new_exists2) && !edges_equivalent(edge_to_new1, edge_to_new2))) { return (false); } bool is_undirected1 = is_undirected(graph1), is_undirected2 = is_undirected(graph2); if (is_undirected1 && is_undirected2) { // Edge in both graphs exists and both graphs are undirected if (edge_to_new_exists1 && edge_to_new_exists2) { has_one_edge = true; } continue; } else { if (!is_undirected1) { // Search for edge from new to existing vertex (graph1) BGL_FORALL_OUTEDGES_T( new_vertex1, edge1, graph1, GraphFirst) { if (target(edge1, graph1) == existing_vertex1) { edge_from_new1 = edge1; edge_from_new_exists1 = true; break; } } } if (!is_undirected2) { // Search for edge from new to existing vertex (graph2) BGL_FORALL_OUTEDGES_T( new_vertex2, edge2, graph2, GraphSecond) { if (target(edge2, graph2) == existing_vertex2) { edge_from_new2 = edge2; edge_from_new_exists2 = true; break; } } } // Make sure edges from new to existing vertices are equivalent if ((edge_from_new_exists1 != edge_from_new_exists2) || ((edge_from_new_exists1 && edge_from_new_exists2) && !edges_equivalent(edge_from_new1, edge_from_new2))) { return (false); } if ((edge_from_new_exists1 && edge_from_new_exists2) || (edge_to_new_exists1 && edge_to_new_exists2)) { has_one_edge = true; } } // else } // BGL_FORALL_VERTICES_T // Make sure new vertices are connected to the existing subgraph if (only_connected_subgraphs && !has_one_edge) { return (false); } return (true); } // Recursive method that does a depth-first search in the space of // potential subgraphs. At each level, every new vertex pair from // both graphs is tested to see if it can extend the current // subgraph. If so, the subgraph is output to subgraph_callback // in the form of two correspondence maps (one for each graph). // Returning false from subgraph_callback will terminate the // search. Function returns true if the entire search space was // explored. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond, typename CorrespondenceMapFirstToSecond, typename CorrespondenceMapSecondToFirst, typename VertexStackFirst, typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, typename SubGraphInternalCallback > bool mcgregor_common_subgraphs_internal(const GraphFirst& graph1, const GraphSecond& graph2, const VertexIndexMapFirst& vindex_map1, const VertexIndexMapSecond& vindex_map2, CorrespondenceMapFirstToSecond correspondence_map_1_to_2, CorrespondenceMapSecondToFirst correspondence_map_2_to_1, VertexStackFirst& vertex_stack1, EdgeEquivalencePredicate edges_equivalent, VertexEquivalencePredicate vertices_equivalent, bool only_connected_subgraphs, SubGraphInternalCallback subgraph_callback) { typedef typename graph_traits< GraphFirst >::vertex_descriptor VertexFirst; typedef typename graph_traits< GraphSecond >::vertex_descriptor VertexSecond; typedef typename graph_traits< GraphFirst >::vertices_size_type VertexSizeFirst; // Get iterators for vertices from both graphs typename graph_traits< GraphFirst >::vertex_iterator vertex1_iter, vertex1_end; typename graph_traits< GraphSecond >::vertex_iterator vertex2_begin, vertex2_end, vertex2_iter; boost::tie(vertex1_iter, vertex1_end) = vertices(graph1); boost::tie(vertex2_begin, vertex2_end) = vertices(graph2); vertex2_iter = vertex2_begin; // Iterate until all vertices have been visited BGL_FORALL_VERTICES_T(new_vertex1, graph1, GraphFirst) { VertexSecond existing_vertex2 = get(correspondence_map_1_to_2, new_vertex1); // Skip already matched vertices in first graph if (existing_vertex2 != graph_traits< GraphSecond >::null_vertex()) { continue; } BGL_FORALL_VERTICES_T(new_vertex2, graph2, GraphSecond) { VertexFirst existing_vertex1 = get(correspondence_map_2_to_1, new_vertex2); // Skip already matched vertices in second graph if (existing_vertex1 != graph_traits< GraphFirst >::null_vertex()) { continue; } // Check if current sub-graph can be extended with the matched // vertex pair if (can_extend_graph(graph1, graph2, correspondence_map_1_to_2, correspondence_map_2_to_1, (VertexSizeFirst)vertex_stack1.size(), new_vertex1, new_vertex2, edges_equivalent, vertices_equivalent, only_connected_subgraphs)) { // Keep track of old graph size for restoring later VertexSizeFirst old_graph_size = (VertexSizeFirst)vertex_stack1.size(), new_graph_size = old_graph_size + 1; // Extend subgraph put(correspondence_map_1_to_2, new_vertex1, new_vertex2); put(correspondence_map_2_to_1, new_vertex2, new_vertex1); vertex_stack1.push(new_vertex1); // Returning false from the callback will cancel iteration if (!subgraph_callback(correspondence_map_1_to_2, correspondence_map_2_to_1, new_graph_size)) { return (false); } // Depth-first search into the state space of possible // sub-graphs bool continue_iteration = mcgregor_common_subgraphs_internal(graph1, graph2, vindex_map1, vindex_map2, correspondence_map_1_to_2, correspondence_map_2_to_1, vertex_stack1, edges_equivalent, vertices_equivalent, only_connected_subgraphs, subgraph_callback); if (!continue_iteration) { return (false); } // Restore previous state if (vertex_stack1.size() > old_graph_size) { VertexFirst stack_vertex1 = vertex_stack1.top(); VertexSecond stack_vertex2 = get(correspondence_map_1_to_2, stack_vertex1); // Contract subgraph put(correspondence_map_1_to_2, stack_vertex1, graph_traits< GraphSecond >::null_vertex()); put(correspondence_map_2_to_1, stack_vertex2, graph_traits< GraphFirst >::null_vertex()); vertex_stack1.pop(); } } // if can_extend_graph } // BGL_FORALL_VERTICES_T (graph2) } // BGL_FORALL_VERTICES_T (graph1) return (true); } // Internal method that initializes blank correspondence maps and // a vertex stack for use in mcgregor_common_subgraphs_internal. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond, typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, typename SubGraphInternalCallback > inline void mcgregor_common_subgraphs_internal_init( const GraphFirst& graph1, const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1, const VertexIndexMapSecond vindex_map2, EdgeEquivalencePredicate edges_equivalent, VertexEquivalencePredicate vertices_equivalent, bool only_connected_subgraphs, SubGraphInternalCallback subgraph_callback) { typedef mcgregor_common_subgraph_traits< GraphFirst, GraphSecond, VertexIndexMapFirst, VertexIndexMapSecond > SubGraphTraits; typename SubGraphTraits::correspondence_map_first_to_second_type correspondence_map_1_to_2(num_vertices(graph1), vindex_map1); BGL_FORALL_VERTICES_T(vertex1, graph1, GraphFirst) { put(correspondence_map_1_to_2, vertex1, graph_traits< GraphSecond >::null_vertex()); } typename SubGraphTraits::correspondence_map_second_to_first_type correspondence_map_2_to_1(num_vertices(graph2), vindex_map2); BGL_FORALL_VERTICES_T(vertex2, graph2, GraphSecond) { put(correspondence_map_2_to_1, vertex2, graph_traits< GraphFirst >::null_vertex()); } typedef typename graph_traits< GraphFirst >::vertex_descriptor VertexFirst; std::stack< VertexFirst > vertex_stack1; mcgregor_common_subgraphs_internal(graph1, graph2, vindex_map1, vindex_map2, correspondence_map_1_to_2, correspondence_map_2_to_1, vertex_stack1, edges_equivalent, vertices_equivalent, only_connected_subgraphs, subgraph_callback); } } // namespace detail // ========================================================================== // Enumerates all common subgraphs present in graph1 and graph2. // Continues until the search space has been fully explored or false // is returned from user_callback. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond, typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, typename SubGraphCallback > void mcgregor_common_subgraphs(const GraphFirst& graph1, const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1, const VertexIndexMapSecond vindex_map2, EdgeEquivalencePredicate edges_equivalent, VertexEquivalencePredicate vertices_equivalent, bool only_connected_subgraphs, SubGraphCallback user_callback) { detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, vindex_map1, vindex_map2, edges_equivalent, vertices_equivalent, only_connected_subgraphs, user_callback); } // Variant of mcgregor_common_subgraphs with all default parameters template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback > void mcgregor_common_subgraphs(const GraphFirst& graph1, const GraphSecond& graph2, bool only_connected_subgraphs, SubGraphCallback user_callback) { detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, get(vertex_index, graph1), get(vertex_index, graph2), always_equivalent(), always_equivalent(), only_connected_subgraphs, user_callback); } // Named parameter variant of mcgregor_common_subgraphs template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback, typename Param, typename Tag, typename Rest > void mcgregor_common_subgraphs(const GraphFirst& graph1, const GraphSecond& graph2, bool only_connected_subgraphs, SubGraphCallback user_callback, const bgl_named_params< Param, Tag, Rest >& params) { detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, choose_const_pmap( get_param(params, vertex_index1), graph1, vertex_index), choose_const_pmap( get_param(params, vertex_index2), graph2, vertex_index), choose_param( get_param(params, edges_equivalent_t()), always_equivalent()), choose_param( get_param(params, vertices_equivalent_t()), always_equivalent()), only_connected_subgraphs, user_callback); } // ========================================================================== namespace detail { // Binary function object that intercepts subgraphs from // mcgregor_common_subgraphs_internal and maintains a cache of // unique subgraphs. The user callback is invoked for each unique // subgraph. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond, typename SubGraphCallback > struct unique_subgraph_interceptor { typedef typename graph_traits< GraphFirst >::vertices_size_type VertexSizeFirst; typedef mcgregor_common_subgraph_traits< GraphFirst, GraphSecond, VertexIndexMapFirst, VertexIndexMapSecond > SubGraphTraits; typedef typename SubGraphTraits::correspondence_map_first_to_second_type CachedCorrespondenceMapFirstToSecond; typedef typename SubGraphTraits::correspondence_map_second_to_first_type CachedCorrespondenceMapSecondToFirst; typedef std::pair< VertexSizeFirst, std::pair< CachedCorrespondenceMapFirstToSecond, CachedCorrespondenceMapSecondToFirst > > SubGraph; typedef std::vector< SubGraph > SubGraphList; unique_subgraph_interceptor(const GraphFirst& graph1, const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1, const VertexIndexMapSecond vindex_map2, SubGraphCallback user_callback) : m_graph1(graph1) , m_graph2(graph2) , m_vindex_map1(vindex_map1) , m_vindex_map2(vindex_map2) , m_subgraphs(make_shared< SubGraphList >()) , m_user_callback(user_callback) { } template < typename CorrespondenceMapFirstToSecond, typename CorrespondenceMapSecondToFirst > bool operator()( CorrespondenceMapFirstToSecond correspondence_map_1_to_2, CorrespondenceMapSecondToFirst correspondence_map_2_to_1, VertexSizeFirst subgraph_size) { for (typename SubGraphList::const_iterator subgraph_iter = m_subgraphs->begin(); subgraph_iter != m_subgraphs->end(); ++subgraph_iter) { SubGraph subgraph_cached = *subgraph_iter; // Compare subgraph sizes if (subgraph_size != subgraph_cached.first) { continue; } if (!are_property_maps_different(correspondence_map_1_to_2, subgraph_cached.second.first, m_graph1)) { // New subgraph is a duplicate return (true); } } // Subgraph is unique, so make a cached copy CachedCorrespondenceMapFirstToSecond new_subgraph_1_to_2 = CachedCorrespondenceMapFirstToSecond( num_vertices(m_graph1), m_vindex_map1); CachedCorrespondenceMapSecondToFirst new_subgraph_2_to_1 = CorrespondenceMapSecondToFirst( num_vertices(m_graph2), m_vindex_map2); BGL_FORALL_VERTICES_T(vertex1, m_graph1, GraphFirst) { put(new_subgraph_1_to_2, vertex1, get(correspondence_map_1_to_2, vertex1)); } BGL_FORALL_VERTICES_T(vertex2, m_graph2, GraphFirst) { put(new_subgraph_2_to_1, vertex2, get(correspondence_map_2_to_1, vertex2)); } m_subgraphs->push_back(std::make_pair(subgraph_size, std::make_pair(new_subgraph_1_to_2, new_subgraph_2_to_1))); return (m_user_callback(correspondence_map_1_to_2, correspondence_map_2_to_1, subgraph_size)); } private: const GraphFirst& m_graph1; const GraphFirst& m_graph2; const VertexIndexMapFirst m_vindex_map1; const VertexIndexMapSecond m_vindex_map2; shared_ptr< SubGraphList > m_subgraphs; SubGraphCallback m_user_callback; }; } // namespace detail // Enumerates all unique common subgraphs between graph1 and graph2. // The user callback is invoked for each unique subgraph as they are // discovered. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond, typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, typename SubGraphCallback > void mcgregor_common_subgraphs_unique(const GraphFirst& graph1, const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1, const VertexIndexMapSecond vindex_map2, EdgeEquivalencePredicate edges_equivalent, VertexEquivalencePredicate vertices_equivalent, bool only_connected_subgraphs, SubGraphCallback user_callback) { detail::unique_subgraph_interceptor< GraphFirst, GraphSecond, VertexIndexMapFirst, VertexIndexMapSecond, SubGraphCallback > unique_callback( graph1, graph2, vindex_map1, vindex_map2, user_callback); detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, vindex_map1, vindex_map2, edges_equivalent, vertices_equivalent, only_connected_subgraphs, unique_callback); } // Variant of mcgregor_common_subgraphs_unique with all default // parameters. template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback > void mcgregor_common_subgraphs_unique(const GraphFirst& graph1, const GraphSecond& graph2, bool only_connected_subgraphs, SubGraphCallback user_callback) { mcgregor_common_subgraphs_unique(graph1, graph2, get(vertex_index, graph1), get(vertex_index, graph2), always_equivalent(), always_equivalent(), only_connected_subgraphs, user_callback); } // Named parameter variant of mcgregor_common_subgraphs_unique template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback, typename Param, typename Tag, typename Rest > void mcgregor_common_subgraphs_unique(const GraphFirst& graph1, const GraphSecond& graph2, bool only_connected_subgraphs, SubGraphCallback user_callback, const bgl_named_params< Param, Tag, Rest >& params) { mcgregor_common_subgraphs_unique(graph1, graph2, choose_const_pmap( get_param(params, vertex_index1), graph1, vertex_index), choose_const_pmap( get_param(params, vertex_index2), graph2, vertex_index), choose_param( get_param(params, edges_equivalent_t()), always_equivalent()), choose_param( get_param(params, vertices_equivalent_t()), always_equivalent()), only_connected_subgraphs, user_callback); } // ========================================================================== namespace detail { // Binary function object that intercepts subgraphs from // mcgregor_common_subgraphs_internal and maintains a cache of the // largest subgraphs. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond, typename SubGraphCallback > struct maximum_subgraph_interceptor { typedef typename graph_traits< GraphFirst >::vertices_size_type VertexSizeFirst; typedef mcgregor_common_subgraph_traits< GraphFirst, GraphSecond, VertexIndexMapFirst, VertexIndexMapSecond > SubGraphTraits; typedef typename SubGraphTraits::correspondence_map_first_to_second_type CachedCorrespondenceMapFirstToSecond; typedef typename SubGraphTraits::correspondence_map_second_to_first_type CachedCorrespondenceMapSecondToFirst; typedef std::pair< VertexSizeFirst, std::pair< CachedCorrespondenceMapFirstToSecond, CachedCorrespondenceMapSecondToFirst > > SubGraph; typedef std::vector< SubGraph > SubGraphList; maximum_subgraph_interceptor(const GraphFirst& graph1, const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1, const VertexIndexMapSecond vindex_map2, SubGraphCallback user_callback) : m_graph1(graph1) , m_graph2(graph2) , m_vindex_map1(vindex_map1) , m_vindex_map2(vindex_map2) , m_subgraphs(make_shared< SubGraphList >()) , m_largest_size_so_far(make_shared< VertexSizeFirst >(0)) , m_user_callback(user_callback) { } template < typename CorrespondenceMapFirstToSecond, typename CorrespondenceMapSecondToFirst > bool operator()( CorrespondenceMapFirstToSecond correspondence_map_1_to_2, CorrespondenceMapSecondToFirst correspondence_map_2_to_1, VertexSizeFirst subgraph_size) { if (subgraph_size > *m_largest_size_so_far) { m_subgraphs->clear(); *m_largest_size_so_far = subgraph_size; } if (subgraph_size == *m_largest_size_so_far) { // Make a cached copy CachedCorrespondenceMapFirstToSecond new_subgraph_1_to_2 = CachedCorrespondenceMapFirstToSecond( num_vertices(m_graph1), m_vindex_map1); CachedCorrespondenceMapSecondToFirst new_subgraph_2_to_1 = CachedCorrespondenceMapSecondToFirst( num_vertices(m_graph2), m_vindex_map2); BGL_FORALL_VERTICES_T(vertex1, m_graph1, GraphFirst) { put(new_subgraph_1_to_2, vertex1, get(correspondence_map_1_to_2, vertex1)); } BGL_FORALL_VERTICES_T(vertex2, m_graph2, GraphFirst) { put(new_subgraph_2_to_1, vertex2, get(correspondence_map_2_to_1, vertex2)); } m_subgraphs->push_back(std::make_pair(subgraph_size, std::make_pair(new_subgraph_1_to_2, new_subgraph_2_to_1))); } return (true); } void output_subgraphs() { for (typename SubGraphList::const_iterator subgraph_iter = m_subgraphs->begin(); subgraph_iter != m_subgraphs->end(); ++subgraph_iter) { SubGraph subgraph_cached = *subgraph_iter; m_user_callback(subgraph_cached.second.first, subgraph_cached.second.second, subgraph_cached.first); } } private: const GraphFirst& m_graph1; const GraphFirst& m_graph2; const VertexIndexMapFirst m_vindex_map1; const VertexIndexMapSecond m_vindex_map2; shared_ptr< SubGraphList > m_subgraphs; shared_ptr< VertexSizeFirst > m_largest_size_so_far; SubGraphCallback m_user_callback; }; } // namespace detail // Enumerates the largest common subgraphs found between graph1 // and graph2. Note that the ENTIRE search space is explored before // user_callback is actually invoked. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond, typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, typename SubGraphCallback > void mcgregor_common_subgraphs_maximum(const GraphFirst& graph1, const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1, const VertexIndexMapSecond vindex_map2, EdgeEquivalencePredicate edges_equivalent, VertexEquivalencePredicate vertices_equivalent, bool only_connected_subgraphs, SubGraphCallback user_callback) { detail::maximum_subgraph_interceptor< GraphFirst, GraphSecond, VertexIndexMapFirst, VertexIndexMapSecond, SubGraphCallback > max_interceptor( graph1, graph2, vindex_map1, vindex_map2, user_callback); detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, vindex_map1, vindex_map2, edges_equivalent, vertices_equivalent, only_connected_subgraphs, max_interceptor); // Only output the largest subgraphs max_interceptor.output_subgraphs(); } // Variant of mcgregor_common_subgraphs_maximum with all default // parameters. template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback > void mcgregor_common_subgraphs_maximum(const GraphFirst& graph1, const GraphSecond& graph2, bool only_connected_subgraphs, SubGraphCallback user_callback) { mcgregor_common_subgraphs_maximum(graph1, graph2, get(vertex_index, graph1), get(vertex_index, graph2), always_equivalent(), always_equivalent(), only_connected_subgraphs, user_callback); } // Named parameter variant of mcgregor_common_subgraphs_maximum template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback, typename Param, typename Tag, typename Rest > void mcgregor_common_subgraphs_maximum(const GraphFirst& graph1, const GraphSecond& graph2, bool only_connected_subgraphs, SubGraphCallback user_callback, const bgl_named_params< Param, Tag, Rest >& params) { mcgregor_common_subgraphs_maximum(graph1, graph2, choose_const_pmap( get_param(params, vertex_index1), graph1, vertex_index), choose_const_pmap( get_param(params, vertex_index2), graph2, vertex_index), choose_param( get_param(params, edges_equivalent_t()), always_equivalent()), choose_param( get_param(params, vertices_equivalent_t()), always_equivalent()), only_connected_subgraphs, user_callback); } // ========================================================================== namespace detail { // Binary function object that intercepts subgraphs from // mcgregor_common_subgraphs_internal and maintains a cache of the // largest, unique subgraphs. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond, typename SubGraphCallback > struct unique_maximum_subgraph_interceptor { typedef typename graph_traits< GraphFirst >::vertices_size_type VertexSizeFirst; typedef mcgregor_common_subgraph_traits< GraphFirst, GraphSecond, VertexIndexMapFirst, VertexIndexMapSecond > SubGraphTraits; typedef typename SubGraphTraits::correspondence_map_first_to_second_type CachedCorrespondenceMapFirstToSecond; typedef typename SubGraphTraits::correspondence_map_second_to_first_type CachedCorrespondenceMapSecondToFirst; typedef std::pair< VertexSizeFirst, std::pair< CachedCorrespondenceMapFirstToSecond, CachedCorrespondenceMapSecondToFirst > > SubGraph; typedef std::vector< SubGraph > SubGraphList; unique_maximum_subgraph_interceptor(const GraphFirst& graph1, const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1, const VertexIndexMapSecond vindex_map2, SubGraphCallback user_callback) : m_graph1(graph1) , m_graph2(graph2) , m_vindex_map1(vindex_map1) , m_vindex_map2(vindex_map2) , m_subgraphs(make_shared< SubGraphList >()) , m_largest_size_so_far(make_shared< VertexSizeFirst >(0)) , m_user_callback(user_callback) { } template < typename CorrespondenceMapFirstToSecond, typename CorrespondenceMapSecondToFirst > bool operator()( CorrespondenceMapFirstToSecond correspondence_map_1_to_2, CorrespondenceMapSecondToFirst correspondence_map_2_to_1, VertexSizeFirst subgraph_size) { if (subgraph_size > *m_largest_size_so_far) { m_subgraphs->clear(); *m_largest_size_so_far = subgraph_size; } if (subgraph_size == *m_largest_size_so_far) { // Check if subgraph is unique for (typename SubGraphList::const_iterator subgraph_iter = m_subgraphs->begin(); subgraph_iter != m_subgraphs->end(); ++subgraph_iter) { SubGraph subgraph_cached = *subgraph_iter; if (!are_property_maps_different(correspondence_map_1_to_2, subgraph_cached.second.first, m_graph1)) { // New subgraph is a duplicate return (true); } } // Subgraph is unique, so make a cached copy CachedCorrespondenceMapFirstToSecond new_subgraph_1_to_2 = CachedCorrespondenceMapFirstToSecond( num_vertices(m_graph1), m_vindex_map1); CachedCorrespondenceMapSecondToFirst new_subgraph_2_to_1 = CachedCorrespondenceMapSecondToFirst( num_vertices(m_graph2), m_vindex_map2); BGL_FORALL_VERTICES_T(vertex1, m_graph1, GraphFirst) { put(new_subgraph_1_to_2, vertex1, get(correspondence_map_1_to_2, vertex1)); } BGL_FORALL_VERTICES_T(vertex2, m_graph2, GraphFirst) { put(new_subgraph_2_to_1, vertex2, get(correspondence_map_2_to_1, vertex2)); } m_subgraphs->push_back(std::make_pair(subgraph_size, std::make_pair(new_subgraph_1_to_2, new_subgraph_2_to_1))); } return (true); } void output_subgraphs() { for (typename SubGraphList::const_iterator subgraph_iter = m_subgraphs->begin(); subgraph_iter != m_subgraphs->end(); ++subgraph_iter) { SubGraph subgraph_cached = *subgraph_iter; m_user_callback(subgraph_cached.second.first, subgraph_cached.second.second, subgraph_cached.first); } } private: const GraphFirst& m_graph1; const GraphFirst& m_graph2; const VertexIndexMapFirst m_vindex_map1; const VertexIndexMapSecond m_vindex_map2; shared_ptr< SubGraphList > m_subgraphs; shared_ptr< VertexSizeFirst > m_largest_size_so_far; SubGraphCallback m_user_callback; }; } // namespace detail // Enumerates the largest, unique common subgraphs found between // graph1 and graph2. Note that the ENTIRE search space is explored // before user_callback is actually invoked. template < typename GraphFirst, typename GraphSecond, typename VertexIndexMapFirst, typename VertexIndexMapSecond, typename EdgeEquivalencePredicate, typename VertexEquivalencePredicate, typename SubGraphCallback > void mcgregor_common_subgraphs_maximum_unique(const GraphFirst& graph1, const GraphSecond& graph2, const VertexIndexMapFirst vindex_map1, const VertexIndexMapSecond vindex_map2, EdgeEquivalencePredicate edges_equivalent, VertexEquivalencePredicate vertices_equivalent, bool only_connected_subgraphs, SubGraphCallback user_callback) { detail::unique_maximum_subgraph_interceptor< GraphFirst, GraphSecond, VertexIndexMapFirst, VertexIndexMapSecond, SubGraphCallback > unique_max_interceptor( graph1, graph2, vindex_map1, vindex_map2, user_callback); detail::mcgregor_common_subgraphs_internal_init(graph1, graph2, vindex_map1, vindex_map2, edges_equivalent, vertices_equivalent, only_connected_subgraphs, unique_max_interceptor); // Only output the largest, unique subgraphs unique_max_interceptor.output_subgraphs(); } // Variant of mcgregor_common_subgraphs_maximum_unique with all default // parameters template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback > void mcgregor_common_subgraphs_maximum_unique(const GraphFirst& graph1, const GraphSecond& graph2, bool only_connected_subgraphs, SubGraphCallback user_callback) { mcgregor_common_subgraphs_maximum_unique(graph1, graph2, get(vertex_index, graph1), get(vertex_index, graph2), always_equivalent(), always_equivalent(), only_connected_subgraphs, user_callback); } // Named parameter variant of // mcgregor_common_subgraphs_maximum_unique template < typename GraphFirst, typename GraphSecond, typename SubGraphCallback, typename Param, typename Tag, typename Rest > void mcgregor_common_subgraphs_maximum_unique(const GraphFirst& graph1, const GraphSecond& graph2, bool only_connected_subgraphs, SubGraphCallback user_callback, const bgl_named_params< Param, Tag, Rest >& params) { mcgregor_common_subgraphs_maximum_unique(graph1, graph2, choose_const_pmap( get_param(params, vertex_index1), graph1, vertex_index), choose_const_pmap( get_param(params, vertex_index2), graph2, vertex_index), choose_param( get_param(params, edges_equivalent_t()), always_equivalent()), choose_param( get_param(params, vertices_equivalent_t()), always_equivalent()), only_connected_subgraphs, user_callback); } // ========================================================================== // Fills a membership map (vertex -> bool) using the information // present in correspondence_map_1_to_2. Every vertex in a // membership map will have a true value only if it is not // associated with a null vertex in the correspondence map. template < typename GraphSecond, typename GraphFirst, typename CorrespondenceMapFirstToSecond, typename MembershipMapFirst > void fill_membership_map(const GraphFirst& graph1, const CorrespondenceMapFirstToSecond correspondence_map_1_to_2, MembershipMapFirst membership_map1) { BGL_FORALL_VERTICES_T(vertex1, graph1, GraphFirst) { put(membership_map1, vertex1, get(correspondence_map_1_to_2, vertex1) != graph_traits< GraphSecond >::null_vertex()); } } // Traits associated with a membership map filtered graph. Provided // for convenience to access graph and vertex filter types. template < typename Graph, typename MembershipMap > struct membership_filtered_graph_traits { typedef property_map_filter< MembershipMap > vertex_filter_type; typedef filtered_graph< Graph, keep_all, vertex_filter_type > graph_type; }; // Returns a filtered sub-graph of graph whose edge and vertex // inclusion is dictated by membership_map. template < typename Graph, typename MembershipMap > typename membership_filtered_graph_traits< Graph, MembershipMap >::graph_type make_membership_filtered_graph( const Graph& graph, MembershipMap& membership_map) { typedef membership_filtered_graph_traits< Graph, MembershipMap > MFGTraits; typedef typename MFGTraits::graph_type MembershipFilteredGraph; typename MFGTraits::vertex_filter_type v_filter(membership_map); return (MembershipFilteredGraph(graph, keep_all(), v_filter)); } } // namespace boost #endif // BOOST_GRAPH_MCGREGOR_COMMON_SUBGRAPHS_HPP
Save
cmd:
run