I am working with networkx to calculate the k-shortest simple paths. nx.shortest_simple_paths(G, source, target, weight=weight)
returns the list of paths in the increasing order of cost (cumulative path length considering weights).
I am interested in obtaining the cost of these paths. Is there any simple function in networkX to obtain this?
This question is similar to this question: Is there already implemented algorithm in Networkx to return paths lengths along with paths?.
I believe the posted answer in that post is wrong. From How to add custom function for calculating edges weights in a graph? I made the following solution (see below).
Is this the right approach?
Is there anything simple available in the networkx library?
My aim is to find the cost of k-shortest path.
G = nx.Graph() # or DiGraph, MultiGraph, MultiDiGraph, etc
G.add_edge('a', 'b', weight=2)
G.add_edge('b', 'c', weight=4)
G.add_edge('a', 'c', weight=10)
G.add_edge('c', 'd', weight=6)
G.size()
def path_length(G, nodes, weight):
w = 0
for ind,nd in enumerate(nodes[1:]):
prev = nodes[ind]
w += G[prev][nd][weight]
return w
for path in nx.shortest_simple_paths(G, 'a', 'd', weight='weight'):
print(path, len(path)) # wrong approach
print(path, path_length(G,path,'weight')) # correct solution
print("--------------")
This will output this:
['a', 'b', 'c', 'd'] 4
['a', 'b', 'c', 'd'] 12
--------------
['a', 'c', 'd'] 3
['a', 'c', 'd'] 16
--------------
I appreciate @sentence's and @nbeuchat's solution. However, if you have a large graph @sentence's solution takes so much time and nbeuchat's solution doesn't provide k-shortest paths. I merge their solutions to come up with much faster k-shortest simple paths with path length.
import networkx as nx
G = nx.Graph()
G.add_edge('a', 'b', weight=2)
G.add_edge('b', 'c', weight=4)
G.add_edge('a', 'c', weight=10)
G.add_edge('c', 'd', weight=6)
G.add_edge('b', 'd', weight=2)
G.add_edge('b', 'e', weight=5)
G.add_edge('e', 'f', weight=8)
G.add_edge('d', 'f', weight=8)
from itertools import islice
from networkx.classes.function import path_weight
def k_shortest_paths(G, source, target, k, weight=None):
return list(islice(nx.shortest_simple_paths(G, source, target, weight='weight'), k))
for path in k_shortest_paths(G, 'a','f', 3):
print(path, path_weight(G, path, weight="weight"))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With