游戏AI实现-寻路算法(Dijkstra)
戴克斯特拉算法(英语:Dijkstra's algorithm),又称迪杰斯特拉算法、Dijkstra算法,是由荷兰计算机科学家艾兹赫尔·戴克斯特拉在1956年发现的算法。
算法过程:
1.首先设置开始节点的成本值为0,并将开始节点放入检测列表中。
2.将检测列表中的所有点按到目标点所需的成本值排序,选择成本最小的节点作为当前节点,并将其移出检测列表。
3.将当前点周围的点中不包含在检测列表中的点加入到检测列表,将周围点加入到已检测列表中。
4.更新检测列表中的节点到当前节点的成本值。
5.重复2,3,4直到找到目标点。
代码实现:
public class Dijkstra : FindPathAlgorithm
{public Dijkstra(int[,] mapData, int xCount, int zCount) : base(mapData, xCount, zCount){}public override List<Vector2Int> FindPath(Vector2Int startPos, Vector2Int goalPos){DataNode dataNode = this.DijkstraFind(startPos, goalPos);if (dataNode == null){Debug.LogError("寻路有误,请检查参数是否正确");return null;}return Utils.GetPath(dataNode);}DataNode DijkstraFind(Vector2Int startPos, Vector2Int goalPos){//存储要检测的点List<DataNode> frontier = new List<DataNode>();//存储已经检测的点List<Vector2Int> reached = new List<Vector2Int>();DataNode startNode = new DataNode(startPos, null);startNode.gCost = 0;frontier.Add(startNode);reached.Add(startPos);while (frontier.Count > 0){DataNode currentNode = GetLowestgCostNode(frontier);frontier.Remove(currentNode);if (currentNode.pos == goalPos){Debug.Log("完成!!!");return new DataNode(goalPos, currentNode.parent);}List<DataNode> neighbors = GetNeighbors(currentNode.pos, reached);foreach (DataNode neighbourNode in neighbors){if (!frontier.Contains(neighbourNode)){neighbourNode.parent = currentNode;frontier.Add(neighbourNode);}reached.Add(neighbourNode.pos);}this.UpdateCost(frontier, currentNode);}return null;}//更新成本值void UpdateCost(List<DataNode> nodes, DataNode currentNode){for (int i = 0; i < nodes.Count; i++){int newCost = currentNode.gCost + CalculateDistanceCost(nodes[i].pos, currentNode.pos);if (nodes[i].gCost > newCost){nodes[i].gCost = newCost;}}}List<DataNode> GetNeighbors(Vector2Int current, List<Vector2Int> reached){List<DataNode> neighbors = new List<DataNode>();for (int i = 0; i < Utils.pointDir.Count; i++){Vector2Int neighbor = current + Utils.pointDir[i];if (this.IsCanAdd(neighbor, reached)){neighbors.Add(new DataNode(neighbor, null));}}return neighbors;}bool IsCanAdd(Vector2Int current, List<Vector2Int> reached){if (reached.Contains(current))return false;if (current.x >= 0 && current.y >= 0 && current.x < MapData.m_MapData.GetLength(1) && current.y < MapData.m_MapData.GetLength(0)){//如果是障碍物,则不能被Addif (MapData.m_MapData[current.y, current.x] == 1){return false;}return true;}return false;}private int CalculateDistanceCost(Vector2Int a, Vector2Int b){return Mathf.Abs(a.x - b.x) + Mathf.Abs(a.y - b.y);}private DataNode GetLowestgCostNode(List<DataNode> pathNodeList){DataNode lowestFCostNode = pathNodeList[0];for (int i = 1; i < pathNodeList.Count; i++){if (pathNodeList[i].gCost < lowestFCostNode.gCost){lowestFCostNode = pathNodeList[i];}}return lowestFCostNode;}
}
结果:

参考链接:
Pathfinding in Unity - Part3: Dijkstra Algorithm Theory (youtube.com)
Pathfinding in Unity - Part4: Dijkstra Algorithm Implementation (youtube.com)
How Dijkstra's Algorithm Works (youtube.com)
戴克斯特拉算法 - 维基百科,自由的百科全书 (wikipedia.org)
相关文章:
游戏AI实现-寻路算法(Dijkstra)
戴克斯特拉算法(英语:Dijkstras algorithm),又称迪杰斯特拉算法、Dijkstra算法,是由荷兰计算机科学家艾兹赫尔戴克斯特拉在1956年发现的算法。 算法过程: 1.首先设置开始节点的成本值为0,并将…...
Android OpenGLES2.0开发(九):图片滤镜
“当你改变想法的时候,记得也要改变你的世界。”——诺曼文森特皮尔 Android OpenGLES开发:EGL环境搭建Android OpenGLES2.0开发(一):艰难的开始Android OpenGLES2.0开发(二):环境搭…...
SQLite Update 语句
SQLite Update 语句 SQLite 的 UPDATE 语句用于更新数据库表中的现有记录。使用 UPDATE 语句,您可以修改一个或多个列的值。本教程将详细介绍如何使用 SQLite UPDATE 语句,包括语法、示例以及一些最佳实践。 语法 SQLite UPDATE 语句的基本语法如下&a…...
Metaploit-永恒之蓝漏洞利用
1:Metaploit介绍 本次测试主要是利用永恒之蓝漏洞对windows7进行控制利用,掌握Metaploit工具的使用,知道永恒之蓝的漏洞利用原理。永恒之蓝是在Windows的SMB服务处理SMB v1请求时发生的漏洞,这个漏洞导致攻击者在目标系统上可…...
机器学习预处理-表格数据的空值处理
机器学习预处理-表格数据的空值处理 机器学习预处理-表格数据的分析与可视化中详细介绍了表格数据的python可视化,可视化能够帮助我们了解数据的构成和分布,是我们进行机器学习的必备步骤。上文中也提及,原始的数据存在部分的缺失࿰…...
数据结构_平衡二叉树
结点类 构造函数分为有参和无参,相同点都是初始化树高为1 class Node { public:int data; // 用于输出int val; // 数据域,用于排序int height; // 树高Node* left;Node* right;Node();Node(int v, int d);static int max(int a, int b); };Node::N…...
C++对象的赋值与复制复制构造函数(指针数据成员)
一、对象的赋值 同类对象之间可以相互赋值,对象赋值的一般形式:对象名2 对象名1; 原理是,赋值运算符的重载。仅赋值,因此赋值前,需要先定义并初始化对象2。 对象的赋值针对指对象中所有数据成员的值; 对…...
Coding Caprice - monotonic stack2
42. 接雨水 class Solution { public:int trap(vector<int>& height) {stack<int> sh;int out 0;for(int i0; i<height.size(); i){while(!sh.empty() && height[sh.top()]<height[i]){int bo height[sh.top()];sh.pop();if(sh.empty()){brea…...
Spring Mvc面试题(常见)
1 Spring MVC的执行流程 用户发起请求,请求先被Servlet拦截以后,转发给SpringMVC框架SpringMVC 里面的DispatcherServlet(核心控制器) 接收到请求,并转发给HandlerMappingHandlerMapping负责解析请求,根据请求信息和配置信息找到匹配的Controller类(当这里有配置拦截器,会…...
opencv # Sobel算子、Laplacian算子、Canny边缘检测、findContours、drawContours绘制轮廓、外接矩形
一、Sobel算子 案例图片 cv2.Sobel(src, ddepth, dx, dy, ksize3, scale1, delta0, borderTypeNone) 功能:用于计算图像梯度(gradient)的函数 参数: src: 输入图像,它应该是灰度图像。 ddepth: 输出图像的所需深度&am…...
Neo4j插入数据逐级提升速度4倍又4倍
语雀版:https://www.yuque.com/xw76/back/dtukgqfkfwg1d6yo 目录 背景介绍初始方案Node()创建事务批量提交记录Node是否存在生成Cypher语句执行数据库参数优化切换成85k个三元组测试建索引(很显著!!!)MATCH…...
C++特殊类设计(单例模式等)
目录 引言 1.请设计一个类,不能被拷贝 2. 请设计一个类,只能在堆上创建对象 为什么设置实例的方法为静态成员呢 3. 请设计一个类,只能在栈上创建对象 4. 请设计一个类,不能被继承 5. 请设计一个类,只能创建一个对…...
J8学习打卡笔记
🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 Inception v1算法实战与解析 导入数据数据预处理划分数据集搭建模型训练模型正式训练结果可视化详细网络结构图个人总结 import os, PIL, random, pathlib imp…...
前端学习-操作元素内容(二十二)
目录 前言 目标 对象.innerText 属性 对象.innerHTML属性 案例 年会抽奖 需求 方法一 方法二 总结 前言 曾经沧海难为水,除却巫山不是云。 目标 能够修改元素的文本更换内容 DOM对象都是根据标签生成的,所以操作标签,本质上就是操作DOM对象,…...
【踩坑】pip离线+在线在虚拟环境中安装指定版本cudnn攻略
pip离线在线在虚拟环境中安装指定版本cudnn攻略 在线安装离线安装Windows环境:Linux环境: 清华源官方帮助文档 https://mirrors.tuna.tsinghua.edu.cn/help/pypi/ 标题的离线的意思是先下载whl文件再安装到虚拟环境,在线的意思是直接在当前虚…...
golang操作sqlite3加速本地结构化数据查询
目录 摘要Sqlite3SQLite 命令SQLite 语法SQLite 数据类型列亲和类型——优先选择机制 SQLite 创建数据库SQLite 附加数据库SQLite 分离数据库 SQLite 创建表SQLite 删除表 SQLite Insert 语句SQLite Select 语句SQLite 运算符SQLite 算术运算符SQLite 比较运算符SQLite 逻辑运算…...
vllm加速(以Qwen2.5-7B-instruction为例)与流式响应
1. vllm介绍 什么是vllm? vLLM 是一个高性能的大型语言模型推理引擎,采用创新的内存管理和执行架构,显著提升了大模型推理的速度和效率。它支持高度并发的请求处理,能够同时服务数千名用户,并且兼容多种深度学习框架,…...
WordPress弹窗公告插件-ts小陈
使用效果 使用后网站所有页面弹出窗口 插件特色功能 设置弹窗公告样式:这款插件可展示弹窗样式公告,用户点击完之后不再弹出,不会频繁打扰用户。可设置弹窗中间的logo图:这款插件针对公告图片进行独立设置,你可以在设…...
【ELK】容器化部署Elasticsearch1.14.3集群【亲测可用】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1. 部署1.1 单节点1.2 新节点加入集群1.3 docker-compose部署集群 1. 部署 按照官网流程进行部署 使用 Docker 安装 Elasticsearch |Elasticsearch 指南 [8.14] |…...
[SAP ABAP] ALV状态栏GUI STATUS的快速创建
使用事务码SE38进入到指定程序,点击"显示对象列表"按钮 鼠标右键,选择"GUI状态" 弹出【创建状态】窗口,填写状态以及短文本描述以后,点击按钮 点击"调整模板",复制已有程序的状态栏 填…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
《通信之道——从微积分到 5G》读书总结
第1章 绪 论 1.1 这是一本什么样的书 通信技术,说到底就是数学。 那些最基础、最本质的部分。 1.2 什么是通信 通信 发送方 接收方 承载信息的信号 解调出其中承载的信息 信息在发送方那里被加工成信号(调制) 把信息从信号中抽取出来&am…...
Spring AI 入门:Java 开发者的生成式 AI 实践之路
一、Spring AI 简介 在人工智能技术快速迭代的今天,Spring AI 作为 Spring 生态系统的新生力量,正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务(如 OpenAI、Anthropic)的无缝对接&…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
python报错No module named ‘tensorflow.keras‘
是由于不同版本的tensorflow下的keras所在的路径不同,结合所安装的tensorflow的目录结构修改from语句即可。 原语句: from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后: from tensorflow.python.keras.lay…...
