1 | initial version |
A slightly improved solution.
def twin_reduced_graph(G):
r"""
Return a twin reduced graph.
Vertices `u` and `v` are twins if `N(u) == N(v)`.
This method merges twins until no twin vertices remain in `G`.
"""
H = G.copy(immutable=False)
while True:
# Identify twins
twins = {}
best = None
for v in H:
neigh = frozenset(H.neighbor_iterator(v))
if neigh in twins:
twins[neigh].append(v)
if best is None or len(best) < len(twins[neigh]):
best = twins[neigh]
else:
twins[neigh] = [v]
# Merge the largest set of twins
if best is None or len(best) == 1:
break
H.delete_vertices(best[1:])
return H
A better approach might be to use the modular decomposition of the graph, but it's not easy with the current implementation.