计算图中的许多最短路径

Posted

技术标签:

【中文标题】计算图中的许多最短路径【英文标题】:Computing many shortest paths in graph 【发布时间】:2018-05-15 00:17:30 【问题描述】:

我有一个大型(加权、有向)图(>100,000 个节点),我想在该图中计算大量随机最短路径。所以我想随机选择两个节点(比如说k次)并计算最短路径。一种方法是使用 networkx 或 igraph 模块并执行 for 循环,如

pairs=np.random.choice(np.arange(0,len(graph.nodes)), [k,2]) 
for pair in pairs:
    graph.get_shortest_paths(pair[0],pair[1], weights='weight')

这可行,但需要很长时间。特别是,与计算特定源节点的所有路径相比。本质上,在每次迭代中,流程都会再次加载图表并从头开始流程。那么有没有一种方法可以从将图形结构加载到内存中而不是在不计算所有最短路径的情况下在每次迭代中重做这一点中受益(考虑到这些路径将是 n*(n-1) 路径,这将花费太长时间)。

换个说法,我可以有效地计算所有最短路径的随机子集吗?

【问题讨论】:

你看过Floyd-Warshall算法吗?它计算所有节点到所有其他节点的最短距离。 感谢您的回复!是的,据我了解,igraph 模块会自动将 Floyd-Warshall 应用到一定数量的节点之上。但正如我所说,这仍然需要很长时间,所以就我的目的而言,只需计算所有最短路径的较小子集就足够了。 抱歉,刚刚检查过。至少根据 R 包的文档,igraph 模块使用 Johnson-Dijkstra。根据***,Johnson-Dijkstra 是 O(EV + V2 log V),而 Floyd-Warshall 是 O(V3)。但是忽略时间复杂度的差异,它只需要很长时间。在某种程度上,我的(天真的)问题是,是否可以从这些高效算法中受益,但仅适用于所有可能节点对的子集。 【参考方案1】:

AFAIK,这些操作彼此独立,因此可以并行运行它们(伪代码):

import dask

@dask.delayed
def short_path(graph, pair):
    return graph.get_shortest_paths(pair[0],pair[1], weights='weight')

pairs=np.random.choice(np.arange(0,len(graph.nodes)), [k,2]) 
results = dask.compute(*[short_path(pair) for pair in pairs])

【讨论】:

以上是关于计算图中的许多最短路径的主要内容,如果未能解决你的问题,请参考以下文章

数据结构图之三(最短路径--迪杰斯特拉算法——转载自i=i++

数据结构8——最短路径

[C语言算法]关于计算图中最短路径时的带负权情况

图-最短路径-Dijkstra及其变种

软考 系统架构设计师数学与经济管理① 图论应用

软考 系统架构设计师数学与经济管理① 图论应用