2

Is there any faster, nicer way of building a Networkx tree. Currently, my code is

for numb in range(0,len(previous)):
    nodos = list(chunks(current,3))
        for i in range(0,3):
            G.add_edge(previous[numb],nodos[numb][i])

This works in the following way: 1. The tree has 3 branches (or edges). I have two arrays:

previous = [x,y,z] #These nodes have already been added to the graph
current = [xx,xy,xz, xy,yy,yz, xz,yz,zz] #This nodes need to be added.

Ideally, I should do the following:

1. Start with x in previous:
1.1 Pick the first 3 nodes in current (i.e. xx,xy,xz)
1.1.1 Add the nodes-edges: x->xx, x->xy, x->xz

So far my codes does:

1. Start with x in previous
2. Partition current into chunks of 3 items: [[xx,xy,xz], [xy,yy,yz], [xz,yz,zz]]
3. Loop through all the nodes in these chunks:
4. Add x->xx, loop again, add x->xy... etc.

My implementation is extremely inefficient. How would you do this efficiently? Thank you

1 Answer 1

3

You could use the helper function from https://github.com/networkx/networkx/blob/master/networkx/generators/classic.py#L50

def _tree_edges(n,r):
    # helper function for trees
    # yields edges in rooted tree at 0 with n nodes and branching ratio r
    nodes=iter(range(n))
    parents=[next(nodes)] # stack of max length r
    while parents:
        source=parents.pop(0)
        for i in range(r):
            try:
                target=next(nodes)
                parents.append(target)
                yield source,target
            except StopIteration:
                break

print list(_tree_edges(13,3))
#[(0, 1), (0, 2), (0, 3), (1, 4), (1, 5), (1, 6), (2, 7), (2, 8), (2, 9), (3, 10), (3, 11), (3, 12)]
import networkx as nx
G = nx.Graph(_tree_edges(13,3))

If you want nodes other than integers you can either relabel or specify them on input like this

def _tree_edges(nodes,r):
    # helper function for trees
    # yields edges in rooted tree with given nodes and branching ratio r
    nodes=iter(nodes)
    parents=[next(nodes)] # stack of max length r
    while parents:
        source=parents.pop(0)
        for i in range(r):
            try:
                target=next(nodes)
                parents.append(target)
                yield source,target
            except StopIteration:
                break

nodes = list('abcdefghijklm')
print list(_tree_edges(nodes,3))
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you! I didnt know this existed. But I still have a problem, this works great if n,r are numbers, but in my case they are letters. so [(x,xx),(x,xy),(x,xz),(y,xy) .. and so on]. But I cant use this function if r is not a number. Any ideas of how to get around this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.