6

I have a NetworkX graph. I would like to know how to do edge contraction between multiple nodes.

For example, if I wanted to contract X, Y and Z:

         _ node A _
       _/    |     \_
node X --- node Y --- node Z

Would become

           node A 
             |     
           node XYZ (or whatever X/Y/Z)

Graph creation is not the problem. It works. I want to reduce the graph by merging nodes that have the same "meanings": nodes that I call "end lvl" (node name length is equal to 7) and that are linked together.

I have found the condensation function in NetworkX so I tried to use it:

# edge contraction for same nodes
# for each node, get the links to other nodes "end lvl"
# if there is such a link, it means that these node are
# the sames
#
# copy graph
I = G
for n,d in G.nodes(data=True):
    if n in I.nodes():
        if len(n) == 7:
            # list of nodes adjacent to n : filter only "end lvl" nodes
            neighbors = [ node for node in I.neighbors(n) if len(node) == 7 ]
            nodes_to_merges = neighbors.append(n)
            I = nx.condensation(I,scc=nodes_to_merges)

The thing I got when I convert to JSON is:

{"directed": true, "graph": [], "nodes": [{"id": 0}], "links": [], "multigraph": false}

There is a problem as you can see...

Reference to functions are here.

mdml
  • 22,442
  • 8
  • 58
  • 66
qdelettre
  • 1,873
  • 5
  • 25
  • 36
  • One solution would be to do it manually using a dict representation (to_dict_of_dicts). – keyser Mar 26 '13 at 15:30
  • Ok, i am not familiar with graphs but i should improve my question, as @zodiac asked me. Here it comes. – qdelettre Mar 26 '13 at 15:40
  • what do the nodes(), neighbours() and condensation() functions do? what is nx? – xuanji Mar 26 '13 at 15:48
  • nx is python networkx : http://networkx.github.com. Nodes() return the nodes for a graph. Neighbours(x) return the neighbors node of a node x. Condensation of G is the graph with each of the strongly connected components or nodes contracted into a single node. – qdelettre Mar 26 '13 at 15:54
  • you whole graph seems to be strongly connected to me, hence the output only has one node. don't use it to contract arbitrary nodes – xuanji Mar 27 '13 at 09:03

2 Answers2

4

How about:

add_node(XYZ)
add_edge(XYZ, A)
for edge incident on (X, Y, Z):
    v = nodes in edge not in (X, Y, Z, A)
    if v:
       remove_edge(edge)
       add_edge(v, XYZ)
for node in (X, Y, Z):
    remove_node(node)
user650654
  • 5,630
  • 3
  • 41
  • 44
0

Instead of trying to use nx.condensation (which is meant for contracting strongly connected components, not groups of nodes in general) use these functions:

https://networkx.org/documentation/stable/reference/classes/graph.html#adding-and-removing-nodes-and-edges

to remove all but one of the collapsed nodes and rewire their nodes.

Alex Shroyer
  • 3,499
  • 2
  • 28
  • 54
xuanji
  • 5,007
  • 2
  • 26
  • 35