Why does Dijkstra's algorithm use decrease-key?

后端 未结 3 804
花落未央
花落未央 2020-12-07 07:54

Dijkstra\'s algorithm was taught to me was as follows

while pqueue is not empty:
    distance, node = pqueue.delete_min()
    if node has been visited:
              


        
3条回答
  •  悲哀的现实
    2020-12-07 08:22

    There are two ways to implement Dijkstra: one uses a heap that supports decrease-key and another a heap that doesn't support that.

    They are both valid in general, but the latter is usually preferred. In the following I'll use 'm' to denote the number of edges and 'n' to denote the number of vertices of our graph:

    If you want the best possible worst-case complexity, you would go with a Fibonacci heap that supports decrease-key: you'll get a nice O(m + nlogn).

    If you care about the average case, you could use a Binary heap as well: you'll get O(m + nlog(m/n)logn). Proof is here, pages 99/100. If the graph is dense (m >> n), both this one and the previous tend to O(m).

    If you want to know what happens if you run them on real graphs, you could check this paper, as Mark Meketon suggested in his answer.

    What the experiments results will show is that a "simpler" heap will give the best results in most cases.

    In fact, among the implementations that use a decrease-key, Dijkstra performs better when using a simple Binary heap or a Pairing heap than when it uses a Fibonacci heap. This is because Fibonacci heaps involve larger constant factors and the actual number of decrease-key operations tends to be much smaller than what the worst case predicts.

    For similar reasons, a heap that doesn't have to support a decrease-key operation, has even less constant factors and actually performs best. Especially if the graph is sparse.

提交回复
热议问题