使用斐波那契最小堆的dijkstra的时间复杂度

时间:2019-05-14 20:15:08

标签: python time-complexity

我一直在尝试使用Fibonacci min-heap优化我的Dijkstra算法,根据此 1 [article]该文章应采用$ O(M + N log(N))的复杂度$其中:

  • M是边数
  • N是顶点数

我已经计算了总体复杂度,但是不确定是否正确,我希望得到一些建议:

首先,我们要尽量避免使用“声明和赋值”,因为它们都是不变的基本运算,占用$ O(1)$,对我的复杂度没有贡献,因为n $ \ to $ $ \ infty $。

第一个for循环,其复杂度为$ O(N)$。

采用$ O(log(N))$的headpop方法假定我们在二进制堆中查找权重最小的节点。

这是我不确定的地方。因此,我们从源中获取权重较小的节点,然后更新邻居的标签,这意味着我们转到邻接列表(在本例中为Dictionary)并检查集合$ \ 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

1 个答案:

答案 0 :(得分:1)

Dijkstra的算法是:

O(|E| |decrease-key(Q)| + |V| |extract-min(Q)|)

斐波那契堆:

O(|E| + |V| log |V|)

二进制堆:

O((|E| + |V|) log |V|)

E是:

|E| = O(|V|^2)

Q是: 最小优先级队列按其自身当前的距离估计值对顶点进行排序。

初始化堆:

from heapq import *
from random import randint

f = FibonacciHeap()
h = []
n = 100
for i in xrange(0, n):
    r = randint(1, 1000)
    f.insert(r)
    heappush(h, r)

打印运行时间代码:

import time
# test fib heap running time 
start_time = time.time()
while f.total_nodes > 0:
    m = f.extract_min()
print "%s seconds run time for fib heap" % (time.time() - start_time)

# test heapq running time 
start_time = time.time()
while h:
    m = heappop(h)
print "%s seconds run time for heapq" % (time.time() - start_time)