igraph,另一个 Python 图形模块可以计算给定节点对之间的所有 最短 路径。计算所有路径没有意义,因为您有无数这样的路径。
计算从顶点 0 开始的所有最短路径的示例:
>>> from igraph import Graph
>>> g = Graph.Lattice([10, 10], circular=False)
>>> g.get_all_shortest_paths(0)
[...a list of 3669 shortest paths starting from vertex 0...]
如果您有 igraph 0.6 或更高版本(这是撰写本文时的开发版本),您也可以将 get_all_shortest_paths 的结果限制为给定的结束顶点:
>>> g.get_all_shortest_paths(0, 15)
[[0, 1, 2, 3, 4, 14, 15],
[0, 1, 2, 12, 13, 14, 15],
[0, 10, 11, 12, 13, 14, 15],
[0, 1, 11, 12, 13, 14, 15],
[0, 1, 2, 3, 13, 14, 15],
[0, 1, 2, 3, 4, 5, 15]]
当然要小心;例如,假设您有一个 100 x 100 的网格图(可以通过 igraph 中的Graph.Lattice([100, 100], circular=False) 轻松生成)。从左上角节点到右下角节点的最短路径的数量等于从 200 个元素中选择 100 个元素的可能性的数量(证明:最短路径的长度有 200 条边,其中 100 条将“水平”在网格中,其中 100 个将“垂直”移动)。这可能不适合您的记忆,因此即使计算这两个节点之间的所有 最短 路径在这里也不可行。
如果你真的需要两个节点之间的所有路径,你可以使用igraph重写你提到的网页上给出的函数,这可能会比纯Python解决方案更快,因为igraph的核心是用C实现的:
def find_all_paths(graph, start, end, path=[]):
path = path + [start]
if start == end:
return [path]
paths = []
for node in set(graph.neighbors(start)) - set(path):
paths.extend(find_all_paths(graph, node, end, path))
return paths
可以通过首先将图形转换为邻接表表示来对其进行更多优化,因为它可以避免重复调用graph.neighbors:
def find_all_paths(graph, start, end):
def find_all_paths_aux(adjlist, start, end, path):
path = path + [start]
if start == end:
return [path]
paths = []
for node in adjlist[start] - set(path):
paths.extend(find_all_paths_aux(adjlist, node, end, path))
return paths
adjlist = [set(graph.neighbors(node)) for node in xrange(graph.vcount())]
return find_all_paths_aux(adjlist, start, end, [])
编辑:修复了第一个示例以在 igraph 0.5.3 中工作,而不仅仅是在 igraph 0.6 中。