zoukankan      html  css  js  c++  java
  • 数学建模2之迪杰特斯拉算法(上)

     转载自:链接:https://www.jianshu.com/p/ff6db00ad866   ,

    这篇文章很好的解释了算的原理和过程,转自于简书,链接已经标注,传播一下,希望跟多的人能力理解。   

    迪杰斯特拉(Dijkstra)算法是典型最短路径算法,用于计算一个节点到其他节点的最短路径。
    它的主要特点是以起始点为中心向外层层扩展(广度优先搜索思想),直到扩展到终点为止。

    Dijkstra算法可以计算任意节点其他节点的最短路径

     
     

    算法思路

    1. 指定一个节点,例如我们要计算 'A' 到其他节点的最短路径
    2. 引入两个集合(S、U),S集合包含已求出的最短路径的点(以及相应的最短长度),U集合包含未求出最短路径的点(以及A到该点的路径,注意 如上图所示,A->C由于没有直接相连 初始时为∞
    3. 初始化两个集合,S集合初始时 只有当前要计算的节点,A->A = 0
      U集合初始时为 A->B = 4, A->C = ∞, A->D = 2, A->E = ∞敲黑板!!!接下来要进行核心两步骤了
    4. 从U集合中找出路径最短的点,加入S集合,例如 A->D = 2
    5. 更新U集合路径,if ( 'D 到 B,C,E 的距离' + 'AD 距离' < 'A 到 B,C,E 的距离' ) 则更新U
    6. 循环执行 4、5 两步骤,直至遍历结束,得到A 到其他节点的最短路径

    算法图解

    1.选定A节点并初始化,如上述步骤3所示
     
     

    2.执行上述 4、5两步骤,找出U集合中路径最短的节点D 加入S集合,并根据条件 if ( 'D 到 B,C,E 的距离' + 'AD 距离' < 'A 到 B,C,E 的距离' ) 来更新U集合

     
     

    3.这时候 A->B, A->C 都为3,没关系。其实这时候他俩都是最短距离,如果从算法逻辑来讲的话,会先取到B点。而这个时候 if 条件变成了 if ( 'B 到 C,E 的距离' + 'AB 距离' < 'A 到 C,E 的距离' )如图所示这时候A->B距离 其实为 A->D->B

     
     
    1. 思路就是这样,往后就是大同小异了
     
     
    1. 算法结束
     
     
    使用JAVA实现。
    public class Dijkstra {
        public static final int M = 10000; // 代表正无穷
        
        public static void main(String[] args) {
            // 二维数组每一行分别是 A、B、C、D、E 各点到其余点的距离, 
            // A -> A 距离为0, 常量M 为正无穷
            int[][] weight1 = {
                    {0,4,M,2,M}, 
                    {4,0,4,1,M}, 
                    {M,4,0,1,3}, 
                    {2,1,1,0,7},   
                    {M,M,3,7,0} 
                };
    
            int start = 0;
            
            int[] shortPath = dijkstra(weight1, start);
    
            for (int i = 0; i < shortPath.length; i++)
                System.out.println("从" + start + "出发到" + i + "的最短距离为:" + shortPath[i]);
        }
    
        public static int[] dijkstra(int[][] weight, int start) {
            // 接受一个有向图的权重矩阵,和一个起点编号start(从0编号,顶点存在数组中)
            // 返回一个int[] 数组,表示从start到它的最短路径长度
            int n = weight.length; // 顶点个数
            int[] shortPath = new int[n]; // 保存start到其他各点的最短路径
            String[] path = new String[n]; // 保存start到其他各点最短路径的字符串表示
            for (int i = 0; i < n; i++)
                path[i] = new String(start + "-->" + i);
            int[] visited = new int[n]; // 标记当前该顶点的最短路径是否已经求出,1表示已求出
    
            // 初始化,第一个顶点已经求出
            shortPath[start] = 0;
            visited[start] = 1;
    
            for (int count = 1; count < n; count++) { // 要加入n-1个顶点
                int k = -1; // 选出一个距离初始顶点start最近的未标记顶点
                int dmin = Integer.MAX_VALUE;
                for (int i = 0; i < n; i++) {
                    if (visited[i] == 0 && weight[start][i] < dmin) {
                        dmin = weight[start][i];
                        k = i;
                    }
                }
    
                // 将新选出的顶点标记为已求出最短路径,且到start的最短路径就是dmin
                shortPath[k] = dmin;
                visited[k] = 1;
    
                // 以k为中间点,修正从start到未访问各点的距离
                for (int i = 0; i < n; i++) {
                    //如果 '起始点到当前点距离' + '当前点到某点距离' < '起始点到某点距离', 则更新
                    if (visited[i] == 0 && weight[start][k] + weight[k][i] < weight[start][i]) {
                        weight[start][i] = weight[start][k] + weight[k][i];
                        path[i] = path[k] + "-->" + i;
                    }
                }
            }
            for (int i = 0; i < n; i++) {
                
                System.out.println("从" + start + "出发到" + i + "的最短路径为:" + path[i]);
            }
            System.out.println("=====================================");
            return shortPath;
        }
        
    }
  • 相关阅读:
    WPF DelegateCommand 出现Specified cast is not valid
    WPF DelegateCommand 出现Specified cast is not valid
    WPF DelegateCommand 出现Specified cast is not valid
    win10 sdk 是否向下兼容
    win10 sdk 是否向下兼容
    win10 sdk 是否向下兼容
    PHP extract() 函数
    PHP end() 函数
    PHP each() 函数
    PHP current() 函数
  • 原文地址:https://www.cnblogs.com/lgy-gdeu/p/11433850.html
Copyright © 2011-2022 走看看