【问题标题】:Does networkx has a function to calculate the length of the path considering weights?networkx 是否具有计算权重路径长度的功能?
【发布时间】:2019-06-18 21:09:43
【问题描述】:

我正在使用 networkx 来计算 k 最短简单路径nx.shortest_simple_paths(G, source, target, weight=weight) 按成本升序返回路径列表(考虑权重的累积路径长度)。

我有兴趣获得这些路径的成本。 networkX中是否有任何简单的函数来获取这个?

本题与本题类似:Is there already implemented algorithm in Networkx to return paths lengths along with paths?

我认为该帖子中发布的答案是错误的。从How to add custom function for calculating edges weights in a graph? 我提出了以下解决方案(见下文)。

这是正确的方法吗?

networkx 库中有什么简单的可用的吗?

我的目标是找出k-最短路径的成本。

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("--------------")

这将输出:

['a', 'b', 'c', 'd'] 4
['a', 'b', 'c', 'd'] 12
--------------
['a', 'c', 'd'] 3
['a', 'c', 'd'] 16
--------------

【问题讨论】:

    标签: python python-3.x networkx shortest-path weighted-graph


    【解决方案1】:

    我很欣赏@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"))
    

    【讨论】:

      【解决方案2】:

      显然,k_shortest_path 功能尚未在 NetworkX 中实现,尽管 demand 不是新的,您可以在网络上找到一些实现 Yen's algorithm 的尝试。

      您的问题的一个(非常)粗略的解决方案可能是:

      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]
      

      对于这种图表:

      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)
      

      调用:

      k_shortest_path(G, 'a', 'f', 4)
      

      返回:

      (12, ['a', 'b', 'd', 'f'])
      

      【讨论】:

        【解决方案3】:

        您可以使用path_weight(G, path, weight="weight"),如下:

        from networkx.algorithms.shortest_paths.generic import shortest_path
        from networkx.classes.function import path_weight
        
        path = shortest_path(G, source=source, target=target, weight="weight")
        path_length = path_weight(G, path, weight="weight")
        

        【讨论】:

          猜你喜欢
          • 2019-05-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-06-18
          • 2014-08-26
          • 2017-09-28
          相关资源
          最近更新 更多