This algorithm finds all common subgraphs
between graph1 and graph2 and outputs them
to user_callback. The edges_equivalent
and vertices_equivalent predicates are used to
determine edges and vertex equivalence between the two graphs.
To use property maps for equivalence, look at
the make_property_map_equivalent
function. By
default, always_equivalent
is used, which returns true for any pair of edges or vertices.

McGregor's algorithm does a depth-first search on the space of
possible common subgraphs. At each level, every unvisited pair
of vertices from graph1 and graph2 are checked
to see if they can extend the current subgraph. This is done in
three steps (assume vertex1 is
from graph1 and vertex2 is
from graph2):

Verify that the vertex1 and vertex2 are
equivalent using the vertices_equivalent predicate.

For every vertex pair
(existing_vertex1, existing_vertex2) in
the current subgraph, ensure that any edges
between vertex1 and existing_vertex1
in graph1 and between vertex2
and existing_vertex2 in graph2 match
(i.e. either both exist of both don't exist). If both edges
exist, they are checked for equivalence using
the edges_equivalent predicate.

Lastly (and optionally), make sure that the new subgraph
vertex has at least one edge connecting it to the existing
subgraph. When the only_connected_subgraphs
parameter is false, this step is skipped.

Where Defined

Parameters

IN: const GraphFirst& graph1

The first graph of the pair to be searched. The
type GraphFirst must be a model of
Vertex List Graph
and Incidence Graph. All
parameters with a "1"
(i.e. vindex_map1, correspondence_map_1_to_2)
use this graph's vertices as keys.

IN: const GraphSecond& graph2

The second graph of the pair to be searched. The
type Graphsecond must be a model of
Vertex List Graph
and Incidence Graph. All
parameters with a "2"
(i.e. vindex_map2, correspondence_map_2_to_1)
use this graph's vertices as keys.

IN: bool only_connected_subgraphs

If true, subgraphs are expanded only when matching vertices
have at least one edge connecting them to the existing subgraph.

OUT: SubGraphCallback user_callback

A function object that will be invoked when a subgraph has been discovered. The operator() must have the following form:

Both the CorrespondenceMapFirstToSecond
and CorresondenceMapSecondToFirst types are models
of Readable
Property Map and map equivalent vertices across the two
graphs given to mcgregor_common_subgraphs. For
example, if vertex1 is
from graph1, vertex2 is from graph2,
and the vertices can be considered equivalent in the subgraph,
then get(correspondence_map_1_to_2, vertex1) will
be vertex2 and get(correspondence_map_2_to_1,
vertex2) will be vertex1. If any vertex,
say vertex1 in graph1, doesn't match a vertex
in the other graph (graph2 in this example),
then get(correspondence_map_1_to_2, vertex1) will
be graph_traits<GraphSecond>::null_vertex().
Likewise for any un-matched vertices from graph2,
get(correspondence_map_2_to_1, vertex2) will
be graph_traits<GraphFirst>::null_vertex().

The subgraph_size parameter is the number
of vertices in the subgraph, or the number of matched vertex
pairs contained in the correspondence maps. This can be used to
quickly filter out subgraphs whose sizes do not fall within the
desired range.

Returning false from the
callback will abort the search immediately. Otherwise, the
entire search space will be explored [1].

Named Parameters

IN: vertex_index1(VertexIndexMapFirst vindex_map1)

This maps each vertex to an integer in the range [0,
num_vertices(graph1)]. This is necessary for efficient storage
of the subgraphs. The type VertexIndexMapFirst must be a model of
Readable Property Map.
Default:get(vertex_index, graph1)

IN: vertex_index2(VertexIndexMapsecond vindex_map2)

This maps each vertex to an integer in the range [0,
num_vertices(graph2)]. This is necessary for efficient storage
of the subgraphs. The type VertexIndexMapFirst must be a model of
Readable Property Map.
Default:get(vertex_index, graph2)

IN: edges_equivalent(EdgeEquivalencePredicate edges_equivalent)

This function is used to determine if edges
between graph1 and graph2 are equivalent.
The EdgeEquivalencePredicate type must be a model
of Binary
Predicate and have argument types
of graph_traits<GraphFirst>::edge_descriptor
and graph_traits<GraphSecond>::edge_descriptor.
A return value of true indicates that the edges are
equivalent. Default:always_equivalent

This function is used to determine if vertices
between graph1 and graph2 are equivalent.
The VertexEquivalencePredicate type must be a model
of Binary
Predicate and have argument types
of graph_traits<GraphFirst>::vertex_descriptor
and graph_traits<GraphSecond>::vertex_descriptor.
A return value of true indicates that the vertices are
equivalent.Default:always_equivalent

Related Functions

Each mcgregor_common_subgraphs_* function below takes
the same parameters as mcgregor_common_subgraphs.

mcgregor_common_subgraphs_unique(...);

Keeps an internal cache of all discovered subgraphs and
only invokes the user_callback for unique
subgraphs. Returning false
from user_callback will terminate the search as
expected.

mcgregor_common_subgraphs_maximum(...);

Explores the entire search space and invokes
the user_callback afterward with each of the largest
discovered subgraphs. Returning false from
the user_callback will not terminate the search
because it is invoked after the search has been completed.

mcgregor_common_subgraphs_maximum_unique(...);

Explores the entire search space and invokes
the user_callback afterward with each of the largest,
unique discovered subgraphs. Returning false from
the user_callback will not terminate the search
because it is invoked after the search has been completed.

Utility Functions/Structs

Returns a binary predicate function object
(property_map_equivalent<PropertyMapFirst,
PropertyMapSecond>) that compares vertices or edges
between graphs using property maps. If, for
example, vertex1 and vertex2 are the two
parameters given when the function object is invoked,
the operator() is effectively:
return (get(m_property_map1, vertex1) == get(m_property_map2, vertex2));

Creates a Filtered Graph from
a subgraph, represented here as a vertex membership map (vertex
-> bool where a value of true means that the vertex is
present in the subgraph). All edges between the included
vertices are preserved. See the example section for details.

Complexity

The time complexity for searching the entire space is O(V1 *
V2) where V1 is number of vertices in the first graph and
V2 is the number of vertices in the second graph.

Examples

Before calling any of the mcregor_common_subgraphs
algorithms, you must create a function object to act as a callback:

Example 1

If all the vertices and edges in your graph are identical, you
can start enumerating subgraphs immediately:

// Print out all connected common subgraphs between graph1 and graph2.
// All vertices and edges are assumed to be equivalent and both graph1 and graph2
// have implicit vertex index properties.
mcgregor_common_subgraphs(graph1, graph2, true, my_callback);

Example 2

If the vertices and edges of your graphs can be differentiated
with property maps, you can use
the make_property_map_equivalent function to create a
binary predicate for vertex or edge equivalence: