Johnson 全源最短路径算法
时间: 2023-11-06 13:07:26 浏览: 226
Johnson算法是一种全源最短路径算法,可以求解有向图中任意两点之间的最短路径。相比于其他全源最短路径算法,如Floyd算法和Bellman-Ford算法,Johnson算法在稠密图中表现更好。
Johnson算法的基本思路是通过引入一个虚拟节点和新的边权值来转换原始图,使得所有边的权值非负,然后使用Dijkstra算法求解最短路径。
具体来说,Johnson算法的步骤如下:
1. 在原图基础上添加一个虚拟节点,并从该节点向原图中每个节点都连一条边权值为0的边。
2. 利用Bellman-Ford算法求出虚拟节点到其他节点的最短路径估计值h(v),如果发现有负环,则说明原图中存在负环,无法求解最短路径。
3. 对于原图中每条边(u, v),重新定义边权值为w(u, v) + h(u) - h(v)。
4. 对于修改后的图,使用Dijkstra算法求解任意两点之间的最短路径。
5. 对于得到的最短路径,需要将其转换回原图的路径,即将每个节点的最短路径长度加上h(v) - h(u)。
Johnson算法的时间复杂度为O(nm log n),其中n为节点数,m为边数。相比于Bellman-Ford算法的O(nm)和Floyd算法的O(n^3),Johnson算法在稠密图中表现更好,但在稀疏图中可能会比其他算法慢。
相关问题
介绍最短路径算法的发展历程
最短路径算法是指在图中找到两个节点之间的最短路径的算法。下面是最短路径算法的发展历程:
1. Dijkstra算法:
Dijkstra算法是最短路径算法中最早的算法之一,由荷兰计算机科学家Edsger Dijkstra于1956年发明。该算法基于贪心思想,在加权图中寻找单个源节点到其他所有节点之间的最短路径。该算法的时间复杂度为O(n^2),其中n为节点数。
2. Bellman-Ford算法:
Bellman-Ford算法是由美国数学家Richard Bellman和 Lester Ford Jr.在1958年发明的。该算法可以处理具有负权边的图。该算法使用动态规划的思想,通过多次迭代计算,找到单个源节点到其他所有节点之间的最短路径。该算法的时间复杂度为O(nm),其中n为节点数,m为边数。
3. Floyd算法:
Floyd算法也称为插点法,是由美国计算机科学家Robert Floyd在1962年发明的。该算法可以处理具有负权边的图。该算法基于动态规划的思想,通过求解所有节点对之间的最短路径,找到单个源节点到其他所有节点之间的最短路径。该算法的时间复杂度为O(n^3),其中n为节点数。
4. A*算法:
A*算法是由Peter Hart, Nils Nilsson和 Bertram Raphael在1968年发明的。该算法是一种启发式搜索算法,通过估计每个节点到目标节点的距离,来选择下一步要走的节点。该算法可以处理具有负权边的图,但是需要满足一定的启发式条件。该算法的时间复杂度取决于启发式函数的复杂度。
5. 迪杰斯特拉算法的优化:
在Dijkstra算法中,使用了一个优先队列来存储节点,以便快速找到下一个要处理的节点。但是,当图很大时,优先队列的维护成本很高。因此,出现了一些优化算法,如斐波那契堆(Fibonacci heap)和D-堆(D-ary heap),它们可以更有效地维护优先队列,从而提高了算法的效率。
6. Johnson算法:
Johnson算法是由Neil Johnson在1977年发明的,它可以处理具有负权边的图。该算法先通过Bellman-Ford算法计算出每个节点到其他所有节点的最短路径的估计值,然后使用这个估计值来改变原始边的权值,并应用Dijkstra算法来计算最短路径。该算法的时间复杂度为O(nmlogn),其中n为节点数,m为边数。
7. SPFA算法:
SPFA算法是由李煜东在2001年发明的。该算法可以处理具有负权边的图。该算法使用队列来存储节点,通过不断更新每个节点到源节点的距离,来找到最短路径。该算法的时间复杂度最坏情况下为O(nm),但是在实际应用中,它通常比Bellman-Ford算法和Dijkstra算法更快。
阅读全文