Skip to content
Advertisement

Graph traversal with Networkx (Python)

I’m playing a bit with Networkx to manage a graph of dependencies. Let’s say I have this Graph which each letter represent a server

>>> G = nx.Graph()
>>> G.add_edge("A","B")
>>> G.add_edge("A","H")
>>> G.add_edge("H","C")
>>> G.add_edge("B","C")
>>> G.add_edge("B","D")

           A
         /   
       H       B
     /        /  
   C         C     D 

So here we can see that before starting A we need to start H and B and to start H we need to start C and then to start B wee need to start C and D

By fiddling a bit with Networkx I found that I can get that by doing a dfs traversal

print nx.dfs_successors(G,"A")
{A:[H,B], H:[C], B:[D] }

But I have a problem with that method. As you can see when there is two same letter in the tree, Networkx only chose to put one of them in the final structure (which is correct) But I need to have the complete structure How can I force Networkx to add in the structure B:[D,C] ??

I want to precise that by doing

>>> nx.dfs_successors(G,"B")
{'B': ['C', 'D']}

So everything is “Internally” correct, it’s just the dfs_successors that displays it not in the way I wish.

Thank you

Advertisement

Answer

Taking your code, your graph doesn’t come out as you’d expect. If you do:

import pylab as p
import networkx as nx

G = nx.Graph()
G.add_edge("A","B")
G.add_edge("A","H")
G.add_edge("H","C")
G.add_edge("B","C")
G.add_edge("B","D")

nx.draw(G)
p.show()

you will see your graph as: Graph

This is due to the logic of G.add_edge("A", "B"):

  1. If G has no node of id “A”, add it.
  2. If G has no node of id “B”, add it.
  3. Connect “A” to “B” with a new edge.

Thus, you only create five nodes, not six as in your picture.

Edit Networkx can take any hashable as value for a node, and in the graph it uses str(node) to label each circle. So we can simply define our own Node class (which you maybe want to call Server?) and give it the desired behavior.

import pylab as p
import networkx as nx


class Node(object):
    nodes = []

    def __init__(self, label):
        self._label = label

    def __str__(self):
        return self._label

nodes = [Node(l) for l in ["A","B","C","C","D","H"]]
edges = [(0,1),(0,5),(5,2),(1,3),(1,4)]

G = nx.Graph()
for i,j in edges:
    G.add_edge(nodes[i], nodes[j])

nx.draw(G)
p.show()

gives us New graph and so what you wanted.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement