A*算法(A-Star Algorithm)详解

A*算法(A-Star Algorithm)详解

A*算法(A-Star Algorithm)是一种启发式搜索算法,广泛应用于路径规划(如游戏寻路、机器人导航)、图遍历等领域。它通过结合实际代价启发式估计代价,在保证找到最优路径的同时,显著减少搜索范围,效率远高于传统的Dijkstra算法或贪心搜索。

在这里插入图片描述

一、核心思想:评估函数f(n)

A*算法的核心是定义一个评估函数,用于优先扩展“最有希望”到达目标的节点。该函数表示为:
f(n)=g(n)+h(n) f(n) = g(n) + h(n) f(n)=g(n)+h(n)

  • g(n):从起点(Start)到当前节点 nnn 的实际代价(已消耗的代价)。例如,在网格地图中,若每一步移动代价为1,则 g(n)g(n)g(n) 是起点到 nnn 的步数。
  • h(n):从当前节点 nnn 到目标节点(Goal)的估计代价(启发式预测)。它是算法的“智能”来源,需满足可采纳性(Admissible)——即不高估实际代价(否则可能错过最优解)。
  • f(n):节点 nnn 的总代价估计,指导搜索方向(优先扩展 f(n)f(n)f(n) 最小的节点)。
在这里插入图片描述

二、算法步骤

A*算法的执行流程可概括为以下步骤:

1. 初始化数据结构
  • 开放列表(Open List):优先队列(最小堆),存储待扩展的节点,按 f(n)f(n)f(n) 排序(fff 最小的节点在顶部)。初始时仅包含起点。
  • 关闭列表(Closed List):集合或哈希表,存储已扩展过的节点(避免重复处理)。初始为空。
  • 代价记录:维护两个字典(或数组),分别记录每个节点的 g(n)g(n)g(n)(实际代价)和 f(n)f(n)f(n)(总代价)。
2. 主循环:扩展节点

重复以下步骤直到找到目标或开放列表为空(无路径):

  • 步骤1:从开放列表中取出 f(n)f(n)f(n) 最小的节点 nnn(称为当前节点)。
  • 步骤2:若 nnn 是目标节点,回溯路径并返回结果(算法结束)。
  • 步骤3:将 nnn 加入关闭列表(标记为已处理)。
  • 步骤4:遍历 nnn 的所有邻居节点 mmm(上下左右、对角线等,取决于移动规则):
    • 若 mmm 在关闭列表中:跳过(已处理过更优路径)。
    • 计算临时 ggg 值:temp_g=g(n)+从n到m的移动代价temp\_g = g(n) + \text{从}n\text{到}m\text{的移动代价}temp_g=g(n)+从n到m的移动代价(如相邻节点代价为1,对角线为√2)。
    • 若 mmm 不在开放列表中,或 temp_g<g(m)temp\_g < g(m)temp_g<g(m)(发现更优路径):
      • 更新 g(m)=temp_gg(m) = temp\_gg(m)=temp_g。
      • 计算 h(m)h(m)h(m)(启发式估计值)。
      • 计算 f(m)=g(m)+h(m)f(m) = g(m) + h(m)f(m)=g(m)+h(m)。

若 mmm 不在开放列表中,将其加入开放列表;否则,更新其在开放列表中的优先级(因 f(m)f(m)f(m) 可能变小)。

在这里插入图片描述
3. 路径回溯

当目标节点被取出开放列表时,从目标节点反向回溯父节点(扩展时记录每个节点的父节点),直到回到起点,得到完整路径。

三、关键:启发函数h(n)的选择

h(n)h(n)h(n) 的选择直接影响算法效率和最优性。需满足可采纳性(不高估实际代价),常见类型如下:

1. 曼哈顿距离(Manhattan Distance)

适用于四方向移动(上下左右)的网格地图:
h(n)=∣xn−xgoal∣+∣yn−ygoal∣ h(n) = |x_n - x_{goal}| + |y_n - y_{goal}| h(n)=∣xn​−xgoal​∣+∣yn​−ygoal​∣
其中 (xn,yn)(x_n, y_n)(xn​,yn​) 是当前节点坐标,(xgoal,ygoal)(x_{goal}, y_{goal})(xgoal​,ygoal​) 是目标坐标。

2. 欧几里得距离(Euclidean Distance)

适用于八方向移动(允许对角线)的场景:
h(n)=(xn−xgoal)2+(yn−ygoal)2 h(n) = \sqrt{(x_n - x_{goal})^2 + (y_n - y_{goal})^2} h(n)=(xn​−xgoal​)2+(yn​−ygoal​)2​

3. 切比雪夫距离(Chebyshev Distance)

适用于八方向移动且允许斜向一步到位的情况(如国际象棋中的王):
h(n)=max⁡(∣xn−xgoal∣,∣yn−ygoal∣) h(n) = \max(|x_n - x_{goal}|, |y_n - y_{goal}|) h(n)=max(∣xn​−xgoal​∣,∣yn​−ygoal​∣)

4. 其他变种

根据具体问题设计专用启发函数(如路径规划中的预计算代价图)。

四、特性分析

  • 最优性:若 h(n)h(n)h(n) 可采纳(不高估),A* 一定能找到最短路径(前提是所有边的代价非负)。
  • 完备性:若存在路径且图有限,A* 最终会找到路径;若不存在路径,开放列表会为空。
  • 效率:启发函数 h(n)h(n)h(n) 越接近实际代价(但不超过),开放列表扩展的节点越少,效率越高。例如,当 h(n)h(n)h(n) 等于实际代价(仅目标节点的 h=0h=0h=0),A* 退化为Dijkstra算法(全局搜索);当 h(n)h(n)h(n) 强启发(如目标明确时的直线距离),搜索范围大幅缩小。
在这里插入图片描述

五、应用场景

  • 游戏开发:NPC角色寻路(如《魔兽世界》《英雄联盟》)。
  • 机器人导航:自动驾驶中的局部路径规划。
  • 地图服务:GPS导航中的实时路径计算(结合实时交通数据调整代价)。

六、示例:网格地图寻路

假设一个4x4网格(起点(0,0),终点(3,3)),四方向移动,每步代价为1。

  1. 初始化:开放列表包含起点(0,0),g=0g=0g=0,h=∣0−3∣+∣0−3∣=6h=|0-3|+|0-3|=6h=∣0−3∣+∣0−3∣=6,f=6f=6f=6。
  2. 第一次扩展:取出(0,0),扩展邻居(0,1)、(1,0)。计算它们的 g=1g=1g=1,hhh 分别为 ∣0−3∣+∣1−3∣=5|0-3|+|1-3|=5∣0−3∣+∣1−3∣=5(f=6f=6f=6)和 ∣1−3∣+∣0−3∣=5|1-3|+|0-3|=5∣1−3∣+∣0−3∣=5(f=6f=6f=6),加入开放列表。
  3. 后续扩展:每次选择 fff 最小的节点(初始阶段多个节点 f=6f=6f=6),逐步向终点逼近。最终当终点(3,3)被取出时,回溯路径为:(0,0)→(1,0)→(2,0)→(3,0)→(3,1)→(3,2)→(3,3)(或其他等价最短路径)。

总结

A*算法通过平衡实际代价与启发式估计,在路径规划中实现了“高效+最优”的双重优势。理解其核心评估函数、数据结构(开放/关闭列表)及启发函数的选择,是掌握该算法的关键。实际应用中,需根据场景调整启发函数,以在效率和最优性之间取得平衡。

在这里插入图片描述

用生活场景解释A*算法

要理解A算法,咱们可以用一个生活中找路的场景来打比方——就像你在陌生的小区里找朋友家,手里有一张地图(网格或道路图),需要最快找到目的地。A算法就是帮你“聪明选路”的小助手,它会一边算你已经走了多远(实际代价),一边猜剩下的路大概还要走多远(预估代价),最终带你走最快的那条路。

一、核心思路:用“总代价”决定先走哪条路

假设你现在在起点(比如小区门口),目标是朋友家(终点)。A*算法的关键是给每个“可能经过的点”(比如路上的每个路口、格子)算一个总代价分数,分数越低,说明这条路“越值得先走”。这个总分数由两部分组成:

  • g(n):你已经走了多远(实际代价)。比如从起点到当前点,你走了300米(或3步),g(n)=300。
  • h(n):你猜还要走多远(预估代价)。比如当前点离终点看起来还有200米(或2步),h(n)=200(但不能乱猜,得“靠谱”)。

总分数 f(n) = g(n) + h(n),相当于“从起点到终点经过这里的总步数/总距离”。A*算法会优先走f(n)最小的点——就像你会优先选“已经走了100米+还剩100米=总共200米”的路,而不是“已经走了200米+还剩300米=总共500米”的路。

二、具体怎么操作?像“整理待选清单”一样找路

A*算法的过程可以想象成你拿着一张“待选清单”(开放列表)和一张“已检查清单”(关闭列表),一步步缩小范围:

1. 开始:把起点放进待选清单

一开始,你只知道起点,所以待选清单里只有起点,它的g=0(还没走),h是你猜的起点到终点的距离(比如直线距离),f=g+h。

2. 循环:每次从待选清单里挑“最划算”的点

每次从待选清单里找出f(n)最小的点(也就是“最值得走”的点),把它从待选清单移到已检查清单(表示你已经认真考虑过这个点了)。

3. 检查是否到终点

如果这个点刚好是终点,恭喜!你已经找到路了,接下来只需要“倒推”回去,就能得到完整路径(比如:终点←上一步←再上一步←…←起点)。

4. 扩展邻居:看看周围有哪些路可选

如果还没到终点,你需要看看当前点的“邻居”(比如上下左右四个方向的路口,或者对角线的路口,取决于你能怎么走)。对每个邻居:

  • 如果邻居已经在已检查清单(你之前已经仔细看过这个点,而且当时的路线更优),跳过它(不用再浪费时间)。
  • 如果邻居不在待选清单,或者你找到了一条去邻居的“更短实际路径”(比如之前算过去邻居要走500米,现在发现走另一条路只要400米),就更新它的g(n)(实际走了多远),重新算f(n)=g(n)+h(n),然后把它放进待选清单。

三、关键:“猜得靠谱”才能找得快

A*算法好不好用,关键看你怎么“猜”h(n)(剩下的路有多远)。这个“猜测”必须满足一个条件:不能高估实际距离(比如实际要走200米,你不能猜300米)。否则,算法可能会漏掉真正的最短路径。

举个例子:

  • 如果你在走直角的网格路(比如只能上下左右走,不能斜着走),最靠谱的h(n)是“曼哈顿距离”——横竖两边的步数加起来。比如当前点在(2,3),终点在(5,7),那么横向需要走5-2=3步,纵向需要走7-3=4步,h(n)=3+4=7(实际可能需要更多步,但绝不会更少)。
  • 如果你可以斜着走(比如八方向移动),h(n)可以用“欧几里得距离”——直接算两点之间的直线距离(比如√[(5-2)²+(7-3)²]≈5),这比曼哈顿距离更接近实际步数。

四、为什么A*比“笨办法”好?

传统方法比如Dijkstra算法,相当于“盲目”地从起点开始,把所有可能的路都展开,直到找到终点(像撒网捕鱼)。而A*算法因为有h(n)的“聪明猜测”,会优先展开那些“看起来离终点更近”的点(像瞄准目标撒网),所以找路更快,计算量更小

总结:A*算法的本质

A*算法就像一个“聪明的导航员”:

  • 它知道你已经走了多远(g(n)),也知道大概还要走多远(h(n)),从而选出“总代价最小”的路。
  • 它不会乱猜(h(n)不吹牛),所以最终一定能找到最短路径(如果存在的话)。
  • 生活中,它能在游戏里帮角色快速找路、在导航软件里帮你避开拥堵(调整h(n)为实时路况),非常实用!

Read more

内存暴涨700%背后的惊天真相:AI正在吞噬一切!能源·隐私·绿色三大维度深度拆解

内存暴涨700%背后的惊天真相:AI正在吞噬一切!能源·隐私·绿色三大维度深度拆解

🔥作者简介: 一个平凡而乐于分享的小比特,中南民族大学通信工程专业研究生,研究方向无线联邦学习 🎬擅长领域:驱动开发,嵌入式软件开发,BSP开发 ❄️作者主页:一个平凡而乐于分享的小比特的个人主页 ✨收录专栏:未来思考,本专栏结合当前国家战略和实时政治,对未来行业发展的思考 欢迎大家点赞 👍 收藏 ⭐ 加关注哦!💖💖 🔥内存暴涨700%背后的惊天真相:AI正在吞噬一切!能源·隐私·绿色三大维度深度拆解 |前言| 最近装机的小伙伴们欲哭无泪:DDR5内存价格一路狂飙,部分DRAM现货价格在过去一年暴涨近700% 。大家习惯性吐槽“厂商放火”、“产能不足”,但很少有人看到,这场涨价风暴的真正推手,是那只名为“AI”的巨兽。 当你还在为多花几百块钱买内存心疼时,国家正在西部荒漠建起一座座数据中心,科技巨头正在为“吃电怪兽”抢购每一颗芯片。2026年,大型科技公司的AI相关投资预计将达到6500亿美元,较去年增长约80% 。 今天,我们从能源供应、隐私安全、绿色AI 三个维度,结合东数西算、算电协同、

By Ne0inhk
C#AI系列:从零开始打造自己的OpenClaw

C#AI系列:从零开始打造自己的OpenClaw

OpenLum.Console 项目说明 这个项目是参考OpenClaw的CSharp版控制台智能体助手,Aot发布后主体程序7mb大小,另外的Skills文件夹目前自带了浏览器操作、office文件读取等基础工具。 用户可自行动态扩展Skills(描述提供地址及操作方式后,即可学会各种技能,比如登录到公司网络报销发票、请假考勤等。注意:部分网站的DOM可能不易交互导致失败) 基于 .NET 的通用智能体 Shell,原生 AOT 发布、零第三方依赖。 面向本地/内网部署,支持 OpenAI API 兼容的各类模型(DeepSeek、Ollama、OpenAI 等)。 浏览器搜索信息获取操作 自带规划拉取信息、创建工具、完成任务(pdf文档生成) 技能的按需加载示例 全部开源免费,新朋友可以关注公众号“萤火初芒”回复"OpenLum"获取仓库地址,有问题可留言或私信作者。让我们一起探索 AI 助手的无限可能!

By Ne0inhk
AI的提示词专栏:Instruction Tuning 与自定义指令集

AI的提示词专栏:Instruction Tuning 与自定义指令集

AI的提示词专栏:Instruction Tuning 与自定义指令集 本文围绕 Instruction Tuning(指令微调)与自定义指令集展开深入解析,先阐释 Instruction Tuning 的定义、与传统 Prompt 调优的区别及核心价值,指出其通过 “指令 - 响应” 对训练让模型从通用文本生成转向精准执行任务,解决传统 Prompt 调优痛点。接着详解自定义指令集的构成要素与设计原则,给出多领域示例。随后介绍 Instruction Tuning 从数据准备、模型选择、微调训练、效果评估到部署应用的完整实施流程,结合电商客服场景实战案例说明落地要点。还针对数据不足、过拟合等常见问题提供解决方案,最后总结核心内容并展望自动指令集生成等未来趋势,为相关实践提供全面指导。 人工智能专栏介绍     人工智能学习合集专栏是 AI 学习者的实用工具。它像一个全面的 AI 知识库,把提示词设计、AI 创作、智能绘图等多个细分领域的知识整合起来。无论你是刚接触

By Ne0inhk
Flutter 组件 google_generative_language_api 适配鸿蒙 HarmonyOS 实战:生成式 AI 集成,构建大语言模型调度与全场景智能推理治理架构

Flutter 组件 google_generative_language_api 适配鸿蒙 HarmonyOS 实战:生成式 AI 集成,构建大语言模型调度与全场景智能推理治理架构

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.ZEEKLOG.net Flutter 组件 google_generative_language_api 适配鸿蒙 HarmonyOS 实战:生成式 AI 集成,构建大语言模型调度与全场景智能推理治理架构 前言 在鸿蒙(OpenHarmony)生态迈向全场景 AI 赋能、涉及高效的语义理解、自动化内容生成及严苛的端云协同智能隐私保护背景下,如何实现一套既能深度对接 Google 生成式语言模型(如 Gemini、PaLM)、又能保障异步请求高响应性且具备多模态输入处理能力的“AI 调度中枢”,已成为决定应用智能化水平与用户体验代差的关键。在鸿蒙设备这类强调分布式协同与端侧算力按需分配的环境下,如果应用依然采用低效的 REST 手写拼接,由于由于 payload 结构复杂性,极易由于由于“协议解析异常”导致鸿蒙应用在大模型推理环节发生由于由于由于由于通讯阻塞。 我们需要一种能够统一模型调用语义、支持流式(Streaming)响应且符合鸿蒙异步异步并发范式的

By Ne0inhk