0

0

C# A*寻路算法方法 C#如何实现A Star算法

畫卷琴夢

畫卷琴夢

发布时间:2026-02-13 07:19:25

|

517人浏览过

|

来源于php中文网

原创

直接套用网上c# a*代码常失败,主因是node未重写equals/gethashcode、启发式与移动规则不匹配、误用list.sort模拟优先队列;应改用.net 6+ priorityqueue并确保f值稳定排序,闭合列表依规模选bool[,]或hashset,路径回溯需正确绑定parent且逆序处理。

c# a*寻路算法方法 c#如何实现a star算法

为什么直接套用网上A*代码在C#里常跑不通

多数公开的C# A*实现默认假设地图是二维整数网格、节点可自由上下左右移动,且忽略障碍物表示方式差异。实际项目中,GridNode 类可能没重写 EqualsGetHashCode,导致 HashSet 或优先队列反复插入重复节点;更常见的是启发式函数(heuristic)用了欧氏距离但没开根号,而代价函数(g-cost)却按曼哈顿步数累加,造成估价不一致,A*退化为低效Dijkstra。

  • 务必确认你的 Node 类对 Equals / GetHashCode 的实现与坐标唯一性严格对应(比如只基于 XY 字段)
  • 启发式函数必须满足「可接纳性」:即 h(n) ≤ 实际最小代价到目标;对 4 向移动,用曼哈顿距离;8 向则建议用切比雪夫距离:Math.Max(Math.Abs(a.X - b.X), Math.Abs(a.Y - b.Y))
  • 别用 List<t>.Sort()</t> 模拟优先队列——插入和取最小值都是 O(n),改用 SortedSet<t></t>(需自定义 IComparer)或第三方库如 PriorityQueue<telement tpriority></telement>(.NET 6+)

如何用.NET 6+ PriorityQueue 正确构造开放列表

PriorityQueue 要求每个元素绑定一个可比较的优先级值,不能直接把 f = g + h 当作泛型参数类型传入。常见错误是试图塞入 (node, f) 元组却不提供稳定排序逻辑,导致相同 f 值时节点被误判为重复。

  • 优先级类型必须是数值(如 floatdouble),且相等时需靠第二排序键避免歧义;推荐封装为 struct PriorityQueueItem : IComparable<priorityqueueitem></priorityqueueitem>,内部包含 NodeFInsertOrder(递增计数器)
  • 不要在循环中反复调用 Enqueue(node, f) 后又用 TryDequeue(out var node, out var priority) ——这会破坏堆结构;应始终用 TryDequeue 取出最小项,再用 Contains(需额外维护 HashSet)判断是否已访问
  • 开放列表只需存节点引用,所有代价计算(g/h/f)应在入队前完成并作为优先级传入;别在队列里缓存或复算

闭合列表用 HashSet 还是 bool[,]?看地图规模

小地图(如 ≤ 100×100)用二维布尔数组 bool[,] closed 最快,索引即坐标,O(1) 查找;大地图或稀疏障碍(如开放世界场景)用 HashSet<node></node> 更省内存,但要注意 NodeGetHashCode 必须只依赖坐标,且不可变。

醒蓝AI
醒蓝AI

一键快速生成Al形象照、证件照、写真照的强大AI换脸软件

下载
  • 若用 HashSet<node></node>,确保 Node 是不可变结构体或类中 X/Y 为只读字段;否则修改坐标后哈希码变化,节点再也找不到
  • 若用 bool[,] closed,注意数组索引越界检查必须前置,尤其当起点/终点坐标超出预分配范围时,直接抛 IndexOutOfRangeException
  • 闭合列表只标记「已完全探索过该节点」,不是「已入队」——后者属于开放列表职责;两者不可混用

路径回溯失败的三个隐蔽原因

算法返回「无路径」或路径点顺序颠倒,往往不是逻辑错,而是父节点指针链断裂。最典型的是:每次生成邻居节点时,新建了 new Node(x, y),但没把当前节点设为它的 Parent,或设了却在后续覆盖。

  • 邻居节点对象必须复用已有实例(如从 nodePool[x, y] 获取),或确保新建时立即绑定 parentvar neighbor = new Node(x, y) { Parent = currentNode }
  • 回溯时用 while (node != null) 而非 while (node.Parent != null),否则漏掉起点自身
  • 返回路径前务必 path.Reverse()(如果从终点往起点收集),否则得到的是逆序坐标流

实际调试时,先打印前 5 个出队节点的 (X,Y,f,g,h),确认 g 单调递增、f 大致下降;再检查闭合列表大小是否随步数线性增长——异常膨胀说明重复入队。A* 的正确性不难验证,难的是让它在你自己的数据结构上不悄悄绕弯。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
css中float用法
css中float用法

css中float属性允许元素脱离文档流并沿其父元素边缘排列,用于创建并排列、对齐文本图像、浮动菜单边栏和重叠元素。想了解更多float的相关内容,可以阅读本专题下面的文章。

587

2024.04.28

C++中int、float和double的区别
C++中int、float和double的区别

本专题整合了c++中int和double的区别,阅读专题下面的文章了解更多详细内容。

104

2025.10.23

c语言中null和NULL的区别
c语言中null和NULL的区别

c语言中null和NULL的区别是:null是C语言中的一个宏定义,通常用来表示一个空指针,可以用于初始化指针变量,或者在条件语句中判断指针是否为空;NULL是C语言中的一个预定义常量,通常用来表示一个空值,用于表示一个空的指针、空的指针数组或者空的结构体指针。

244

2023.09.22

java中null的用法
java中null的用法

在Java中,null表示一个引用类型的变量不指向任何对象。可以将null赋值给任何引用类型的变量,包括类、接口、数组、字符串等。想了解更多null的相关内容,可以阅读本专题下面的文章。

706

2024.03.01

sort排序函数用法
sort排序函数用法

sort排序函数的用法:1、对列表进行排序,默认情况下,sort函数按升序排序,因此最终输出的结果是按从小到大的顺序排列的;2、对元组进行排序,默认情况下,sort函数按元素的大小进行排序,因此最终输出的结果是按从小到大的顺序排列的;3、对字典进行排序,由于字典是无序的,因此排序后的结果仍然是原来的字典,使用一个lambda表达式作为key参数的值,用于指定排序的依据。

399

2023.09.04

while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

102

2023.09.25

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

322

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

198

2025.07.04

pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

23

2026.02.13

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
C# 教程
C# 教程

共94课时 | 9.3万人学习

C 教程
C 教程

共75课时 | 4.7万人学习

C++教程
C++教程

共115课时 | 17.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号