【问题标题】:Finding N shortest paths in a graph在图中找到 N 条最短路径
【发布时间】:2019-10-20 17:10:26
【问题描述】:

我需要找到两个节点之间的N 最短路径。 例如,以下代码创建三个节点和四个边,两条最短路径为(1, 3) and (1, 2, 3)

import networkx as nx

G = nx.MultiDiGraph()
G.add_edge(1, 2, **{'weight': 15, 'max': 3})
G.add_edge(1, 3, **{'weight': 30, 'max': 4})
G.add_edge(2, 3, **{'weight': 20, 'max': 3})
G.add_edge(2, 3, **{'weight': 20, 'max': 5})

NetworkX 中是否有方法可以找到它们?

我知道 nx.all_shortest_paths(rete,1, 3, weight='weight') 方法,但在这种情况下,该方法仅返回 最短路径 (1,3)。

谢谢!

【问题讨论】:

    标签: python networkx


    【解决方案1】:

    从文档看来,您可以使用shortest_simple_paths 从最短路径开始生成两个顶点之间的所有简单路径:

    https://networkx.github.io/documentation/stable/reference/algorithms/generated/networkx.algorithms.simple_paths.shortest_simple_paths.html#

    编辑:多图的答案

    这是获得您正在寻找的答案的非常粗略的解决方案。我认为它只适用于小图:

    G = nx.MultiDiGraph()
    G.add_edge(1, 2, **{'weight': 15, 'max': 3})
    G.add_edge(1, 3, **{'weight': 30, 'max': 4})
    G.add_edge(2, 3, **{'weight': 20, 'max': 3})
    G.add_edge(2, 3, **{'weight': 20, 'max': 5})
    
    # get all paths and convert them to tuples so that we can
    # deduplicate them
    paths = [tuple(p) for p in nx.all_simple_paths(G, 1, 3)]
    
    # sort the paths according to the number of nodes in the path
    print(sorted(set(paths), key=lambda x:len(x)))
    

    编辑 2:加权多重图的答案

    这个有点复杂,你需要自己编写“路径分数”函数并传递给分拣机。

    G = nx.MultiDiGraph()
    G.add_edge(1, 2, **{'weight': 15, 'max': 3})
    G.add_edge(1, 3, **{'weight': 30, 'max': 4})
    G.add_edge(2, 3, **{'weight': 20, 'max': 3})
    G.add_edge(2, 3, **{'weight': 20, 'max': 5})
    
    
    def get_edge_weight(u, v):
        """Return the minimum weight of all edges between nodes u and v."""
        return min([e['weight'] for e in G.get_edge_data(u, v).values()])
    
    
    def weighted_path_score(path):
        """Sum of edge weights in path."""
        edges = zip(path, path[1:])
        return sum(get_edge_weight(u, v) for u, v in edges)
    
    
    paths = [tuple(p) for p in nx.all_simple_paths(G, 1, 3)]
    
    # sort using the weighted path score
    print(sorted(set(paths), key=weighted_path_score))
    

    您可以使用边权重并检查返回路径的顺序是否符合它(例如,将高权重设置为边 1-3 将导致路径 (1,2,3) 首先列出)。

    【讨论】:

    • 谢谢你,但这提高了NetworkXNotImplemented: not implemented for multigraph type
    • 您也可以使用all_simple_paths,它将返回所有路径,然后使用您自己的逻辑对它们进行排序。请注意,由于它是一个多重图,因此您将在结果中两次获得路径 (1, 2, 3)
    • 最后一篇:如何考虑weights
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-25
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-31
    相关资源
    最近更新 更多