算法系列最短路径Dijkstra算法和JAVA实现

2023年 10月 5日 58.8k 0

Dijkstra算法是一种用于解决单源最短路径问题的经典算法,由荷兰计算机科学家Edsger W. Dijkstra于1956年提出。它可以找到从起始节点到所有其他节点的最短路径。

基本介绍

该算法的基本思想是通过逐步扩展节点的方式,逐渐确定从起始节点到其他节点的最短路径。算法维护两个集合:一个是已确定最短路径的节点集合,记为S;另一个是还未确定最短路径的节点集合,记为V-S。

算法步骤:

  • 创建一个距离表,用于记录起始节点到各个节点的当前最短距离。起始节点的最短距离初始化为0,其他节点的最短距离初始化为无穷大(或一个很大的数)。

  • 选择起始节点作为当前节点,并将其加入已确定最短路径的节点集合S。

  • 对于当前节点的所有邻居节点,更新它们的最短距离。具体步骤如下:

    • 遍历当前节点的所有邻居节点。
    • 对于每个邻居节点,计算从起始节点经过当前节点到达该邻居节点的距离。如果该距离小于该邻居节点当前的最短距离,则更新最短距离。
  • 从未确定最短路径的节点集合V-S中选择一个距离最小的节点作为新的当前节点,并将其加入已确定最短路径的节点集合S。

  • 重复步骤3和步骤4,直到所有节点都被加入到已确定最短路径的节点集合S中,或者无法找到更短的路径。

  • 最终,距离表中记录的即为起始节点到各个节点的最短距离。

  • Dijkstra算法的关键在于每次选择距离最小的节点作为当前节点,并通过更新邻居节点的最短距离来逐步扩展最短路径。该算法基于贪心策略,每次选择当前最优解,因此可以找到最短路径。

    需要注意的是,Dijkstra算法要求图中的边权重非负,且对于有向图和无向图都适用。如果图中存在负权边,可以使用其他算法,如Bellman-Ford算法或SPFA算法来解决最短路径问题。

    举例

    以D为开头,求D到各个点的最短距离。

    image.png

    第1步:初始化距离,其实指与D直接连接的点的距离。dis[c]代表D到C点的最短距离,因而初始dis[C]=3,dis[E]=4,dis[D]=0,其余为无穷大。设置集合S用来表示已经找到的最短路径。此时,S={D}。现在得到D到各点距离 {D(0),C(3),E(4),F(*),G(*),B(*),A(*)} ,其中*代表未知数也可以说是无穷大,括号里面的数值代表D点到该点的最短距离。

    第2步:不考虑集合S中的值,因为dis[C]=3,是当中距离最短的,所以此时更新S,S={D,C} 。接着我们看与C连接的点,分别有B,E,F,已经在集合S中的不看,dis[C-B]=10,因而dis[B]=dis[C]+10=13,dis[F]=dis[C]+dis[C-F]=9,dis[E]=dis[C]+dis[C-E]=3+5=8>4 (初始化时的dis[E]=4) 不更新。此时 {D(0),C(3),E(4),F(9),G(*),B(13),A(*)}。

    第3步:在第2步中,E点的值4最小,更新S={D,C,E} ,此时看与E点直接连接的点,分别有F,G。dis[F]=dis[E]+dis[E-F]=4+2=6(比原来的值小,得到更新),dis[G]=dis[E]+dis[E-G]=4+8=12(更新)。此时 {D(0),C(3),E(4),F(6),G(12),B(13),A(*)} 。

    第4步:在第3步中,F点的值6最小,更新S={D,C,E,F} ,此时看与F点直接连接的点,分别有B,A,G。dis[B]=dis[F]+dis[F-B]=6+7=13,dis[A]=dis[F]+dis[F-A]=6+16=22,dis[G]=dis[F]+dis[F-G]=6+9=15>12(不更新)。此时 {D(0),C(3),E(4),F(6),G(12),B(13),A(22)}.

    第5步:在第4步中,G点的值12最小,更新S={D,C,E,F,G} ,此时看与G点直接连接的点,只有A。dis[A]=dis[G]+dis[G-A]=12+14=26>22(不更新)。 {D(0),C(3),E(4),F(6),G(12),B(13),A(22)}.

    第6步:在第5步中,B点的值13最小,更新S={D,C,E,F,G,B} ,此时看与B点直接连接的点,只有A。dis[A]=dis[B]+dis[B-A]=13+12=25>22(不更新)。 {D(0),C(3),E(4),F(6),G(12),B(13),A(22)}.

    第6步:最后只剩下A值,直接进入集合S={D,C,E,F,G,B,A} ,此时所有的点都已经遍历结束,得到最终结果 {D(0),C(3),E(4),F(6),G(12),B(13),A(22)}.

    JAVA实现

    上述案例的JAVA实现

    import java.util.Arrays;

    public class DijkstraAlgorithm {
    private static int minDistance(int[] dist, boolean[] visited) {
    int min = Integer.MAX_VALUE;
    int minIndex = -1;

    for (int i = 0; i < dist.length; i++) {
    if (!visited[i] && dist[i]

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论