记录我在算法研讨课上的精彩表现,甚至被教授称之为自开课以来最最优秀的报告了,没有之一!
下面开始我的表演。
今天研讨的是迪杰斯特拉算法的优化,那么从什么角度出发?,经过查阅数篇论文,我们小组讨论得出数据结构方面的优化最优突破的可能性,相信大家之前也看到过不少小组展示的堆优化,但今天我们将首次从优化动机角度出发,在近四十年的优化历史历程中,以更加系统宏观的角度回顾历史,带大家开始堆的这场进化之旅。
这是我们给出的迪杰斯特拉算法代码,在人类的历史长河中,单源最短路径问题的现实困难最终催生了迪杰斯特拉算法,然而不幸的是,最初采用的数组或链表结构难以解决大规模数据运算复杂度的要求。具体分析这段代码,结合论文,我们发现可以从3个操作当中进行算法的优化,一个是pop_min操作:选择最小值并弹出;第二个操作是decrease_key操作:也就是更新键值,即每个点到源点的最短路径;最后一个操作是push操作,插入一个点,也就是这个点到源点的就、路径从无穷大到一个常数。
这就是这段进化之旅的总体展示,1964年,J·W·J·Williams首先向这一问题发起了冲击主要的优化是堆的优化,从历史的角度来分析,迪杰斯特拉在1956年就提出了单源最短路径的迪杰斯特拉算法,最经典的算法是用数组或链表来实现的;8年之后,J·W·J·Williams提出二叉堆,在1978年Jean Vuillemin 创造了二项式队列,后来又有了那两种堆。
Linked List 链表
链表
Operation | Linked List |
---|---|
Push | O(1) |
Pop_min | O(n) |
Decrease_key | O(1) |
1956年迪杰斯特拉提出这一算法时因为使用了链表结构,pop_min阶段的复杂度达到O(n)
在循环链表当中,有两个指针,一个指向头节点,一个指向最小节点。
Binary Heap 二叉堆
二叉堆
Operation | Linked List | Binary Heap |
---|---|---|
Push | O(1) | O(log n) |
Pop_min | O(n) | O(log n) |
Decrease_key | O(1) | O(log n) |
1978年J·W·J·Williams使用了优先队列及堆这一数据结构,使3个操作的时间复杂度都变为O(log n),整体上加快了算法,具体来看下面。
二叉堆的结构使得O(log n)的复杂度实现了大量数据的优化。