【发布时间】:2019-05-14 20:15:07
【问题描述】:
我一直在尝试使用斐波那契最小堆优化我的 Dijkstra 算法,根据这个 1[article] 应该采取复杂性 $O(M+Nlog(N))$ 其中:
- M 是边数
- N 是顶点数
我已经计算了总体复杂性,但我不确定它是否正确,我很想得到一些建议:
首先,我们有“声明和分配”,我会尽量避免,因为它们都是不变的基本操作,需要 $O(1)$ 并且对我的复杂性没有贡献 n $\to$ $\infty$。
第一个复杂度为 $O(N)$ 的 for 循环。
采用 $O(log(N))$ 的 headpop 方法假设我们在二叉堆中查找权重最小的节点。
这是我不确定的地方。所以我们从源中取出权重小的节点,然后更新邻居的标签,这意味着我们进入邻接列表(在本例中是字典)并检查集合中所有可能的边 $\delta^+(v) $,即从 v 到包含已访问节点的集合 $\S$ 之外的另一个顶点 u 的所有节点。因此,完整图的总体复杂度为 $O(n-1)$。
考虑到所有这些,我最终得到: $O(N\cdot(log(N) + M))$ $\equiv$ $O(N\cdot(log(N) + N - 1)) $ $\equiv$ $O(N \cdot log(N) + N^2)$ $\equiv$ $O(N^2)$ 对于较大的 N 值。
这不是我想要的解决方案的预期输出,因此我很高兴听到您的建议。
def dijkstra2(successors, s):
S = []; S.append(s)
n = len(successors)
L = dict(); L[s] = 0
P = dict(); P[s] = '-'
# Iterate through the V/{s}-nodes and set L[j] to infinity and P[j] to s.
for o in range(0, n):
if o != s:
L[o] = numpy.inf
P[o] = s
# Visited vector.
visited = [False] * n;
# Heapq
queue = [(0, s)];
while queue:
par_len, v = heappop(queue);
# v is unvisited
if visited[v] is False:
visited[v] = True
for w, edge_len in successors[v].items():
# Check if the child is unvisited and compute the distance.
if visited[w] is False and edge_len + par_len < L[w] :
heappush(queue, (edge_len + par_len, w))
L[w] = edge_len + par_len
P[w] = v
return L, P
【问题讨论】: