当前位置: 首页 > article >正文

数据结构与算法-17高级数据结构_图论(迪杰斯特拉算法)

迪杰斯特拉算法

1 是什么?

迪杰斯特拉算法(Dijkstra’s Algorithm),又称狄克斯特拉算法,是由荷兰计算机科学家埃德加·狄克斯特拉(Edsger Dijkstra)于1959年提出的一种用于解决有权图中最短路径问题的算法。该算法的核心思想是从一个指定的源点出发,逐步求出源点到图中其他所有顶点的最短路径。

  • 提出者:埃德加·狄克斯特拉(Edsger Dijkstra)
  • 提出时间:1959年
  • 应用领域:主要用于求解有权图(包括有向图和无向图)中的单源最短路径问题

2 实现

2.1 基本实现

  1. 初始化:选择一个源点,将图中所有顶点的最短路径估计值设为无穷大(表示未知),将源点的最短路径估计值设为0。
  2. 创建集合:创建两个集合,一个用于存储已经找到最短路径的顶点(通常称为已访问集合),另一个用于存储尚未找到最短路径的顶点(通常称为未访问集合)。
  3. 选择最小值顶点:从未访问集合中选择一个具有最小最短路径估计值的顶点,称为当前顶点。
  4. 更新邻居:遍历当前顶点的所有邻居,计算从源点经过当前顶点到邻居的路径长度。如果这个长度小于邻居当前的最短路径估计值,则更新邻居的最短路径估计值。
  5. 移动顶点:更新完当前顶点的所有邻居后,将当前顶点从未访问集合移动到已访问集合。
  6. 重复过程:重复步骤3到5,直到未访问集合为空,或者所有顶点的最短路径都被找到。
  7. 构造最短路径:如果需要,可以通过回溯每个顶点的最短路径估计值来构造出从源点到该顶点的最短路径。
  8. 详细步骤见下文图解

2.2 算法特性

  • 贪心算法:迪杰斯特拉算法是贪心算法的一个例子,它在每一步选择局部最优解(即当前顶点的最短路径估计值最小的顶点),以期望获得全局最优解。
  • 适用于稠密图:当图中的边远多于顶点时,迪杰斯特拉算法相对于贝尔曼-福特算法通常更高效。

2.3 图解示例

在这里插入图片描述

在这里插入图片描述

2.4 代码示例

package cn.zxc.demo.leetcode_demo.advanced_data_structure.graph;

/**
 * 求有权图最短路径:迪杰斯特拉算法
 */
public class Dijkstra {

    // 有权有向图
    private int[][] graph;

    // 节点距离
    private int[] dist;

    /**
     * 构建一个有v个顶点的有权有向图
     * @param v
     */
    public Dijkstra(int v) {
        this.graph = new int[v][v];
        this.dist = new int[v];
        // 初始化距离数组,初始值为无限大,这是使用Integer.MAX_VALUE表示
        for (int i = 0; i < v; i++) {
            dist[i] = Integer.MAX_VALUE;
        }
    }

    /**
     * 初始化 有向图
     * @param inits
     */
    public void init(int[][] inits){
        for (int[] init : inits) {
            graph[init[0]][init[1]] = init[2];
        }
    }

    public int dijkstra(int src, int dest) {
        // 创建一个数组,记录已经访问过的顶点
        int visitedNum = 0;
        // 创建一个数组,记录未访问过的顶点
        boolean[] unvisited = new boolean[graph.length];
        for (int i = 0; i < graph.length; i++) {
            unvisited[i] = true;
        }
        // 将原节点的距离设置为0
        dist[src] = 0;
        // 计算每一个顶点到src的最短距离
        while (visitedNum < graph.length){
            // 获取到第一个顶点:距离原点距离最短的顶点
            int min = -1;
            for (int i = 0; i < unvisited.length; i++) {
                if (unvisited[i] && (min == -1 || dist[i] < dist[min])){
                    min = i;
                }
            }
            if (min == -1){
                break;
            }
            // 根据当前顶点更新最短距离
            for (int i = 0; i < graph.length; i++) {
                if (graph[min][i] != 0 && dist[min] + graph[min][i] < dist[i] && unvisited[i]){
                    dist[i] = dist[min] + graph[min][i];
                }
            }
            // 更新已访问过的节点集合
            visitedNum++;
            unvisited[min] = false;
        }
        return dist[dest];
    }

    public static void main(String[] args) {
        // 见上图
        int[][] inits = {{1, 3, 10}, {1, 5, 30}, {1, 6, 100}, {2, 3, 5}, {3, 4, 50}, {5, 4, 20}, {4, 6, 10}, {5, 6, 60}};
        Dijkstra dijkstra = new Dijkstra(7);
        dijkstra.init(inits);
        System.out.println(dijkstra.dijkstra(1, 6));
    }
}

http://www.kler.cn/a/308085.html

相关文章:

  • Vue计算属性computed
  • Java NIO 深度解析:构建高效的 I/O 操作
  • 前缀和技巧解析
  • makefile 设置动态库路径参数
  • 2023年MathorCup数学建模B题城市轨道交通列车时刻表优化问题解题全过程文档加程序
  • 软件测试面试大全(含答案+文档)
  • 5分钟熟练上手ES的具体使用
  • Python数据分析-Steam 收入排名前 1500 的游戏
  • 克隆虚拟机,xshell无法传文件,windows无法ping克隆虚拟机,已解决
  • idea2024 Safe Mode解决、配置git出现Can‘t run a Git command in the safe mode、取消受信任项目功能
  • Python | Leetcode Python题解之第409题最长回文串
  • JDBC与MyBatis:数据库访问技术的变迁【后端 15】
  • VScode 怎么缩放界面大小
  • Spring Boot 3项目使用Swagger3教程
  • Web 安全基础教程:从零基础入门到精通
  • chatgpt个人版ssrf漏洞
  • [Unity Demo]从零开始制作空洞骑士第三集之导入插件2D toolkit和使用playmaker制作敌人状态机以及扩展FSM脚本
  • CSP-J初赛每日题目2
  • 深度学习Day-33:Semi-Supervised GAN理论与实战
  • 【电脑组装】✈️从配置拼装到安装系统组装自己的台式电脑
  • 华为eNSP使用详解
  • 【编程底层原理】亿级数据表查询最后10条记录limit 99999990,10性能为啥特慢,而且数据库都被查宕机了
  • C语言中数据类型
  • PHP:强大的Web开发语言
  • nginx实现https安全访问的详细配置过程
  • Spring Boot-RESTful API相关问题