# Traversing level order for the graph in networkx

## Question:

I am trying to convert a `DiGraph` into n-ary tree and displaying the nodes in level order or BFS. My tree is similar to this, but much larger, for simplicity using this example:

``````G = networkx.DiGraph()
G.add_edges_from([('n', 'n1'), ('n', 'n2'), ('n', 'n3')])
G.add_edges_from([('n4', 'n41'), ('n1', 'n11'), ('n1', 'n12'), ('n1', 'n13')])
``````

Tree: borrowed the data from this question:

``````n---->n1--->n11
|     |--->n12
|     |--->n13
|           |--->n131
|--->n2
|     |---->n21
|     |---->n22
|            |--->n221
|--->n3
``````

I am using `networkx.DiGraph` for this purpose and created the graph successfully. Here is my code for creating a DiGraph:

``````G = nx.DiGraph()
roots = set()
for l in raw.splitlines():
if len(l):
target, prereq = regex1.split(l)
deps = tuple(regex2.split(prereq))
for d in deps:
if d:
``````

I am reading the all the data from a file with about 200 lines in the following format and trying to get a dependency tree. My graph is around 100 nodes with 600 edges.

``````AAA: BBB,CCC,DDD,
BBB:
DDD: EEE,FFF,GGG,KKK
GGG: AAA,BBB,III,LLL
....
...
..
.
``````

After looking into the networkx docs online, now I can achieve the the level order output doing a topological sort on the dependency tree, with the below code.

``````order =  nx.topological_sort(G)
print "topological sort"
print order
``````

output:

``````['n2', 'n3', 'n1', 'n21', 'n22', 'n11', 'n13', 'n12', 'n221', 'n131']
``````

The order seems correct, but since I need to process the jobs in a batch (which saves time) and not sequentially, I want the output in level ordered output batches or using BFS. What is the best way to achieve this ?
ex: level[0:n], ex:

``````0. ['n']
1. ['n2', 'n3', 'n1',]
2. ['n21', 'n22', 'n11',]
3. ['n13', 'n12', 'n221', 'n131']
``````

You could use the bfs_edges() function to get a list of nodes in a breadth-first-search order.

``````In [1]: import networkx

In [2]: G = networkx.DiGraph()

In [3]: G.add_edges_from([('n', 'n1'), ('n', 'n2'), ('n', 'n3')])

In [4]: G.add_edges_from([('n4', 'n41'), ('n1', 'n11'), ('n1', 'n12'), ('n1', 'n13')])

In [5]: G.add_edges_from([('n2', 'n21'), ('n2', 'n22')])

In [6]: G.add_edges_from([('n13', 'n131'), ('n22', 'n221')])

In [7]: list(networkx.bfs_edges(G,'n'))
Out[7]:
[('n', 'n2'),
('n', 'n3'),
('n', 'n1'),
('n2', 'n21'),
('n2', 'n22'),
('n1', 'n11'),
('n1', 'n13'),
('n1', 'n12'),
('n22', 'n221'),
('n13', 'n131')]

In [8]: [t for (s,t) in networkx.bfs_edges(G,'n')]
Out[8]: ['n2', 'n3', 'n1', 'n21', 'n22', 'n11', 'n13', 'n12', 'n221', 'n131']

In [9]: networkx.single_source_shortest_path_length(G,'n')
Out[9]:
{'n': 0,
'n1': 1,
'n11': 2,
'n12': 2,
'n13': 2,
'n131': 3,
'n2': 1,
'n21': 2,
'n22': 2,
'n221': 3,
'n3': 1}
``````

You can also use `bfs_layers` which is handy for processing all nodes at the same depth.

``````import networkx as nx

G = nx.DiGraph()

G.add_edges_from([("n", "n1"), ("n", "n2"), ("n", "n3")])
G.add_edges_from([("n4", "n41"), ("n1", "n11"), ("n1", "n12"), ("n1", "n13")])

for level in nx.bfs_layers(G, "n"):
print(level)
``````

Which outputs

``````['n']
['n1', 'n2', 'n3']
['n11', 'n12', 'n13', 'n21', 'n22']
['n131', 'n221']
``````
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.