Dat Nguyen
Dat Nguyen

Reputation: 11

Length of All Paths In A List Using NetworkX

I need some help for a Graph. I use the module NetworkX, but it isn't so important knowing everything about it. I'm a beginner in Python. I started creating a normal Graph:

import networkx as nx

G = nx.Graph()

G.add_edge("Node1","Node2",length=140,sf=4)
G.add_edge("Node2","Node3",length=170,sf=3)
G.add_edge("Node1","Node4",length=300,sf=1)
G.add_edge("Node4","Node3",length=230,sf=10)

x = input('First Node: ')
y = input('Second Node: ')

paths = sorted(nx.all_simple_paths(G,x,y))

print(paths)

I added 2 attributes: length and sf (i will need it later). I ran this programm and get with Node1 and Node3 this:

[['Node1', 'Node2', 'Node3'], ['Node1', 'Node4', 'Node3']]

How can I calculate the length for the paths? And than I need to multiply the length with the attribute "sf". I simplified the problem, because later I have hundreds of nodes, so it will be more difficult.

I started thinking about a for-function, but I just get errors.

Upvotes: 0

Views: 2712

Answers (2)

Subhrasankha Dey
Subhrasankha Dey

Reputation: 56

You can use the path_weight function to calculate the individual path length of the list "paths":

Let length_of_All_Paths be a list of lengths of each list within paths:

length_of_All_Paths = [nx.path_weight(G, temp_path, weight='length') for temp_path in paths]

Upvotes: 0

unutbu
unutbu

Reputation: 880807

You could use a for-loop:

import sys
import networkx as nx

G = nx.Graph()

G.add_edge("Node1", "Node2", length=140, sf=4)
G.add_edge("Node2", "Node3", length=170, sf=3)
G.add_edge("Node1", "Node4", length=300, sf=1)
G.add_edge("Node4", "Node3", length=230, sf=10)

x, y = sys.argv[-2:]
paths = sorted(nx.all_simple_paths(G, x, y))

for path in paths:
    total_length = 0
    for i in range(len(path)-1):
        source, target = path[i], path[i+1]
        edge = G[source][target]
        length = edge['length']*edge['sf']
        total_length += length
    print('{}: {}'.format(path, total_length))

or, more tersely, you could replace the inner for-loop with a generator expression:

import operator
length_sf = operator.itemgetter('length', 'sf')
for path in paths:
    total_length = sum(operator.mul(*length_sf(G[path[i]][path[i+1]])) 
                       for i in range(len(path)-1)) 
    print('{}: {}'.format(path, total_length))

Both options yield (for x, y = 'Node1', 'Node3')

['Node1', 'Node2', 'Node3']: 1070
['Node1', 'Node4', 'Node3']: 2600

Upvotes: 3

Related Questions