【发布时间】:2014-03-19 21:01:05
【问题描述】:
numpy 中计算 dijkstra 算法使用的跳跃次数的最快方法是什么?我有一个 10000x10000 元素连接矩阵并使用 scipy.sparse.csgraph.dijkstra 来计算填充距离矩阵和前驱矩阵。我的幼稚解决方案如下:
import numpy as np
from numpy.random import rand
from scipy.sparse.csgraph import dijkstra
def dijkway(dijkpredmat, i, j):
"""calculate the path between two nodes in a dijkstra matrix"""
wayarr = []
while (i != j) & (j >= 0):
wayarr.append(j)
j = dijkpredmat[i,j]
return np.array(wayarr)
def jumpvec(pmat,node):
"""calculate number of jumps from one node to all others"""
jumps = np.zeros(len(pmat))
jumps[node] = -999
while 1:
try:
rvec = np.nonzero(jumps==0)[0]
r = rvec.min()
dway = dijkway(pmat, node, r)
jumps[dway] = np.arange(len(dway),0,-1)
except ValueError:
break
return jumps
#Create a matrix
mat = (rand(500,500)*20)
mat[(rand(50000)*500).astype(int), (rand(50000)*500).astype(int)] = np.nan
dmat,pmat = dijkstra(mat,return_predecessors=True)
timeit jumpvec(pmat,300)
In [25]: 10 loops, best of 3: 51.5 ms per loop
~50msek/node 是可以的,但是将距离矩阵扩展到 10000 个节点会将时间增加到~2sek/node。 jumpvec 也必须执行 10000 次......
【问题讨论】:
-
对于那些想在不查看您的 python 代码的情况下回答的人,通过计算 Dijkstra 算法使用的“跳跃次数”可能有助于解释您的意思。
-
当然! Dijkstra 算法通过其他节点使用中间步骤来计算两个节点之间的最短距离。例如:A 和 C 之间的距离是 5,A 和 B 之间的距离是 2,B 和 C 之间的距离是 2。那么走 A->B->C 而不是直接走 A->C 会更短。第一种情况下的跳跃次数为 2,第二种情况下为 1。
-
@brorfred:我可能遗漏了一些东西,但似乎跳跃次数可以简单地解决为具有未加权图的 dijkstra 的一个特例,顺便说一下,可以用广度优先搜索(无需像 dijkstra 那样重新访问旧节点)。
标签: python algorithm numpy graph-theory dijkstra