戴克斯特拉算法

title: 算法描述.
content: 戴克斯特拉算法通过保留目前为止所找到的每个顶点formula_8从formula_4到formula_10的最短路径来工作的。初始时,原点formula_4的路径权重被赋为 0 (即原点的实际最短路径=0)。同时把所有其他顶点的路径长度设为无穷大,即表示我们不知道任何通向这些顶点的路径。当算法结束时,formula_12 中储存的便是从formula_4到formula_10的最短路径,或者如果路径不存在的话是无穷大。  松弛操作是戴克斯特拉算法的基础操作:如果存在一条从formula_6到formula_10的边,那么从formula_4到formula_10的一条新路径是将边formula_19添加到从formula_4到formula_6的路径尾部来拓展一条从formula_4到formula_10的路径。这条路径的长度是formula_24。如果这个值比目前已知的formula_12的值要小,那么可以用这个值来替代当前formula_12中的值。松弛边的操作一直执行到所有的formula_12都代表从formula_4到formula_10的最短路径的长度值。  算法维护两个顶点集合formula_2和formula_31。集合formula_2保留所有已知实际最短路径值的顶点,而集合formula_31则保留其他所有顶点。集合formula_2初始状态为空,而后每一步都有一个顶点从formula_31移动到formula_2。这个被选择的顶点是formula_31中拥有最小的formula_38值的顶点。当一个顶点formula_6从formula_31中转移到了formula_2中,算法对formula_6的每条外接边formula_43进行松弛。  《算法导论》中给出了以下伪代码:该伪代码计算并保留图formula_44中原点formula_4到每一顶点formula_10的最短距离formula_12。其中,函数formula_48将顶点集合formula_31中有最小formula_38值的顶点formula_6从formula_31中删除并返回formula_6。  如果我们只对在formula_4和formula_67之间寻找一条最短路径的话,我们可以在第5或第6行添加条件如果满足formula_68的话终止程序。  在肯尼·罗森所著的《离散数学及其应用》中给出了如下的另一份伪代码:
title: 时间复杂度.
content: 我们可以用大O符号将该算法的运行时间表示为边数formula_85和顶点数formula_86的函数。  对于任何基于顶点集formula_31的实现,算法的运行时间是formula_88,其中formula_89和formula_90分别表示完成键的降序排列时间和从formula_31中提取最小键值的时间。  对于没有任何优化的戴克斯特拉算法,实际上等价于每次遍历了整个图的所有结点来找到Q中满足条件的元素(即寻找最小的顶点是formula_92的),此外实际上还需要遍历所有的边一遍,因此算法的复杂度是formula_93。  对于边数少于formula_94的稀疏图来说,可以用邻接表来更有效的实现该算法。  可以使用一个二叉堆或者斐波纳契堆用作优先队列来寻找最小的顶点(formula_95)以优化算法。当用到二叉堆的时候,算法所需的时间为formula_96,斐波纳契堆能提高一些性能,让算法运行时间达到formula_97。然而,使用斐波纳契堆进行编程,有时会由于算法常数过大而导致速度没有显著提高。  下面是一些戴克斯特拉算法经典实现的复杂度比较:
title: 算法正确性证明.
content: 戴克斯特拉本人在他的论文中给出了一份简单的证明。  《算法导论》使用循环不变式(数学归纳法)给出了如下的一份证明:
title: 算法起源与历史.
content: 戴克斯特拉1956年在荷兰数学和计算机科学研究学会担任程序员时为了展示新型计算机ARMAC的功能曾思考过最短路径问题的解法。他的目标是让不去实际计算的人也能理解这个问题和解决的方法,于是他在发现了这个算法之后在ARMAC上做了简单实验。1959年,他正式将此算法发表在期刊上,该算法也成为了戴克斯特拉成名的基石之一。
title: 算法相关应用.
content: 链路状态路由协议中需要计算最短路时常常要用到该算法,开放最短路径优先算法是该算法在网络路由中的一个具体实现。  戴克斯特拉算法及其改进算法应用广泛,尤其是在寻路、交通、规划中。  如果有已知信息可用来估计某一点到目标点的距离,则可改用A*搜寻算法,以减小最短路径的搜索范围,戴克斯特拉算法本身也可以看作是A*搜索算法的一个特例。  戴克斯特拉算法本身采用了与Prim算法类似的贪心策略。快速行进算法与戴克斯特拉算法同样有相似之处。
title: 参考源程序.
content: 以下是该算法使用堆优化的一个C++实现参考: using namespace std; // iPair ==> Integer Pair(整数对) typedef pair<int, int> iPair; // 加边 void addEdge(vector <pair<int, int> > adj[], int u, // 计算最短路 void shortestPath(vector<pair<int,int> > adj[], int V, int src) int main()  以下是该算法Python的一个实现:  import sys max = sys.maxsize  vertices_number = 6 adjacency_matrix = [ start = [] dest = ["2", "5"] key = [] def init_keys(s: int): def dijkstra(from_vertex, dest_vertex):  def find_shortest_router(): def main():  if __name__ == '__main__':

Summary: 戴克斯特拉算法(英语:Dijkstra's algorithm),又译迪杰斯特拉算法,亦可不音译而称为Dijkstra算法,是由荷兰计算机科学家艾兹赫尔·戴克斯特拉在1956年发现的算法,并于3年后在期刊上发表。戴克斯特拉算法使用类似广度优先搜索的方法解决赋权图的单源最短路径问题。

Dijkstrův algoritmus: Dijkstrův algoritmus je algoritmus sloužící k nalezení nejkratší cesty v grafu. Je konečný (pro jakýkoliv konečný vstup algoritmus skončí), protože v každém průchodu cyklu se do množiny navštívených uzlů přidá právě jeden uzel, průchodů cyklem je tedy nejvýše tolik, kolik má graf vrcholů. Funguje nad hranově kladně ohodnoceným grafem (neohodnocený graf lze však na ohodnocený snadno převést). Pro grafy s hranami se záporným ohodnocením se obvykle používá pomalejší Bellmanův–Fordův algoritmus.