迪杰斯特拉算法 – 图的单源最短路径

这篇具有很好参考价值的文章主要介绍了迪杰斯特拉算法 – 图的单源最短路径。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

概述

迪杰斯特拉算法是由荷兰计算机科学家狄克斯特拉于1959 年提出的,因此又叫狄克斯特拉算法。是从一个顶点到其余各顶点的最短路径算法,解决的是有权图中最短路径问题。迪杰斯特拉算法主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止。迪杰斯特拉算法采用的是贪心策略,将Graph中的节点集分为最短路径计算完成的节点集S和未计算完成的节点集T,每次将从T中挑选V0->Vt最小的节点Vt加入S,并更新V0经由Vt到T中剩余节点的更短距离,直到T中的节点全部加入S中,它贪心就贪心在每次都选择一个距离源点最近的节点加入最短路径节点集合。迪杰斯特拉算法只支持非负权图,它计算的是单源最短路径,即单个源点到剩余节点的最短路径,时间复杂度为O(n²)。

算法流程

本节将对算法流程进行模拟,设置Graph为包含7个顶点和9条边的有向无环图,源点为0,计算从源点0到剩余节点的最短路径,Graph如下:

迪杰斯特拉,数据结构算法,算法,图论,数据结构

 文章来源地址https://www.toymoban.com/news/detail-753001.html

每个节点将维护shortest和visited两个数据结构,shortest存储v0到该节点的最短路径,visited存储v0到该节点的最短路径是否求出。S为已求出最短路径的节点,T为未求出最短路径的节点。源节点只允许将S中的节点作为中间节点来计算到达其它节点的最短路径,不允许将T中的节点作为中间节点来计算到达其它节点的最短路径。随着S中节点的增加,源节点可达的节点才会增加。初始状态下,源节点只可达节点1和节点3。

算法步骤如下:

1、将源节点(即节点0)加入S中,对shortest和visited数组进行更新。

迪杰斯特拉,数据结构算法,算法,图论,数据结构

 

2、S中现有节点0,源节点可达T中的节点1和节点3,节点0->节点1距离为5,节点0->节点3距离为3,按距离从小到大排序,因此选择将节点3加入S中。更新源点将节点3作为中间节点到达其它节点的距离。

迪杰斯特拉,数据结构算法,算法,图论,数据结构

 

3、S中现有节点0和节点3,源节点可达T中的节点1和4,节点0->节点1距离为5,节点0->节点4距离为8,按距离从小到大排序,因此选择将节点1加入S中。更新源点将节点1作为中间节点到达其它节点的距离。

迪杰斯特拉,数据结构算法,算法,图论,数据结构

 

4、S中现有节点0、1、3,源节点可达T中的节点2、4、5,0->2距离为12,0->4距离为8,0->5距离为6,按距离从小到大排序,因此选择将节点5加入S中。更新源点将节点5作为中间节点到达其它节点的距离。

迪杰斯特拉,数据结构算法,算法,图论,数据结构

 

5、S中现有节点0、1、3、5,源节点可达T中的节点2、4、6,0->2距离为12,0->4距离为8,0->6距离为14,按距离从小到大排序,因此选择将节点4加入S中。更新源点将节点4作为中间节点到达其它节点的距离。

迪杰斯特拉,数据结构算法,算法,图论,数据结构

 

6、S中现有节点0、1、3、4、5,源节点可达T中的节点2、6,0->2距离为10,0->6距离为14,按距离从小到大排序,因此选择将节点2加入S中。更新源点将节点2作为中间节点到达其它节点的距离。

迪杰斯特拉,数据结构算法,算法,图论,数据结构

 

7、T中只剩下节点6,0->6距离为14,将节点6加入S中。

迪杰斯特拉,数据结构算法,算法,图论,数据结构

 

8、算法结束,源点到其它节点的最短路径都已依次求出。

迪杰斯特拉,数据结构算法,算法,图论,数据结构

 

public class Dijkstra  {
    /**
     * 两点之间路线不通
     */
    private static final int M = 10000;
​
    public static void main(String[] args) {
        // 二维数组每一行分别是 A、B、C、D、E 各点到其余点的距离,
        // A -> A 距离为0, 常量M 为正无穷
        int[][] weight1 = {
                {0, 5, M, 3, M, M, M},
                {5, 0, 7, 8, M, 1, M},
                {M, 7, 0, M, M, 4, M},
                {3, 8, M, 0, 5, M, M},
                {M, M, M, 5, 0, 5, 6},
                {M, 1, 4, M, 5, 0, M},
                {M, M, M, M, 6, M, 0}
        };
​
        int start = 0;
​
        int[] shortPath = dijkstra(weight1, start);
​
        for (int i = 0; i < shortPath.length; i++) {
            System.out.println("从" + start + "出发到" + i + "的最短距离为:" + shortPath[i]);
        }
    }
​
    private static int[] dijkstra(int[][] weight, int start) {
        // 接受一个有向图的权重矩阵,和一个起点编号start(从0编号,顶点存在数组中)
        // 返回一个int[] 数组,表示从start到它的最短路径长度
        // 顶点个数
        int n = weight.length;
        // 保存start到其他各点的最短路径
        int[] shortPath = new int[n];
        // 保存start到其他各点最短路径的字符串表示
        String[] path = new String[n];
        for (int i = 0; i < n; i++) {
            path[i] = start + "-->" + i;
        }
        // 标记当前该顶点的最短路径是否已经求出,1表示已求出
        int[] visited = new int[n];
​
        // 初始化,第一个顶点已经求出
        shortPath[start] = 0;
        visited[start] = 1;
​
        // 要加入n-1个顶点
        for (int count = 1; count < n; count++) {
            // 选出一个距离初始顶点start最近的未标记顶点
            int k = -1;
            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;
    }
​
}

迪杰斯特拉,数据结构算法,算法,图论,数据结构 

 

到了这里,关于迪杰斯特拉算法 – 图的单源最短路径的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 最短路径:迪杰斯特拉算法

    简介         英文名Dijkstra         作用:找到路中指定起点到指定终点的带权最短路径 核心步骤         1)确定起点,终点         2)从未走过的点中选取从起点到权值最小点作为中心点         3)如果满足 起点到中心点权值 + 中心点到指定其他点的

    2024年02月08日
    浏览(30)
  • 最短路径——迪杰斯特拉算法

    日常生活中常常涉及最短路径问题,如在一个城市交通网中,如何选取从起点到达终点的路径,才能使这一趟旅程的路程最短?或所需时间最少?或所需交通费用最低?诸如此类问题都可以抽象为 求解图的最短路径问题 。我们把 图的顶点 表示为 城市的交通站点 , 边表示交

    2024年02月04日
    浏览(36)
  • 迪杰斯特拉算法(求最短路径)

    迪杰斯特拉算法用于查找图中某个顶点到其它所有顶点的最短路径,该算法既适用于无向加权图,也适用于有向加权图。 注意,使用迪杰斯特拉算法查找最短路径时,必须保证图中所有边的权值为非负数,否则查找过程很容易出错。 迪杰斯特拉算法的实现思路 图 1 是一个无

    2024年02月02日
    浏览(29)
  • 算法提高-图论-单源最短路的综合应用

    多次dijkstra求每个点到其它点的最短距离, 此时相当于建好了一张图,每个点之间的最短距离都知道了,接下来dfs搜一下怎么走最短即可 一篇博客解释了为什么一个正向建图求最小值,反向建图求最大值 根本思想是保证1到n的买卖是连通的

    2024年02月11日
    浏览(37)
  • C++算法:单源最短路径Dijkstra

    如果你有一份北京地图,想从中关村走到三元桥,那么怎样能找出实现这一目的的最短路径呢?一种可能的方法就是将这两点之间所有的路线都找出来,然后求出每条路线的距离,找出最短的路线。但是仔细想想我们就会发现这种办法几乎是不可行的,因为这样的路线太多了,

    2024年02月09日
    浏览(36)
  • 算法提高-图论-单源最短路的扩展应用

    多源点单终点最短路建图: 创建虚拟源点(创建虚拟源点的时候以是spfa为例 可以在建图的时候建出来,也可以在spfa这直接入队,也是虚拟源点的意思) 反向建图变成单源点多终点,然后遍历终点的dist即可找出最短路 这题挺简单的就不详细说了,主要是第一次遇到计数问题

    2024年02月16日
    浏览(36)
  • 图论算法基础:单源最短路径Dijkstra算法分析

    在 有向带权图 中给定一个起始顶点(源点),Dijkstra算法可以求出 所有其他顶点 到源点的最短路径,Dijkstra算法 不能用于同时含有正负权值的边的图 Source 顶点集合:已经确定 到源点的最短路径 的顶点就会加入 Source 集合中, Source 集合初始时只有源点 dist 数组:用于记录每个顶点到

    2024年02月11日
    浏览(30)
  • 算法提高-图论-单源最短路的建图方式

    建图 找出一个牧场,它到其他牧场的距离之和最小 我是这么理解的,djsktra是一个贪心的思想,加法里面不能加负数我就不说了 求乘法最大值的时候为什么边权必须0-1,因为在乘法最大值里面有一个边权大于1的话那不就等价于求加法最小值的时候有一个边权为负数的么,d

    2024年02月08日
    浏览(32)
  • 【算法入门&搜索法】走迷宫|单源最短路径1

    ✅作者简介:热爱后端语言的大学生,CSDN内容合伙人 ✨精品专栏:C++面向对象 🔥系列专栏:算法百炼成神 本专栏收录的均为牛客网的算法题目,内含链表、双指针、递归、动态规划、基本数据结构等算法思想的具体运用。牛客网不仅有大量的经典算法题目,也有大厂的面

    2024年02月03日
    浏览(53)
  • 贝尔曼福特算法——负权值单源最短路径

    title: 贝尔曼福特算法——负权值单源最短路径 date: 2023-05-16 11:42:26 tags: 数据结构与算法 **问题:**具有负权值非环图的单源最短路径算法 git地址:https://github.com/944613709/HIT-Data-Structures-and-Algorithms 对图中的边进行V-1轮遍历,对所有的边松弛(对每条边v1-v2,如果d[v2]+Weight(v1-v2)

    2024年02月14日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包