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

【数据结构与算法】迪杰斯特拉算法

迪杰斯特拉算法

介绍

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

算法过程

设置出发顶点为 v,顶点集合 V{v1,v2,v3…vi},v 到 V 中各顶点的距离构成距离集合 Dis,Dis{d1,d2,d3…di},Dis 集合记录着 v 到图中各顶点的距离(到自身可以看做 0,v 到 vi 举例对应为 di)

  1. 从 Dis 中选择值最小的 di 并移出 Dis 集合,同时移出 V 集合中对应的顶点 vi,此时的 v 到 vi 即为最短路径
  2. 更新 Dis 集合,更新规则为:比较 v 到 V 结合中顶点的距离值,与 v 通过 vi 到 V 集合中顶点的距离值,保留值最小的一个(同时也应该更新顶点的前驱节点为 vi,表明是通过 vi 到达的)
  3. 重复执行两步骤,直到最短路径顶点为目标顶点即可结束

迪杰斯特拉算法最佳应用 - 最短路径

在这里插入图片描述

  1. 战争时期,胜利乡有 7 个村庄(A,B,C,D,E,F,G),现在有六个邮差,从 G 点出发,需要分别把邮件分别送到 A,B,C,D,E,F 六个村庄
  2. 各个村庄的距离用边线表示(权),比如 A - B 距离 5 公里
  3. 问:如何计算出 G 村庄到其他各个村庄的最短距离?
  4. 如果从其他点出发到各个点的最短距离又是多少?

代码实现

public class DijkstraAlgorithm {public static void main(String[] args) {char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};// 邻接矩阵int[][] matrix = new int[vertex.length][vertex.length];final int N = 65535; // 表示不可连接matrix[0] = new int[]{N, 5, 7, N, N, N, 2};matrix[1] = new int[]{5, N, N, 9, N, N, 3};matrix[2] = new int[]{7, N, N, N, 8, N, N};matrix[3] = new int[]{N, 9, N, N, N, 4, N};matrix[4] = new int[]{N, N, 8, N, N, 5, 4};matrix[5] = new int[]{N, N, N, 4, 5, N, 6};matrix[6] = new int[]{2, 3, N, N, 4, 6, N};// 创建图Graph graph = new Graph(vertex, matrix);graph.showGraph();graph.dsj(6);graph.showDijkstra();}
}class Graph {private char[] vertex; // 顶点数组private int[][] matrix; // 邻接矩阵private VisitedVertex vv; // 已经访问的顶点的集合public Graph(char[] vertex, int[][] matrix) {this.vertex = vertex;this.matrix = matrix;}/*** 显示结果*/public void showDijkstra() {vv.show();}/*** 显示图*/public void showGraph() {for (int[] link : matrix) {System.out.println(Arrays.toString(link));}}/*** 迪杰斯特拉算法** @param index 表示出发顶点对应的下标*/public void dsj(int index) {vv = new VisitedVertex(vertex.length, index);update(index); // 更新 index 顶点到周围顶点的距离和前驱顶点for (int j = 1; j < vertex.length; j++) {index = vv.updateArr(); // 选择并返回新的访问节点update(index); // 更新 index 顶点到周围顶点的距离和前驱顶点}}/*** 更新 index 下标顶点到周围顶点的距离和周围定额点的前驱顶点** @param index*/private void update(int index) {int len = 0;// 根据遍历我们的邻接矩阵的 matrix[index] 行for (int j = 0; j < matrix[index].length; j++) {// len 含义是:出发顶点到 index 顶点的距离 + 从 index 顶点到 j 顶点的距离的和len = vv.getDis(index) + matrix[index][j];// 如果 j 顶点没有被访问过,并且 len 小于出发顶点到 j 顶点的距离,就需要更新if (!vv.in(j) && len < vv.getDis(j)) {vv.updatePre(j, index); // 更新 j 顶点的前驱为 index 顶点vv.updateDis(j, len); // 更新出发顶点到 j 顶点的距离}}}
}// 已访问顶点集合
class VisitedVertex {// 记录各个顶点是否访问过 1 表示访问过,0 表示未访问,会动态更新private int[] already_arr;// 每个下标对应的值为前一个顶点下标,会动态更新private int[] pre_visited;// 记录出发顶点到其他所有顶点的距离,比如 G 为出发顶点,就会记录 G 到其他顶点的距离,会动态更新,求的最短距离就会存放到 disprivate int[] dis;/*** 构造器初始化** @param length 表示顶点的个数* @param index  出发顶点对应的下标*/public VisitedVertex(int length, int index) {this.already_arr = new int[length];this.pre_visited = new int[length];this.dis = new int[length];// 初始化 disArrays.fill(dis, 65535);this.already_arr[index] = 1; // 设置出发顶点被访问过this.dis[index] = 0; // 设置出发顶点的访问距离为 0}/*** 判断 index 顶点是否被访问过** @param index 顶点下标* @return 如果访问过,就返回 true,否则 返回 false*/public boolean in(int index) {return already_arr[index] == 1;}/*** 更新出发顶点得到 index 顶点的距离** @param index 顶点下标* @param len   长度(距离)*/public void updateDis(int index, int len) {dis[index] = len;}/*** 更新 pre 顶点的前驱顶点为 index 顶点** @param pre   要更新的顶点* @param index 跟新顶点*/public void updatePre(int pre, int index) {pre_visited[pre] = index;}/*** 返回出发顶点到 index 顶点的距离** @param index 顶点*/public int getDis(int index) {return dis[index];}/*** 继续选择并返回新的访问顶点** @return*/public int updateArr() {int min = 65535, index = 0;for (int i = 0; i < already_arr.length; i++) {if (already_arr[i] == 0 && dis[i] < min) {min = dis[i];index = i;}}// 更新 index 顶点被访问过already_arr[index] = 1;return index;}/*** 显示最后的结果* 即将三个数组的情况输出*/public void show() {System.out.println("=======================================");// 输出 already_arrfor (int i : already_arr) {System.out.print(i + " ");}System.out.println();// 输出 pre_visitedfor (int i : pre_visited) {System.out.print(i + " ");}System.out.println();// 输出 disfor (int i : dis) {System.out.print(i + " ");}System.out.println();char[] vertex = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};int count = 0;for (int i : dis) {if (i != 65535) {System.out.print(vertex[count] + "(" + i + ") ");} else {System.out.println("N ");}count++;}}
}

相关文章:

【数据结构与算法】迪杰斯特拉算法

迪杰斯特拉算法 介绍 迪杰斯特拉&#xff08;Dijkstra&#xff09;算法是典型最短路径算法&#xff0c;用于计算一个节点到其他节点的最短路径。它的主要特点是以中心向外层层扩展&#xff08;广度优先搜索思想&#xff09;&#xff0c;直到扩展到终点为止。 算法过程 设置…...

python爬虫-网页数据提取

import requests #headers 网页右键->Network->最下面的User-Agent复制。 headers {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36"} #你想要的网址 url &q…...

ZigBee的Many-to-One和Source Routing

1. Many-to-One Routing Many-to-One Routing&#xff0c;是一种简单的路由机制&#xff0c;使得整个网络中的路由设备拥有回到中心节点的路由。 在这种机制下&#xff0c;中心节点周期性发送Many-to-One route discovery广播&#xff08;协议栈默认设置为60s&#xff0c;可以…...

七夕节 Chinese Valentine‘s Day 的由来

农历七月初七是七夕节。Qixi Festival falls on the seventh day of the seventh lunar month. 以前有一个牛郎&#xff0c;和他的哥哥和嫂子住在一起。他放的一头牛曾经是天庭的一个神仙&#xff0c;但他违反天庭的戒律&#xff0c;变成牛放到了人间。As the story goes,once …...

掌握JDK21全新结构化并发编程,轻松提升开发效率!

1 概要 通过引入结构化并发编程的API&#xff0c;简化并发编程。结构化并发将在不同线程中运行的相关任务组视为单个工作单元&#xff0c;从而简化错误处理和取消操作&#xff0c;提高可靠性&#xff0c;并增强可观察性。这是一个预览版的API。 2 历史 结构化并发是由JEP 42…...

【SA8295P 源码分析】00 - 系列文章链接汇总 - 持续更新中

【SA8295P 源码分析】00 - 系列文章链接汇总 - 持续更新中 一、分区、下载、GPIO等杂项相关二、开机启动流程代码分析二、OpenWFD 显示屏模块三、Touch Panel 触摸屏模块四、QUPv3 及 QNX Host透传配置五、Camera 摄像头模块&#xff08;当前正在更新中...&#xff09;六、网络…...

TCP拥塞控制详解 | 6. 主动队列管理

网络传输问题本质上是对网络资源的共享和复用问题&#xff0c;因此拥塞控制是网络工程领域的核心问题之一&#xff0c;并且随着互联网和数据中心流量的爆炸式增长&#xff0c;相关算法和机制出现了很多创新&#xff0c;本系列是免费电子书《TCP Congestion Control: A Systems …...

前端学习清单

顺序不分先后。 技术名称技术描述技术链接HTML5HTML5是下一代的HTML标准&#xff0c;是一种用于结构化内容的标记语言。MDN|HTMLCSS3CSS3是CSS技术的升级版本&#xff0c;它的最大好处就是可以让网页设计师更加方便的为网页添加各种各样的样式&#xff0c;而不用再局限于文字、…...

go atomic原子操作详细解读

文章目录 概要1、基本知识1.1 原子操作是什么1.2 CPU怎么实现原子操作的&#xff1f; 2、atomic包2.1、 Add函数2.2、CompareAndSwap函数2.3、Swap函数2.4、Load函数2.5、Store函数 3、atomic.Value值 概要 atomic包是golang通过对底层系统支持的原子操作进行封装&#xff0c;…...

Vue用JSEncrypt对长文本json加密以及发现解密失败

哈喽 大家好啊&#xff0c;最近发现进行加密后 超长文本后端解密失败&#xff0c;经过看其他博主修改 JSEncrypt原生代码如下&#xff1a; // 分段加密&#xff0c;支持中文JSEncrypt.prototype.encryptUnicodeLong function (string) {var k this.getKey();//根据key所能编…...

Excel/PowerPoint折线图从Y轴开始(两侧不留空隙)

默认Excel/PowerPoint折线图是这个样子的&#xff1a; 左右两侧都留了大块空白&#xff0c;很难看 解决方案 点击横坐标&#xff0c;双击&#xff0c;然后按下图顺序点击 效果...

C++的类成员对齐

这是个小语法点&#xff0c;之前我们的对齐方式都是使用#pragma pack&#xff0c;这个方式实际是依赖编译器&#xff0c;且粒度粗(如果#pragma pack(1)之后没有#pragma pack(),那就作用整个进程了)。在C11之后引入关键字alignas&#xff0c;以此来实现对齐更加便利&#xff0c;…...

敏感挂载userhelper容器逃逸复现

目录 前言 分析 实验 前言 分析 实验 # Creates a payload cat "#!/bin/sh" > /evil-helper cat "ps > /output" >> /evil-helper chmod x /evil-helper # Finds path of OverlayFS mount for container # Unless the configuration ex…...

深度解读Promise.prototype.finally

由一个问题引发的血案&#xff1a; 手写源码实现Promise.prototype.finally。 我们知道&#xff0c;对于promise来讲&#xff0c;当状态敲定&#xff0c;无论状态兑现或拒绝时都需要调用的函数&#xff0c;可以使用Promise.prototype.finally的回调来实现。那么如何手写实现Pro…...

如何实现24/7客户服务自动化?建设智能客服知识库

客户自助服务是指用户通过企业或者第三方建立的网络平台或者终端&#xff0c;实现相关的自定义处理。实现客户服务自动化&#xff0c;对提高客户满意度、维持客户关系至关重要。客户服务自动化可以帮助企业以更快的速度和更高的效率来满足客户的售后服务要求&#xff0c;以进一…...

和鲸 ModelWhale 与中科可控多款服务器完成适配认证,赋能中国云生态

当前世界正处于新一轮技术革命及传统产业数字化转型的关键期&#xff0c;云计算作为重要的技术底座&#xff0c;其产业发展与产业规模对我国数字经济的高质量运行有着不可取代的推动作用。而随着我国数字上云、企业上云加快进入常规化阶段&#xff0c;云计算承载的业务应用越来…...

selenium +Jmeter 的性能测试

通过Jmeter快速将已有的Selenium 代码以性能测试的方式组织起来&#xff0c;并使用JMeter 丰富的报表展示测试结果 from selenium import webdriver from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By driver …...

探索高效的HTTP异步接口测试方法:从轮询等待到自动化方案

本文将深入探讨HTTP异步接口测试的多个方面&#xff0c;包括轮询等待、性能测试以及自动化方案。通过详细的解释和实际案例&#xff0c;帮助您了解如何有效地测试异步接口&#xff0c;确保系统的稳定性和性能。 在现代软件开发中&#xff0c;HTTP异步接口扮演着至关重要的角色&…...

Android资深工程书之LiveData核心组件原理剖析

LiveData是Android架构组件库中的一个类&#xff0c;用于在应用程序组件之间共享数据。它是一种可观察的数据持有者&#xff0c;可以感知应用程序组件的生命周期&#xff0c;并在数据发生变化时通知观察者。 使用LiveData 在Android应用程序中使用LiveData&#xff0c;你可以…...

Vue的五种方法实现加减乘除运算

五种方法的详细说明&#xff1a; 计算属性&#xff08;Computed Properties&#xff09;&#xff1a; 计算属性是Vue.js提供的一种便捷的属性&#xff0c;它根据依赖的数据动态计算出一个新的值。计算属性的值会被缓存&#xff0c;只有当依赖的数据发生变化时&#xff0c;才会…...

超短脉冲激光自聚焦效应

前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应&#xff0c;这是一种非线性光学现象&#xff0c;主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场&#xff0c;对材料产生非线性响应&#xff0c;可能…...

Flask RESTful 示例

目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题&#xff1a; 下面创建一个简单的Flask RESTful API示例。首先&#xff0c;我们需要创建环境&#xff0c;安装必要的依赖&#xff0c;然后…...

FastAPI 教程:从入门到实践

FastAPI 是一个现代、快速&#xff08;高性能&#xff09;的 Web 框架&#xff0c;用于构建 API&#xff0c;支持 Python 3.6。它基于标准 Python 类型提示&#xff0c;易于学习且功能强大。以下是一个完整的 FastAPI 入门教程&#xff0c;涵盖从环境搭建到创建并运行一个简单的…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

uniapp手机号一键登录保姆级教程(包含前端和后端)

目录 前置条件创建uniapp项目并关联uniClound云空间开启一键登录模块并开通一键登录服务编写云函数并上传部署获取手机号流程(第一种) 前端直接调用云函数获取手机号&#xff08;第三种&#xff09;后台调用云函数获取手机号 错误码常见问题 前置条件 手机安装有sim卡手机开启…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

在 Spring Boot 项目里,MYSQL中json类型字段使用

前言&#xff1a; 因为程序特殊需求导致&#xff0c;需要mysql数据库存储json类型数据&#xff0c;因此记录一下使用流程 1.java实体中新增字段 private List<User> users 2.增加mybatis-plus注解 TableField(typeHandler FastjsonTypeHandler.class) private Lis…...