Python Dijkstra k最短路径

时间:2012-11-22 19:33:13

标签: python algorithm graph graph-algorithm dijkstra

我正在尝试制作一个小型公共交通路线应用程序。

我的数据以下列结构表示:

graph = {'A': {'B':3, 'C':5},
     'B': {'C':2, 'D':2},
     'C': {'D':1},
     'D': {'C':3},
     'E': {'F':8},
     'F': {'C':2}}

其中:

  1. 图表dict键是一个节点
  2. subdict键是2个节点之间的边缘
  3. subict value是边权重
  4. 我使用的是此处描述的find_shortest_path算法https://www.python.org/doc/essays/graphs/但由于递归而且它不支持权重,因此速度相当慢。

    所以我转到了Davide Epstein所描述的算法http://code.activestate.com/recipes/119466-dijkstras-algorithm-for-shortest-paths/(在使用heapq的评论中可以找到更好的实现)

    效果很好,速度非常快,但我只获得最佳路线,而不是所有可能路线的列表。这就是我陷入困境的地方。

    有人可以帮助我,或者至少给出指示?我在图最短路径算法方面不是很好。

    提前致谢!

3 个答案:

答案 0 :(得分:8)

毫无疑问,图表中会有大量的最短路径。因此很难在满足时间复杂度的情况下生成所有最短路径。但我可以给你一个简单的方法,可以获得你想要的最短路径。

算法

  1. 从起点运行Dijkstra算法,得到disS [i]列表(最短距离 在起点和点之间i)。然后从终点运行Dijkstra算法,得到disT [i]列表(终点和点i之间的最短距离)
  2. 制作新图表:对于原始图表中的边缘,如果 disS [a] + disT [b] + w(a,b)== disS [终点],我们在新图中添加边。显然,新图是DAG(有向无环图),并且具有接收器(起始点)和目标(终点)。从接收器到目标的任何路径都是原始图形中的最短路径。
  3. 您可以在新图表中运行DFS。保存路径信息 递归和回溯,无论何时达到目标,保存 信息将是最短路径。当算法结束都取决于你。
  4. 伪代码:

    def find_one_shortest_path(graph, now, target, path_info):
        if now == target:
            print path_info
            return
        for each neighbor_point of graph[now]:
            path_info.append(neighbor_point) 
            find_one_shortest_path(graph, neighbor_point, target, path_info) #recursion
            path_info.pop(-1) #backtracking
    
    def all_shortest_paths(graph, starting_point, ending_point):
        disS = [] # shortest path from S
        disT = [] # shortest path from T
        new_graph = []
        disS = Dijkstra(graph, starting_point)
        disT = Dijkstra(graph, endinng_point)
        for each edge<a, b> in graph:
            if disS[a] + w<a, b> + disT[b] == disS[ending_point]:
                new_graph.add(<a, b>)
        find_one_shortest_path(new_graph, starting_point, ending_point, []) 
    

答案 1 :(得分:4)

Networkx具有执行此操作的功能all_shortest_paths

它返回所有最短路径的生成器。

答案 2 :(得分:0)

我在运输网络分析中遇到过类似的问题。我使用了优秀的python模块NetworkX。它具有在两个节点之间生成所有简单路径的功能。这是链接:

http://networkx.lanl.gov/reference/generated/networkx.algorithms.simple_paths.all_simple_paths.html