Dijkstra(迪杰斯特拉)算法求解最短路径

简介:

过程                                                                                   

Dijkstra_Animation

首先需要记录每个点到原点的距离,这个距离会在每一轮遍历的过程中刷新每一个节点到原点的最短路径是其上一个节点(前驱节点)到原点的最短路径加上前驱节点到该节点的距离。以这个原则,经过N轮计算就能得到每一个节点的最短距离。

第一轮,可以计算出,2、3、4、5、6到原点1的距离分别为:[7, 9, -1, -1, 14]。-1表示无穷大。取其中最小的,为7,即可以确定1的最短路径为0,2为下一轮的前驱节点。同时确定2节点的最短路径为7,路线:1->2

第二轮,取2节点为前驱节点,按照前驱节点的最短距离加上该节点与前驱节点的距离计算新的最短距离,可以得到3,4,5,6节点到原点的距离为:[17, 22, -1, -1],此时需要将这一轮得到的结果与上一轮的比较3节点:17 > 9,最短路径仍然为9;4节点:22 < 无穷大,刷新4节点的最短路径为225节点:不变,仍然为无穷大6节点:14 < 无穷大,取14,不变。则可以得到本轮的最短距离为:[9, 22, -1, 14],取最短路径最小的节点,为3,作为下一轮的前驱节点。同时确定3节点的最短路径为9,路线:1->3。

第三轮,同上,以3为前驱节点,得到4,5,6的计算距离为:[20, -1, 11],按照取最短路径的原则,与上一轮的进行比较,刷新为:[20, –1, 11],选定6为下一轮的前驱节点。同时取定6的最短路径为11,路线:1->3->6。

第四轮,同上,以6为前驱节点,得到4和5的计算距离为[20, 20],与上一轮进行比较,刷新后为[20, 20],二者相等只剩下两个节点,并且二者想等,剩下的计算已经不需要了。则两个节点的最短路径都为20。整个计算结束。4的最短路径为20,路线:1->3->4。5的最短路径为20,路线:1->3->6->5。

如果二者不相等,则还需要进行第五轮,先确定二者中的一个的最短路径和路线,再取定剩下的。直到整个5次循环都完成。

伪代码                                                                                 

复制代码
function Dijkstra(G, w, s)
   for each vertex v in V[G]         //初始化
         d[v] := infinity             //将各点的已知最短距离先设成无穷大
         previous[v] := undefined     // 各点的已知最短路径上的前趋都未知
   d[s] := 0                         // 因为出发点到出发点间不需移动任何距离,所以可以直接将s到s的最小距离设为0
   S := empty set
   Q := set of all vertices
   while Q is not an empty set       // Dijkstra算法主体
         u := Extract_Min(Q)
         S.append(u)
         for each edge outgoing from u as (u,v)
                if d[v] > d[u] + w(u,v)       // 拓展边(u,v)。w(u,v)为从u到v的路径长度。
                      d[v] := d[u] + w(u,v)   // 更新路径长度到更小的那个和值。
                      previous[v] := u        // 记录前面顶点
复制代码

Code                                                                                   

复制代码
public class Dijkstra
{
    public static final int M = -1;

    public static void main(String[] args)
    {
        int[][] map1 = { 
                { 0,  7,  9,  M,  M, 14 }, 
                { 7,  0,  10, 15, M, M },
                { 9,  10, 0,  11, M, 2 }, 
                { M,  15, 11, 0,  6, M },
                { M,  M,  M,  6,  0, 9 }, 
                { 14, M,  2,  M,  9, 0 } };

        int orig = 0;
        int[] shortPath = Dijsktra(map1, orig);

        if (shortPath == null)
        {
            return;
        }
        
        for (int i = 0; i < shortPath.length; i++)
        {
            System.out.println("从" + (orig + 1) + "出发到" + (i + 1) + "的最短距离为:"
                    + shortPath[i]);
        }
    }

    public static int[] Dijsktra(int[][] weight, int orig)
    {
        int n = weight.length;              // 顶点个数

        int[] shortest = new int[n];        // 存放从start到其他各点的最短路径
        boolean[] visited = new boolean[n]; // 标记当前该顶点的最短路径是否已经求出,true表示已求出

        // 初始化,第一个顶点求出
        shortest[orig] = 0;
        visited[orig] = true;

        for (int count = 0; count != n - 1; count++) // 要加入n-1个顶点
        {
            // 选出一个距离初始顶点最近的未标记顶点
            int k = M;     
            int dmin = M;
            for (int i = 0; i < n; i++)
            {
                if (!visited[i] && weight[orig][i] != M)
                {
                     if (dmin == -1 || dmin > weight[orig][i])
                     {
                         dmin = weight[orig][i];
                         k = i;
                     }
                }
            }

            // 正确的图生成的矩阵不可能出现K == M的情况
            if (k == M)
            {
                System.out.println("the input map matrix is wrong!");
                return null;
            }
            
            shortest[k] = dmin;
            visited[k] = true;

            // 以k为中间点,修正从原点到未访问各点的距离
            for (int i = 0; i < n; i++)
            {
                if (!visited[i] && weight[k][i] != M)
                {
                    int callen = dmin + weight[k][i];
                    if (weight[orig][i] == M || weight[orig][i] > callen)
                    {
                        weight[orig][i] = callen;
                    }
                }
            }
        }

        return shortest;
    }
}


本文转自我爱物联网博客园博客,原文链接:http://www.cnblogs.com/yydcdut/p/4008180.html,如需转载请自行联系原作者
相关文章
|
2月前
|
人工智能 算法 数据可视化
路径规划最全综述+代码+可视化绘图(Dijkstra算法+A*算法+RRT算法等)-2
路径规划最全综述+代码+可视化绘图(Dijkstra算法+A*算法+RRT算法等)-2
206 0
|
2月前
|
存储 人工智能 算法
路径规划最全综述+代码+可视化绘图(Dijkstra算法+A*算法+RRT算法等)-1
路径规划最全综述+代码+可视化绘图(Dijkstra算法+A*算法+RRT算法等)-1
70 0
|
7天前
|
算法 定位技术 Windows
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
R语言最大流最小割定理和最短路径算法分析交通网络流量拥堵问题
13 4
|
1月前
|
算法
关于Dijkstra算法
关于Dijkstra算法
|
1月前
|
人工智能 算法 Java
【算法设计与分析】— —单源最短路径的贪心算法
【算法设计与分析】— —单源最短路径的贪心算法
32 0
|
3月前
|
算法 定位技术 C++
数据结构实训(大作业)c++模拟北斗卫星导航系统简单的迪杰斯特拉算法
数据结构实训(大作业)c++模拟北斗卫星导航系统简单的迪杰斯特拉算法
24 0
|
3月前
|
算法
bellman_ford算法与dijkstra为什么dijkstra算法不能计算带有负权边图
bellman_ford算法与dijkstra为什么dijkstra算法不能计算带有负权边图
22 0
|
1月前
|
传感器 算法 计算机视觉
基于肤色模型和中值滤波的手部检测算法FPGA实现,包括tb测试文件和MATLAB辅助验证
该内容是关于一个基于肤色模型和中值滤波的手部检测算法的描述,包括算法的运行效果图和所使用的软件版本(matlab2022a, vivado2019.2)。算法分为肤色分割和中值滤波两步,其中肤色模型在YCbCr色彩空间定义,中值滤波用于去除噪声。提供了一段核心程序代码,用于处理图像数据并在FPGA上实现。最终,检测结果输出到&quot;hand.txt&quot;文件。
|
1月前
|
机器学习/深度学习 算法 计算机视觉
基于yolov2深度学习网络的视频手部检测算法matlab仿真
基于yolov2深度学习网络的视频手部检测算法matlab仿真
|
1月前
|
算法
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
【MATLAB】语音信号识别与处理:移动中位数滤波算法去噪及谱相减算法呈现频谱
23 2

热门文章

最新文章