PPR*_*PPR 5 python shortest-path networkx python-3.x weighted-graph
我正在与 networkx 一起计算k- shortest simple paths。nx.shortest_simple_paths(G, source, target, weight=weight)
以成本递增的顺序返回路径列表(考虑权重的累积路径长度)。
我有兴趣获得这些路径的成本。networkX 中是否有任何简单的函数来获得它?
这个问题类似于这个问题:Networkx 中是否已经实现了算法来返回路径长度和路径?.
我相信该帖子中发布的答案是错误的。从如何添加用于计算图中边权重的自定义函数?我做了以下解决方案(见下文)。
这是正确的方法吗?
networkx 库中有什么简单可用的东西吗?
我的目标是找到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("--------------")
Run Code Online (Sandbox Code Playgroud)
这将输出:
['a', 'b', 'c', 'd'] 4
['a', 'b', 'c', 'd'] 12
--------------
['a', 'c', 'd'] 3
['a', 'c', 'd'] 16
--------------
Run Code Online (Sandbox Code Playgroud)
我很欣赏@sentence 和@nbeuchat 的解决方案。但是,如果您有一个大图,@sentence 的解决方案会花费很多时间,并且 nbeuchat 的解决方案不提供 k-最短路径。我合并他们的解决方案,以提出更快的 k-最短简单路径和路径长度。
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"))
Run Code Online (Sandbox Code Playgroud)
显然,k_shortest_path
NetworkX 中尚未实现某个功能,尽管该需求并不新鲜,并且您可以在网络上找到一些实现Yen 算法的尝试。
您的问题的(非常)粗略的解决方案可能是:
def k_shortest_path(G, source, target, k):
def path_cost(G, path):
return sum([G[path[i]][path[i+1]]['weight'] for i in range(len(path)-1)])
return sorted([(path_cost(G,p), p) for p in nx.shortest_simple_paths(G, source,target,weight='weight') if len(p)==k])[0]
Run Code Online (Sandbox Code Playgroud)
对于这种图:
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)
Run Code Online (Sandbox Code Playgroud)
呼叫:
k_shortest_path(G, 'a', 'f', 4)
Run Code Online (Sandbox Code Playgroud)
返回:
(12, ['a', 'b', 'd', 'f'])
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
3446 次 |
最近记录: |