0

0

C++怎么实现A*寻路算法_C++游戏路径规划【AI】

冰火之心

冰火之心

发布时间:2026-03-07 00:09:21

|

698人浏览过

|

来源于php中文网

原创

能跑通的astar类需确保状态不重复扩展且启发函数不过度乐观:用std::priority_queue按f=g+h排序,曼哈顿或欧氏距离作h,首次弹出才标记访问,h与移动代价单位一致(如均放大100倍防浮点误差)。

c++怎么实现a*寻路算法_c++游戏路径规划【ai】

怎么写一个能跑通的 AStar 类,不卡死不绕路

核心是状态不重复扩展 + 启发函数不过度乐观。很多人写出来要么无限循环,要么路径明显绕远,问题通常出在开放列表没用堆优化、或 heuristic 返回负值/不满足三角不等式。

  • std::priority_queue 存开放节点,排序依据必须是 f = g + h,不能只按 hg
  • heuristic 推荐用曼哈顿距离(网格)或欧氏距离(自由空间),避免用 abs(x1-x2) * abs(y1-y2) 这类非单调的
  • 每个节点首次从开放列表弹出时才算“已访问”,不是第一次加入时就标记 —— 否则会漏掉更优路径
  • 示例关键判断:
    if (new_g < node.g) { node.g = new_g; node.f = node.g + heuristic(node, goal); update_in_open_list(node); }

为什么 std::priority_queue 不能直接改内部元素

因为 std::priority_queue 没有提供降低键(decrease-key)接口,而 A* 需要动态更新已入队节点的 f 值。硬改会导致堆结构错乱,后续弹出顺序错误,路径变长甚至死锁。

  • 常见错误:用 std::vector 手动找节点再 std::make_heap —— 时间复杂度退化到 O(N),1000 个节点就明显卡顿
  • 实用解法:允许同一节点多次入队,但每次从队列弹出时先检查是否已被处理(用 closed_setvisited 标记)
  • 代价是内存略增,但代码简洁、不易出错,对中小规模地图(

网格地图里怎么定义 get_neighbors 才不出边界或撞墙

不是所有相邻坐标都合法。直接写 {x±1, y}, {x, y±1} 然后靠 is_walkable 过滤,效率低且容易漏判对角线移动规则。

小羊标书
小羊标书

一键生成百页标书,让投标更简单高效

下载
  • 先生成所有可能位移向量(如四连通用 {{1,0},{0,1},{-1,0},{0,-1}},八连通加 {{1,1},{1,-1},{-1,1},{-1,-1}}
  • 对每个位移做两步检查:!is_out_of_bounds(new_x, new_y)grid[new_y][new_x] != WALL(注意 y 在前,数组索引别反)
  • 如果支持对角线,记得把对角线移动代价设为 1.414(或 14 整数化),否则算法会倾向绕行

调试时看到 std::priority_queue 弹出顺序不对怎么办

大概率是自定义比较函数逻辑反了。C++ 的 std::priority_queue 默认是大顶堆,而我们需要最小 f 值优先,所以比较器必须返回 true 当 a 应该排在 b 后面(即 a > b)。

立即学习C++免费学习笔记(深入)”;

  • 错误写法:auto cmp = [](const Node& a, const Node& b) { return a.f → 实际建的是最大堆
  • 正确写法:auto cmp = [](const Node& a, const Node& b) { return a.f > b.f; };
  • 验证方法:插入三个不同 f 值节点,连续 top() + pop(),看是否从小到大输出
  • 别依赖打印整个队列 —— std::priority_queue 不提供遍历接口,所谓“打印”往往只是底层容器快照,不反映真实堆序

A* 表面是算法题,实际是状态管理 + 容器行为 + 浮点与整数权衡的组合问题。最容易被忽略的是:启发函数和移动代价必须用同一套单位,比如都用整数放大 100 倍,否则浮点精度会让相等判断失效,导致节点重复处理或漏更新。

热门AI工具

更多
DeepSeek
DeepSeek

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

豆包大模型
豆包大模型

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

通义千问
通义千问

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

腾讯元宝
腾讯元宝

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

文心一言
文心一言

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

讯飞写作
讯飞写作

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

即梦AI
即梦AI

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

ChatGPT
ChatGPT

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

相关专题

更多
c语言const用法
c语言const用法

const是关键字,可以用于声明常量、函数参数中的const修饰符、const修饰函数返回值、const修饰指针。详细介绍:1、声明常量,const关键字可用于声明常量,常量的值在程序运行期间不可修改,常量可以是基本数据类型,如整数、浮点数、字符等,也可是自定义的数据类型;2、函数参数中的const修饰符,const关键字可用于函数的参数中,表示该参数在函数内部不可修改等等。

558

2023.09.20

硬盘接口类型介绍
硬盘接口类型介绍

硬盘接口类型有IDE、SATA、SCSI、Fibre Channel、USB、eSATA、mSATA、PCIe等等。详细介绍:1、IDE接口是一种并行接口,主要用于连接硬盘和光驱等设备,它主要有两种类型:ATA和ATAPI,IDE接口已经逐渐被SATA接口;2、SATA接口是一种串行接口,相较于IDE接口,它具有更高的传输速度、更低的功耗和更小的体积;3、SCSI接口等等。

1846

2023.10.19

PHP接口编写教程
PHP接口编写教程

本专题整合了PHP接口编写教程,阅读专题下面的文章了解更多详细内容。

614

2025.10.17

php8.4实现接口限流的教程
php8.4实现接口限流的教程

PHP8.4本身不内置限流功能,需借助Redis(令牌桶)或Swoole(漏桶)实现;文件锁因I/O瓶颈、无跨机共享、秒级精度等缺陷不适用高并发场景。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

2351

2025.12.29

java接口相关教程
java接口相关教程

本专题整合了java接口相关内容,阅读专题下面的文章了解更多详细内容。

45

2026.01.19

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

434

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

600

2023.08.10

页面置换算法
页面置换算法

页面置换算法是操作系统中用来决定在内存中哪些页面应该被换出以便为新的页面提供空间的算法。本专题为大家提供页面置换算法的相关文章,大家可以免费体验。

489

2023.08.14

JavaScript浏览器渲染机制与前端性能优化实践
JavaScript浏览器渲染机制与前端性能优化实践

本专题围绕 JavaScript 在浏览器中的执行与渲染机制展开,系统讲解 DOM 构建、CSSOM 解析、重排与重绘原理,以及关键渲染路径优化方法。内容涵盖事件循环机制、异步任务调度、资源加载优化、代码拆分与懒加载等性能优化策略。通过真实前端项目案例,帮助开发者理解浏览器底层工作原理,并掌握提升网页加载速度与交互体验的实用技巧。

1

2026.03.06

热门下载

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

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
10分钟--Midjourney创作自己的漫画
10分钟--Midjourney创作自己的漫画

共1课时 | 0.1万人学习

Midjourney 关键词系列整合
Midjourney 关键词系列整合

共13课时 | 0.9万人学习

AI绘画教程
AI绘画教程

共2课时 | 0.2万人学习

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

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