最短路径算法:Dijkstra算法

news2024/9/9 4:15:38

引言

在图论中,最短路径算法用于找到从一个顶点到另一个顶点的最短路径。Dijkstra算法是由荷兰计算机科学家艾兹赫尔·戴克斯特拉提出的一种用于计算加权图中单源最短路径的经典算法。本文将详细介绍Dijkstra算法的定义、步骤及其实现。

Dijkstra算法

定义

Dijkstra算法是一种贪心算法,用于计算一个顶点到图中所有其他顶点的最短路径。该算法假设图中不存在负权重的边。

算法步骤

  1. 初始化:设定源顶点的距离为0,其余顶点的距离为正无穷大。将所有顶点标记为未访问。
  2. 从未访问的顶点中选择距离源顶点最小的顶点作为当前顶点。
  3. 对于当前顶点的每个邻接顶点,计算从源顶点经过当前顶点到达该邻接顶点的距离。如果该距离小于已知的距离,则更新已知距离。
  4. 将当前顶点标记为已访问。
  5. 重复步骤2至4,直到所有顶点都被访问。

示例

假设我们有一个带权无向图,顶点集合为 ({A, B, C, D, E}),边和权重集合为 ({(A, B, 2), (A, C, 4), (B, C, 1), (B, D, 7), (C, E, 3), (D, E, 1)})。

2
4
1
7
3
1
A
B
C
D
E

Dijkstra算法实现

下面是用Java实现Dijkstra算法的代码示例:

import java.util.*;

public class DijkstraAlgorithm {
    private int vertices; // 顶点数量
    private int[][] graph; // 图的邻接矩阵

    public DijkstraAlgorithm(int vertices) {
        this.vertices = vertices;
        graph = new int[vertices][vertices];
    }

    // 添加边
    public void addEdge(int src, int dest, int weight) {
        graph[src][dest] = weight;
        graph[dest][src] = weight; // 无向图
    }

    // 计算从源顶点到所有顶点的最短路径
    public void dijkstra(int src) {
        int[] dist = new int[vertices]; // 最短距离数组
        boolean[] visited = new boolean[vertices]; // 已访问顶点标记数组

        // 初始化距离数组,所有顶点的距离设为正无穷大
        Arrays.fill(dist, Integer.MAX_VALUE);
        dist[src] = 0;

        for (int i = 0; i < vertices - 1; i++) {
            // 从未访问顶点中选择距离源顶点最近的顶点
            int u = minDistance(dist, visited);
            visited[u] = true;

            // 更新u的邻接顶点的距离
            for (int v = 0; v < vertices; v++) {
                if (!visited[v] && graph[u][v] != 0 && dist[u] != Integer.MAX_VALUE && dist[u] + graph[u][v] < dist[v]) {
                    dist[v] = dist[u] + graph[u][v];
                }
            }
        }

        printSolution(dist);
    }

    // 查找未访问顶点中距离源顶点最近的顶点
    private int minDistance(int[] dist, boolean[] visited) {
        int min = Integer.MAX_VALUE, minIndex = -1;

        for (int v = 0; v < vertices; v++) {
            if (!visited[v] && dist[v] <= min) {
                min = dist[v];
                minIndex = v;
            }
        }

        return minIndex;
    }

    // 打印最短路径
    private void printSolution(int[] dist) {
        System.out.println("顶点\t 距离源顶点");
        for (int i = 0; i < vertices; i++) {
            System.out.println(i + "\t\t" + dist[i]);
        }
    }

    public static void main(String[] args) {
        int vertices = 5;
        DijkstraAlgorithm graph = new DijkstraAlgorithm(vertices);
        graph.addEdge(0, 1, 2);
        graph.addEdge(0, 2, 4);
        graph.addEdge(1, 2, 1);
        graph.addEdge(1, 3, 7);
        graph.addEdge(2, 4, 3);
        graph.addEdge(3, 4, 1);

        graph.dijkstra(0); // 从顶点0开始计算最短路径
    }
}

Dijkstra算法步骤图解

以下是对上述示例中Dijkstra算法步骤的图解:

  1. 初始化顶点距离和访问状态:
A: 0
B: ∞
C: ∞
D: ∞
E: ∞
  1. 选择距离最小的顶点A,并更新其邻接顶点B和C的距离:
A: 0
B: 2
C: 4
D: ∞
E: ∞
  1. 选择距离最小的顶点B,并更新其邻接顶点C和D的距离:
A: 0
B: 2
C: 3
D: 9
E: ∞
  1. 选择距离最小的顶点C,并更新其邻接顶点E的距离:
A: 0
B: 2
C: 3
D: 9
E: 6
  1. 选择距离最小的顶点E,并更新其邻接顶点D的距离:
A: 0
B: 2
C: 3
D: 7
E: 6
  1. 选择距离最小的顶点D,算法结束。

结论

通过上述讲解和实例代码,我们详细展示了Dijkstra算法的定义、步骤及其实现。Dijkstra算法是一种重要的最短路径算法,广泛应用于各种网络和图的场景。希望这篇博客对您有所帮助!


如果您觉得这篇文章对您有帮助,请关注我的CSDN博客,点赞并收藏这篇文章,您的支持是我持续创作的动力!


关键内容总结

  • Dijkstra算法的定义
  • Dijkstra算法的步骤
  • Dijkstra算法的实现及其图解

推荐阅读:深入探索设计模式专栏,详细讲解各种设计模式的应用和优化。点击查看:深入探索设计模式。


特别推荐:设计模式实战专栏,深入解析设计模式的实际应用,提升您的编程技巧。点击查看:设计模式实战。

如有任何疑问或建议,欢迎在评论区留言讨论。谢谢阅读!


测试代码的运行结果:

顶点	 距离源顶点
0		 0
1		 2
2		 3
3		 7
4		 6

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1961008.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Ruoyi 快速开发平台

Ruoyi 快速开发平台 一、官网二、准备工作2.1 环境要求2.2 必要配置 三、运行系统3.1 后端运行3.2 前端安装及运行 四、自定义开发4.1 新增业务模块4.2 代码生成4.2.1 创建菜单4.2.2 后端代码4.2.3 前端代码 一、官网 链接: 前后端分离版本 回到目录 二、准备工作 2.1 环境要…

UDP服务器端bind失败问题

本人使用microchip芯片开发&#xff0c;使用UDP虚拟机通讯&#xff0c;经常提示bind失败&#xff0c;返回-1&#xff0c;尝试了以前UDP作为客户端使用时正常&#xff0c;故硬件链路没问题。 一、可能有几个原因&#xff1a; 端口实际上被占用&#xff1a;最明显的原因是端口真…

基于入侵野草算法的KNN分类优化matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 入侵野草算法 4.2 K近邻分类器&#xff08;KNN&#xff09; 4.3 基于IWO的KNN分类优化 5.完整程序 1.程序功能描述 基于入侵野草算法的KNN分类优化。其中&#xff0c;入侵野草算法是一…

GEE APP:利用谷歌地球引擎实现更有效的草原管理:决策支持应用视角

简介 草原占地球表面和农田的很大一部分,对人类福祉和畜牧业至关重要。由于牧区基础设施不发达、通信不畅,牧民和草原管理部门在有效控制牧民放牧行为和草原利用方面面临挑战。要解决这一问题,促进草原的可持续利用并保护其生态系统服务,就需要基于云的放牧管理和决策支持…

C++初阶大总结

目录 一.命名空间 1.命名空间定义 2.命名空间使用 二.C++输入&输出 三.缺省参数 四. 函数重载 五.引用 1.常引用 2.传值、传引用效率比较 3.引用和指针的区别 4.引用和指针的不同点: 小知识点: 六.内联函数 七.auto关键字(C++11) 1.auto的使用细则 八.基于…

24暑假算法刷题 | Day23 | LeetCode 39. 组合总和,40. 组合总和 II,131. 分割回文串

目录 39. 组合总和题目描述题解 40. 组合总和 II题目描述题解 131. 分割回文串题目描述题解 39. 组合总和 点此跳转题目链接 题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有…

Dolphinscheduler 3.2.1bug记录

问题1&#xff1a;分页只展示首页 解决方案&#xff1a; [Bug][API] list paging missing totalpage by Gallardot Pull Request #15619 apache/dolphinscheduler GitHub 问题2:Hive 数据源连接失败 解决方案&#xff1a;修改源码&#xff1a;HiveDataSourceProcessor.cla…

A Survey on Multimodal Large Language Models(from gpt-4o)

目录 A Survey on Multimodal Large Language Models1. INTRODUCTION2. ARCHITECTURE2.1 Modality encoder2.2 Pre-trained LLM2.3 Modality interface 3. TRAINING STRATEGY AND DATA3.1 Pre-training3.1.1 Training Detail3.1.2 Data 3.2 Instruction-tuning3.2.1 Introducti…

Linux下文件编译器-GCC/G++

前言 本文介绍了c/c的编译过程以及gcc/g的时使用 一.c/c翻译的本质&#xff1a;将高级语言翻译成二进制 1&#xff09;程序翻译过程&#xff1a; &#xff08;1&#xff09;预处理&#xff08;头文件展开、宏替换、去注释、条件编译&#xff09;还是C语言代码 ​ …

hash表如何形成,hash函数如何计算,什么是hash冲突 如何解决 ,Golang map的底层原理及扩容机制

散列表 散列表&#xff08;hash表&#xff09;:根据给定的关键字来计算出关键字在表中的地址的数据结构。也就是说&#xff0c;散列表建立了关键字和 存储地址之间的一种直接映射关系。 问题&#xff1a;如何建立映射管血 散列函数:一个把查找表中的关键字映射成该关键字对应…

平移、旋转、缩放和媒体

一、平移 1.1translate&#xff08;&#xff09;函数 做转换工作可以用translate()函数&#xff0c;这个函数可以改变坐标系。通过改变默认的坐标系&#xff0c;我们可以创建不同的转换方式&#xff0c;包括平移、旋转和缩放。 1.2平移位置案例 案例代码如图1 图1 保存运行如…

【大一公共课】C语言+python语言入门对比+思维导图

C 和 Python 入门教程对比 一、引言 C 语言和 Python 语言都是在编程领域中广泛使用的语言&#xff0c;但它们在语法、应用场景和学习难度上有很大的不同。本教程将对 C 和 Python 的入门知识进行对比&#xff0c;帮助您更好地理解和选择适合自己的编程语言。 二、C 语言入门 …

python爬取某财富网

过程&#xff1a; 点击底部的第3页&#xff0c;第5页&#xff0c;网页刷新了&#xff0c;但是顶部的url地址没有变。那么就是 动态加载&#xff0c; 就是 XHR. 直接请求api. 实验代码如下: import requestsheaders {"User-Agent": "Mozilla/5.0 (Windows NT…

LLM大模型:2024工业AI大模型发展分析

一、大模型为工业智能化发展带来新机遇 1.1. 大模型开启人工智能应用新时代 大模型引领人工智能技术创新和应用。 自 1956 年达特茅斯会议&#xff08;Dartmouth Conference&#xff09;提出人工智能的概念以来&#xff0c;人工智能技术经历了多个发展高峰和低谷。在这一长期的…

《深入浅出WPF》学习笔记一.解析WPF程序

《深入浅出WPF》学习笔记一.解析WPF程序 visual studio帮助我们做了那些事情 引用文件 输出文件类型 按照最原始的方式&#xff0c;我们需要手动打开编译器命令行&#xff0c;使用命令引用类库将代码编译成目标文件。 visual studio会根据我们选择的项目模板&#xff0c;自动…

Java学习Day19:基础篇9

包 final 权限修饰符 代码块 静态代码块在Java中是一个重要的特性&#xff0c;它主要用于类的初始化操作&#xff0c;并且随着类的加载而执行&#xff0c;且只执行一次。静态代码块的实践应用广泛&#xff0c;以下是几个主要的应用场景&#xff1a; 1. 初始化静态变量 静态代…

芋道源码yudao-cloud 二开日记(Editor富文本本地图片上传报错问题)

&#xff1a; 于是找到富文本的组件代码Editor.vue&#xff0c;检查一下上传的接口地址和token有没有传&#xff0c;如下图&#xff1a; 都没有问题&#xff0c;但还是报错&#xff0c;所以试试自定义上传的方法&#xff1a; // 导入上传文件的接口 import * as FileApi from …

数字图像处理 --- 二维离散余弦变换(python实战)

二维离散余弦变换(python实战) &#xff08;注&#xff1a;文中所讨论的离散余弦变换都是DCT-II&#xff09; 在上一篇文章中&#xff0c;我详细介绍了一维离散余弦变换的基本原理&#xff0c;并且以可视化的方式展示了一维DCT中用于分析输入信号的一系列基础余弦波。 在这篇文…

【简单图解 最强计网八股】HTTP 和 HTTPS 的区别

HTTP&#xff08;HyperText Transfer Protocol 超文本传输协议&#xff09; HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff0c;超文本传输安全协议&#xff09; 通过 传输内容加密 和 身份认证 保证了传输过程的安全性 协议传输内容加密身份认证响应效率端口号…

​LLM大模型从入门到精通(7)--企业大模型开发流程​

一、大模型项目开发的两种方式 2023年以来&#xff0c;随着ChatGPT的火爆&#xff0c;使得LLM成为研究和应用的热点&#xff0c;但是市面上大部分LLM都存在一个共同的问题&#xff1a;模型都是基于过去的经验数据进行训练完成&#xff0c;无法获取最新的知识&#xff0c;以及各…