Ask Your Question
2

Twin reduction in Graph

asked 2024-07-08 21:00:35 +0100

Erdos2 gravatar image

Two vertices in a graph are called twins if they have the same neighbourhood. Twin reduction is the process in which twin vertices are merged, until no twin vertices remain. Note that this process is independent of the order in which pair of twins are chosen and merged.

As far as I know, there is no inbuilt function in sage, which returns a twin reduced graph from a given graph G. Can anyone help me in defining one such function?

edit retag flag offensive close merge delete

3 Answers

Sort by » oldest newest most voted
3

answered 2024-07-14 16:21:16 +0100

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.

edit flag offensive delete link more
1

answered 2024-07-14 16:50:27 +0100

vdelecroix gravatar image

updated 2024-07-15 20:45:00 +0100

A slightly 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)`.
    """
    twins = set()
    to_delete = []
    for v in G:
        neigh = frozenset(G.neighbor_iterator(v))
        if neigh in twins:
            to_delete.append(v)
        else:
            twins.add(neigh)

    H = G.copy(immutable=False)
    H.delete_vertices(to_delete)
    return H
edit flag offensive delete link more

Comments

Note that it is easy to modify my function to modify G in place.

vdelecroix gravatar imagevdelecroix ( 2024-07-14 16:52:55 +0100 )edit
1

answered 2024-07-09 13:33:26 +0100

FrédéricC gravatar image

Rough Tentative

sage: def remove_one(G):
....:     store = []
....:     newG = copy(G)
....:     for v in newG:
....:         neigh = set(newG.neighbors(v))
....:         if neigh in store:
....:             newG.delete_vertex(v)
....:             return newG
....:         store.append(neigh)
....:     return G
....:     
sage: G=graphs.CycleGraph(4)
sage: remove_one(G)
Cycle graph: Graph on 3 vertices
sage: remove_one(_)
Cycle graph: Graph on 2 vertices
sage: remove_one(_)
Cycle graph: Graph on 2 vertices
sage: remove_one(_)
edit flag offensive delete link more

Comments

should it return G or newG finally?

Erdos2 gravatar imageErdos2 ( 2024-07-14 08:45:01 +0100 )edit

It returns G when it fails to simplify anything. You need to iterate that several times until there is no change.

FrédéricC gravatar imageFrédéricC ( 2024-07-14 09:04:16 +0100 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2024-07-08 20:40:40 +0100

Seen: 238 times

Last updated: Jul 15