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

最短路径问题

如图,设定源点为D,终点为A,则D到A的最短路径是多少?

 算法思路:

第一步,从源点D出发,此时能到达的选择是C和E,我们根据路径长度选择最少的作为下一个节点,于是选择C,

第二步,到达C后,标记C已经走过了,后续再做选择时,排除C。然后将所有C能到达的节点告知D,也就是B、F、E。由D来分辨,B、F、E这些点,是通过C节点路最短,还是D现有方案最短。选择最短的方案记录下来。然后选择B、F、E中C节点最近的、没标记过的节点作为下一步。

第三步,重复第二步操作,直到选不到下一个节点而结束。

考虑特殊的情况,假如图不是闭环的,这个方式可能会被引导在断路的地方停止。于是记录走过的路,当找不到路的时候,确认end没有找到,且还有节点没被标记的情况下,退回上一个路口。

(1)如果节点都被标记或者已经找到终点了,就退出

(2)如果还有节点未被标记可以回退上一次选择的地方继续选择。

最后直接询问源节点D中对于终点A的方案是什么,最短路径是多少。

代码:

封装图中的节点

   class Node {String name;//当前节点名称Map<String, Integer> path = new HashMap<>();//目标节点->最短路径public Node(String name) { this.name = name; }/*** 更新到达某个节点的最短路径* @param name 目标节点* @param len 最短路径*/public void update(String name, int len) {path.put(name, len);}/*** 获取指定节点的最短路径* @param name 目标节点* @return 最短路径*/public int getLen(String name) {return path.getOrDefault(name, Integer.MAX_VALUE);}}

用到全局变量存储信息,方法里传递这些也行,就是不好看

Map<String, Node> map = new HashMap<>();//节点对象map
Map<String, Boolean> sign = new HashMap<>();//节点标记
List<String> list = new ArrayList<>();//记录走的路径,处理碰到死路的情况,可以退上一个节点

初始化代码,将图上的数据跑入节点对象中。

Object[][] params = {{"A", "B", 12},{"A", "F", 16},{"A", "G", 14},{"B", "F", 7},{"B", "C", 10},{"C", "F", 6},{"C", "E", 5},{"C", "D", 3},{"D", "E", 4},{"E", "F", 2},{"E", "G", 8},{"F", "G", 9}
};
//导入路径数据
for(Object[] p:params){if(!map.containsKey((String)p[0]))map.put((String)p[0],new Node((String) p[0]));if(!map.containsKey((String)p[1]))map.put((String)p[1],new Node((String) p[1]));map.get((String)p[0]).update((String)p[1],(int)p[2]);map.get((String)p[1]).update((String)p[0],(int)p[2]);
}

开始算法

    /*** 选择它下面最小路径出发,更新自己到达最近节点位置** @param name*/boolean f(String name, Node start, String end) {Node now = map.get(name);//获取节点实体sign.put(name, true);//标记已经走过了list.add(name);/*** 更新源节点对能到达节点的最短路径,当前节点是源节点的时候不用更新*/if (!name.equals(start.name)) {int nowLen = start.getLen(name);//取出源节点到当前节点的最短路径,用于后续计算for (String key : now.path.keySet()) {//取出当前节点能直达的所有节点if (!key.equals(start.name)) {//将当前节点到达每一个节点的路径信息告知给到源节点,让源节点扩充自己的最短路径数据int newNodeLen = now.getLen(key) + nowLen;//源节点到新节点的路径长度if (start.getLen(key) > newNodeLen) { //源节点取出原有方案,对比,保留最短的方案start.update(key, newNodeLen);map.get(key).update(start.name, newNodeLen);//路径双方都更新}}}}String nextName = getNextName(now,end);if (nextName == null) return true;return f(nextName, start, end);}

里面涉及到选择最近节点的方法以及包含死路的时候回退操作,

    /*** 获取下一个路径节点* @param now* @param end* @return*/public static String getNextName(Node now,String end){String nextName = null;int min = Integer.MAX_VALUE;for (String key : now.path.keySet()) {if (sign.containsKey(key) && sign.get(key)) continue;if (now.getLen(key) < min) {min = now.getLen(key);nextName = key;}}if (nextName == null) {if (sign.containsKey(end) && sign.get(end)) return null;}else{return nextName;}list.remove(list.size()-1);return getNextName(map.get(list.get(list.size()-1)),end);}

最后使用上面这些东西

String start="D";//源节点
String end="A";//目标节点
f(start, map.get(start), end);
System.out.println(map.get(start).getLen(end));

无脑完整代码:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class Main {public static Map<String, Node> map = new HashMap<>();//节点信息public static Map<String, Boolean> sign = new HashMap<>();//防止重复计算public static List<String> list = new ArrayList<>();//记录走的路径,处理碰到死路的情况,可以退上一个节点public static void main(String[] args) {init();//初始化数据String start = "D";//源节点String end = "A";//目标节点f(start, map.get(start), end);//算法寻找System.out.println(map.get(start).getLen(end));//拿出来始终节点的最短路径}/*** 初始化数据*/public static void init(){Object[][] params = {{"A", "B", 12},{"A", "F", 16},{"A", "G", 14},{"B", "F", 7},{"B", "C", 10},{"C", "F", 6},{"C", "E", 5},{"C", "D", 3},{"D", "E", 4},{"E", "F", 2},{"E", "G", 8},{"F", "G", 9}};//导入路径数据for (Object[] p : params) {if (!map.containsKey((String) p[0])) map.put((String) p[0], new Node((String) p[0]));if (!map.containsKey((String) p[1])) map.put((String) p[1], new Node((String) p[1]));map.get((String) p[0]).update((String) p[1], (int) p[2]);map.get((String) p[1]).update((String) p[0], (int) p[2]);}}/*** 选择它下面最小路径出发,更新自己到达最近节点位置** @param name*/public static boolean f(String name, Node start, String end) {Node now = map.get(name);//获取节点实体sign.put(name, true);//标记已经走过了list.add(name);/*** 更新源节点对能到达节点的最短路径,当前节点是源节点的时候不用更新*/if (!name.equals(start.name)) {int nowLen = start.getLen(name);//取出源节点到当前节点的最短路径,用于后续计算for (String key : now.path.keySet()) {//取出当前节点能直达的所有节点if (!key.equals(start.name)) {//将当前节点到达每一个节点的路径信息告知给到源节点,让源节点扩充自己的最短路径数据int newNodeLen = now.getLen(key) + nowLen;//源节点到新节点的路径长度if (start.getLen(key) > newNodeLen) { //源节点取出原有方案,对比,保留最短的方案start.update(key, newNodeLen);map.get(key).update(start.name, newNodeLen);//路径双方都更新}}}}String nextName = getNextName(now,end);if (nextName == null) return true;return f(nextName, start, end);}/*** 获取下一个路径节点* @param now* @param end* @return*/public static String getNextName(Node now,String end){String nextName = null;int min = Integer.MAX_VALUE;for (String key : now.path.keySet()) {if (sign.containsKey(key) && sign.get(key)) continue;if (now.getLen(key) < min) {min = now.getLen(key);nextName = key;}}if (nextName == null) {if (sign.containsKey(end) && sign.get(end)) return null;}else{return nextName;}list.remove(list.size()-1);return getNextName(map.get(list.get(list.size()-1)),end);}
}
class Node {String name;//当前节点名称Map<String, Integer> path = new HashMap<>();//目标节点->最短路径public Node(String name) {this.name = name;}/*** 更新到达某个节点的最短路径** @param name 目标节点* @param len  最短路径*/public void update(String name, int len) {path.put(name, len);}/*** 获取指定节点的最短路径** @param name 目标节点* @return 最短路径*/public int getLen(String name) {return path.getOrDefault(name, Integer.MAX_VALUE);}
}

相关文章:

最短路径问题

如图&#xff0c;设定源点为D&#xff0c;终点为A&#xff0c;则D到A的最短路径是多少&#xff1f; 算法思路&#xff1a; 第一步&#xff0c;从源点D出发&#xff0c;此时能到达的选择是C和E&#xff0c;我们根据路径长度选择最少的作为下一个节点&#xff0c;于是选择C&…...

国内有哪些SAAS软件?SAAS软件有哪些优点?

国内有哪些SAAS软件&#xff1f;SAAS软件有哪些优点&#xff1f;不请自来答一下&#xff0c;通过SaaS软件与传统软件的对比来详细讲下SaaS软件有哪些优点&#xff1f; 配合以下内容食用更佳&#xff1a; 关于概念——深度详解什么是SaaS&#xff08;软件即服务&#xff09;关…...

分享两组不同的3D VR卡片

最近某音上出现了很多VR视频&#xff0c;转动手机可以看到手机界面未显示出来的场景。这种事情我觉得我们也可以做到。 所以两种不同的3D VR卡片来了&#xff1a; 第一种是横向或上下可以拖动极大的距离。卡片上的信息会随着拖动移动&#xff0c;但不会显示更多的信息&#x…...

外贸人如何精准开发客户?Facebook开发客户全攻略

现在做跨境的都了解的一个社媒平台就是Facebook了&#xff0c;因为很多人都会拿Facebook来开发客户&#xff0c;忙里偷闲&#xff0c;今天东哥就来聊聊用Facebook开发客户的一些心得。 用Facebook开发客户的心得 1、利用关键词搜索 使用行业相关的关键词、产品特定的关键词、相…...

一、Git安装(Git+TortoiseGit图形化)

Git 是一个开源的分布式版本控制系统&#xff0c;用于敏捷高效地处理任何或小或大的项目。 Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 Git 与常用的版本控制工具 CVS, Subversion 等不同&#xff0c;它采用了分布式版本库的方式…...

mysql死锁,如何产生?如何发现?如何处理?

1 产生死锁 就是资源互斥 例子如下 好的&#xff0c;请参考以下 SQL 语句来创建 base_account_item 表和向表中插入一些数据&#xff1a; CREATE TABLE base_account_item (id INT(11) NOT NULL,account_item_name VARCHAR(50) NOT NULL,PRIMARY KEY (id) ) ENGINEInnoDB DEF…...

YOLO V1-V3 简单介绍

目录 1. YOLO 2. YOLO V1 3. YOLO V2 4. YOLO V3 5. YOLO V3 SPP网络 5.1 Mosaic 图像增强 5.2 SPP 模块 5.3 CIou Loss 5.4 Focal loss 1. YOLO YOLO 是目标检测任务强大的算法&#xff0c;将目标检测的问题转换边界框和相关概率的回归问题&#xff0c;是目标检测…...

数据结构总结1:了解数据结构、时间复杂度、空间复杂度

后续可能会有补充和更改 目录 一、数据结构 1.算法介绍 二、时间复杂度、空间复杂度 三、练习 1.时间复杂度 2.空间复杂度 一、数据结构 数据结构是计算机存储、组织数据的方式&#xff0c;指相互之间存在一种或多种特定关系的数据元素的集合。 数据结构和数据库的区…...

abstract class和interface有什么区别?

含有abstract修饰符的class即为抽象类&#xff0c;abstract 类不能创建的实例对象。含有abstract方法的类必须定义为abstract class&#xff0c;abstract class类中的方法不必是抽象的。abstract class类中定义抽象方法必须在具体(Concrete)子类中实现&#xff0c;所以&#xf…...

Kafka在Java项目中的应用

Kafka在Java项目中的应用 Docker 安装Kafka 一.首先需要安装docker,可看这篇文章安装docker 二.拉取zookeeper和KafKa镜像 docker pull wurstmeister/zookeeperdocker pull wurstmeister/kafkaKafka组件需要向zookeeper进行注册,所以也需要安装zookeeper 三.启动zookeeper…...

理解分布式id生成算法SnowFlake

理解分布式id生成算法SnowFlake 分布式id生成算法的有很多种&#xff0c;Twitter的SnowFlake就是其中经典的一种。 概述 SnowFlake算法生成id的结果是一个64bit大小的整数&#xff0c;它的结构如下图&#xff1a; } public function __construct(){ $this->rnew…...

光纤收发器可以连接光模块吗?

随着科技的进步发展&#xff0c;城市信息化速度的加快&#xff0c;光通信产品在数据中心和安防监控等场景中的运用越来越广泛&#xff0c;而这之间的连接则需要光模块和光纤收发器来实现。很多用户对光模块和光纤收发器的使用有些疑虑&#xff0c;两者该如何连接&#xff1f;又…...

一文快速了解浏览器Sui Explorer

Sui作为一条基于第一原理重新设计和构建而成的L1公链&#xff0c;所有区块和交易信息皆公开透明&#xff0c;每个人都能自行查看。通过Sui链上浏览器&#xff0c;用户可以迅速了解链上的交易情况&#xff0c;比如当前的TPS和Gas价格&#xff0c;也可以使用Digest来查看特定交易…...

python中lambda、yield、map、filter、reduce的使用

1、 匿名函数lambda python中允许使用lambda关键字定义一个匿名函数。所谓的匿名函数就是说使用一次或者几次之后就不再需要的函数&#xff0c;属于“一次性”函数。 #例1&#xff1a;求两数之和 f lambda x, y: x y print(f(5, 1))#例2&#xff1a;求平方和 print((lambda…...

第十八章 使用LNMP架构部署动态网站环境

文章目录 第十八章 使用LNMP架构部署动态网站环境一、源码包程序1、源码包的优势2、基本步骤&#xff08;1&#xff09;、下载及解压源码包文件&#xff08;2&#xff09;、编译源码包代码&#xff08;3&#xff09;、生成二进制安装程序&#xff08;4&#xff09;、运行二进制…...

无人值守的IDC机房动环综合运维方案

企业数字化转型以及5G、物联网、云计算、人工智能等新业态带动了数据中心的发展&#xff0c;在国家一体化大数据中心及“东数西算”节点布局的推动下&#xff0c;数据中心机房已成为各大企事业单位维持业务正常运营的重要组成部分&#xff0c;网络设备、系统、业务应用数量与日…...

桌面远程工具推荐

目前市面上的远程工具多如牛毛&#xff0c;很多人不知道怎么选择&#xff0c;下面小编介绍两种桌面远程工具&#xff0c;它们都是跨平台的&#xff0c;均支持Windows&#xff0c;Mac OS&#xff0c;IOS和安卓&#xff0c;分别是RayLink&#xff0c;VNC&#xff0c;好用&#xf…...

MySQL高级——第15章_锁

第15章_锁 1. 概述 锁是计算机协调多个进程或线程并发访问某一资源的机制。在程序开发中会存在多线程同步的问题&#xff0c;当多个线程并发访问某个数据的时候&#xff0c;尤其是针对一-些敏感的数据(比如订单、金额等)&#xff0c;我们就需要保证这个数据在任何 时刻最多只…...

【ROS】Ubuntu22.04安装ROS2(Humble Hawksbill)

0、版本说明 Ubuntu22.04对应的ROS2的版本为Humble Hawksbill&#xff08;ros-humble&#xff09; 如果不是在Ubuntu22.04中安装ROS&#xff0c;请参考下面Ubuntu和ROS的版本对应关系 1、更新apt包列表 $ sudo apt update2、设置编码 将ubuntu环境语言编码设置为en_US en_…...

【ChatGPT】体验一下ChatGPT

体验一下ChatGPT 可以帮你写代码、写邮件、编故事的神器 最近OpenAI 发布了备受期待的原型通用 ChatGPT&#xff0c;这是一种基于对话的 AI 聊天界面&#xff0c;算是GPT-3(Generative Pre-trained Transformer 3)的继承者&#xff0c;今天记录一下体验的过程&#xff0c;以前…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性&#xff0c;不同版本的Docker对内核版本有不同要求。例如&#xff0c;Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本&#xff0c;Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

解决本地部署 SmolVLM2 大语言模型运行 flash-attn 报错

出现的问题 安装 flash-attn 会一直卡在 build 那一步或者运行报错 解决办法 是因为你安装的 flash-attn 版本没有对应上&#xff0c;所以报错&#xff0c;到 https://github.com/Dao-AILab/flash-attention/releases 下载对应版本&#xff0c;cu、torch、cp 的版本一定要对…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测;从基础到高级,涵盖ArcGIS数据处理、ENVI遥感解译与CLUE模型情景模拟等

&#x1f50d; 土地利用/土地覆盖数据是生态、环境和气象等诸多领域模型的关键输入参数。通过遥感影像解译技术&#xff0c;可以精准获取历史或当前任何一个区域的土地利用/土地覆盖情况。这些数据不仅能够用于评估区域生态环境的变化趋势&#xff0c;还能有效评价重大生态工程…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化

缓存架构 代码结构 代码详情 功能点&#xff1a; 多级缓存&#xff0c;先查本地缓存&#xff0c;再查Redis&#xff0c;最后才查数据库热点数据重建逻辑使用分布式锁&#xff0c;二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

Modbus RTU与Modbus TCP详解指南

目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...

Python网页自动化Selenium中文文档

1. 安装 1.1. 安装 Selenium Python bindings 提供了一个简单的API&#xff0c;让你使用Selenium WebDriver来编写功能/校验测试。 通过Selenium Python的API&#xff0c;你可以非常直观的使用Selenium WebDriver的所有功能。 Selenium Python bindings 使用非常简洁方便的A…...

验证redis数据结构

一、功能验证 1.验证redis的数据结构&#xff08;如字符串、列表、哈希、集合、有序集合等&#xff09;是否按照预期工作。 2、常见的数据结构验证方法&#xff1a; ①字符串&#xff08;string&#xff09; 测试基本操作 set、get、incr、decr 验证字符串的长度和内容是否正…...