For example, these two graphs is considered to be a perfect partial match:
0 - 1
1 - 2
2 - 3
3 - 0
AND
0 - 1
1 - 2
This is the subgraph isomorphism problem: http://en.wikipedia.org/wiki/Subgraph_isomorphism_problem
There is one algorithm mentioned in the article due to Ullmann.
Ullmann's algorithm is an extension of a depth-first search. A depth-first search would work like this:
def search(graph,subgraph,assignments):
i=len(assignments)
# Make sure that every edge between assigned vertices in the subgraph is also an
# edge in the graph.
for edge in subgraph.edges:
if edge.first
For the basic algorithm, possible_assignments[i] = range(0,graph.n_vertices)
. That is, all the vertices are a possibility.
Ullmann extends this basic algorithm by narrowing the possibilities:
def update_possible_assignments(graph,subgraph,possible_assignments):
any_changes=True
while any_changes:
any_changes = False
for i in range(0,len(subgraph.n_vertices)):
for j in possible_assignments[i]:
for x in subgraph.adjacencies(i):
match=False
for y in range(0,len(graph.n_vertices)):
if y in possible_assignments[x] and graph.has_edge(j,y):
match=True
if not match:
possible_assignments[i].remove(j)
any_changes = True
The idea is that if node i of the subgraph could possibly match node j of the graph, then for every node x that is adjacent to node i in the subgraph, it has to be possible to find a node y that is adjacent to node j in the graph. This process helps more than might first be obvious, because each time we eliminate a possible assignment, this may cause other possible assignments to be eliminated, since they are interdependent.
The final algorithm is then:
def search(graph,subgraph,assignments,possible_assignments):
update_possible_assignments(graph,subgraph,possible_assignments)
i=len(assignments)
# Make sure that every edge between assigned vertices in the subgraph is also an
# edge in the graph.
for edge in subgraph.edges:
if edge.first