news 2026/5/13 1:36:33

最优路径-A*算法(A-Star)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
最优路径-A*算法(A-Star)

A*算法(A-Star)

算法概述

A* 算法(A-Star Algorithm)是由Peter Hart、Nils Nilsson和Bertram Raphael于1968年提出的一种启发式搜索算法,用于在状态空间中寻找从起始状态到目标状态的最优路径。A* 算法结合了广度优先搜索的完备性和启发式搜索的效率,在路径规划、游戏AI等领域有广泛应用。

算法原理

A*算法的核心思想是通过评估函数来指导搜索方向,平衡已探索路径的成本和预估剩余路径的成本:

  1. 评估函数f(n)=g(n)+h(n)f(n) = g(n) + h(n)f(n)=g(n)+h(n)
  2. 已知成本g(n)g(n)g(n)表示从起始节点到当前节点nnn的实际成本
  3. 启发式成本h(n)h(n)h(n)表示从当前节点nnn到目标节点的预估成本
  4. 优先级选择:每次选择f(n)f(n)f(n)值最小的节点进行扩展

算法步骤

  1. 初始化

    • 将起始节点加入开放列表(open list)
    • 设置起始节点的g(n)=0g(n) = 0g(n)=0h(n)h(n)h(n)为启发式估计值
    • 创建关闭列表(closed list)记录已访问节点
  2. 循环处理

    • 从开放列表中取出f(n)f(n)f(n)值最小的节点
    • 如果该节点是目标节点,则路径找到,算法结束
    • 将该节点移入关闭列表
    • 对该节点的所有邻居进行扩展
  3. 邻居扩展

    • 对于每个邻居节点:
      • 如果邻居在关闭列表中,跳过
      • 计算新的ggg值:gnew=g(current)+cost(current,neighbor)g_{new} = g(current) + cost(current, neighbor)gnew=g(current)+cost(current,neighbor)
      • 如果邻居不在开放列表中或新的ggg值更小:
        • 更新邻居的ggg值和fff
        • 设置邻居的前驱节点为当前节点
        • 如果邻居不在开放列表中,将其加入

数学表达

G=(V,E)G = (V, E)G=(V,E)为一个带权图,其中:

  • VVV是顶点集合
  • EEE是边集合
  • w(u,v)w(u, v)w(u,v)表示边(u,v)(u, v)(u,v)的权重

A*算法维护以下数据结构:

  • g(n)g(n)g(n):从起始节点到节点nnn的实际成本
  • h(n)h(n)h(n):从节点nnn到目标节点的启发式估计成本
  • f(n)=g(n)+h(n)f(n) = g(n) + h(n)f(n)=g(n)+h(n):节点的评估函数值

算法的搜索过程满足:
f(n)=g(n)+h(n)≤g∗(n)+h∗(n)f(n) = g(n) + h(n) \leq g^*(n) + h^*(n)f(n)=g(n)+h(n)g(n)+h(n)
其中g∗(n)g^*(n)g(n)是从起始节点到节点nnn的最优成本,h∗(n)h^*(n)h(n)是从节点nnn到目标节点的最优成本。

时间复杂度

  • 最坏情况时间复杂度O(bd)O(b^d)O(bd)
  • 平均时间复杂度:取决于启发式函数的质量
  • 空间复杂度O(bd)O(b^d)O(bd)

其中:

  • bbb是分支因子
  • ddd是解的深度

算法特点

优点

  1. 能够找到最优解(在满足启发式条件的情况下)
  2. 搜索效率高,避免不必要的探索
  3. 可以通过调整启发式函数控制搜索行为
  4. 广泛应用于路径规划问题

缺点

  1. 需要设计合适的启发式函数
  2. 在最坏情况下可能需要大量内存
  3. 对于某些问题可能陷入局部最优
  4. 启发式函数的设计可能很复杂

应用场景

  1. 游戏AI:角色移动路径规划
  2. 导航系统:地图导航和路线规划
  3. 机器人路径规划:机器人运动轨迹规划
  4. 网络路由:网络数据包路由选择
  5. 自动寻路:各种自动寻路应用

伪代码

function AStar(start, goal, heuristic): open_list ← new PriorityQueue() closed_list ← new Set() // 初始化起始节点 start.g ← 0 start.h ← heuristic(start, goal) start.f ← start.g + start.h start.parent ← null open_list.add(start) while open_list is not empty: current ← open_list.remove() if current == goal: return reconstruct_path(current) closed_list.add(current) for each neighbor of current: if neighbor in closed_list: continue tentative_g ← current.g + cost(current, neighbor) if neighbor not in open_list or tentative_g < neighbor.g: neighbor.parent ← current neighbor.g ← tentative_g neighbor.h ← heuristic(neighbor, goal) neighbor.f ← neighbor.g + neighbor.h if neighbor not in open_list: open_list.add(neighbor) return failure

实现示例

Python实现

importheapqclassNode:def__init__(self,position,parent=None):self.position=position self.parent=parent self.g=0# 从起始节点到当前节点的实际成本self.h=0# 从当前节点到目标节点的启发式成本self.f=0# 总评估成本def__lt__(self,other):returnself.f<other.fdefa_star(grid,start,end,heuristic):""" A*算法实现 :param grid: 二维网格,0表示可通行,1表示障碍 :param start: 起始位置 (x, y) :param end: 目标位置 (x, y) :param heuristic: 启发式函数 :return: 最短路径列表 """# 创建起始节点和目标节点start_node=Node(start)end_node=Node(end)# 初始化开放列表和关闭列表open_list=[]closed_list=set()# 将起始节点加入开放列表heapq.heappush(open_list,start_node)whileopen_list:# 取出f值最小的节点current_node=heapq.heappop(open_list)closed_list.add(current_node.position)# 如果到达目标节点,重构路径ifcurrent_node.position==end_node.position:path=[]current=current_nodewhilecurrent:path.append(current.position)current=current.parentreturnpath[::-1]# 生成邻居节点neighbors=[]fordirectionin[(0,1),(1,0),(0,-1),(-1,0),(1,1),(-1,-1),(1,-1),(-1,1)]:neighbor_pos=(current_node.position[0]+direction[0],current_node.position[1]+direction[1])# 检查邻居是否在网格内且可通行if(0<=neighbor_pos[0]<len(grid)and0<=neighbor_pos[1]<len(grid[0])andgrid[neighbor_pos[0]][neighbor_pos[1]]==0):neighbors.append(Node(neighbor_pos,current_node))# 处理邻居节点forneighborinneighbors:ifneighbor.positioninclosed_list:continue# 计算g值ifabs(neighbor.position[0]-current_node.position[0])+abs(neighbor.position[1]-current_node.position[1])==2:# 对角线移动,成本为√2neighbor.g=current_node.g+1.414else:# 水平/垂直移动,成本为1neighbor.g=current_node.g+1# 计算h值和f值neighbor.h=heuristic(neighbor.position,end_node.position)neighbor.f=neighbor.g+neighbor.h# 检查是否在开放列表中且g值更小in_open=Falseforopen_nodeinopen_list:ifopen_node.position==neighbor.positionandopen_node.g<=neighbor.g:in_open=Truebreakifnotin_open:heapq.heappush(open_list,neighbor)return[]# 没有找到路径

启发式函数

defmanhattan_distance(pos1,pos2):"""曼哈顿距离(适用于四方向移动)"""returnabs(pos1[0]-pos2[0])+abs(pos1[1]-pos2[1])defeuclidean_distance(pos1,pos2):"""欧几里得距离(适用于八方向移动)"""return((pos1[0]-pos2[0])**2+(pos1[1]-pos2[1])**2)**0.5defchebyshev_distance(pos1,pos2):"""切比雪夫距离(适用于棋盘移动)"""returnmax(abs(pos1[0]-pos2[0]),abs(pos1[1]-pos2[1]))defdiagonal_distance(pos1,pos2):"""对角线距离(适用于八方向移动)"""dx=abs(pos1[0]-pos2[0])dy=abs(pos1[1]-pos2[1])returnmax(dx,dy)+(1.414-1)*min(dx,dy)

算法分析

启发式函数的性质

为了确保A*算法找到最优解,启发式函数h(n)h(n)h(n)应该满足以下条件:

  1. 可容性(Admissibility)h(n)≤h∗(n)h(n) \leq h^*(n)h(n)h(n),即启发式估计值不超过实际最优值
  2. 一致性(Consistency)h(n)≤w(u,v)+h(v)h(n) \leq w(u, v) + h(v)h(n)w(u,v)+h(v),对于所有节点u,vu, vu,v

常见的启发式函数:

  • 曼哈顿距离:适用于四方向移动的网格
  • 欧几里得距离:适用于八方向移动的网格
  • 切比雪夫距离:适用于棋盘移动

与其他算法的比较

特性A*DijkstraBFS
最优解保证是(在满足启发式条件时)
搜索效率高(取决于启发式)中等
内存使用较高中等较高
适用场景有明确目标的路径规划单源最短路径无权图最短路径
实现复杂度较复杂简单简单

优化策略

  1. 双向A*:从起点和终点同时进行搜索
  2. 跳点搜索(Jump Point Search):针对网格图的优化
  3. 内存限制A*:限制内存使用,避免内存溢出
  4. 时间限制A*:限制搜索时间,返回当前最优解

双向A*实现

defbidirectional_a_star(grid,start,end,heuristic):""" 双向A*算法实现 """# 初始化两个方向的搜索forward_open=[]backward_open=[]forward_closed=set()backward_closed=set()start_node=Node(start)end_node=Node(end)heapq.heappush(forward_open,start_node)heapq.heappush(backward_open,end_node)whileforward_openandbackward_open:# 前向搜索current_forward=heapq.heappop(forward_open)forward_closed.add(current_forward.position)# 检查是否与反向搜索相遇ifcurrent_forward.positioninbackward_closed:# 重构完整路径path=[]# 从前向搜索重构路径temp=current_forwardwhiletemp:path.append(temp.position)temp=temp.parent path.reverse()# 从反向搜索重构路径temp=find_node(backward_open,current_forward.position)whiletemp:path.append(temp.position)temp=temp.parentreturnpath# 扩展前向搜索forneighbor_posinget_neighbors(current_forward.position,grid):ifneighbor_posinforward_closed:continueneighbor=Node(neighbor_pos,current_forward)neighbor.g=current_forward.g+1neighbor.h=heuristic(neighbor_pos,end)neighbor.f=neighbor.g+neighbor.h heapq.heappush(forward_open,neighbor)# 反向搜索(类似前向搜索)current_backward=heapq.heappop(backward_open)backward_closed.add(current_backward.position)ifcurrent_backward.positioninforward_closed:# 重构路径(类似前向搜索)path=[]temp=current_backwardwhiletemp:path.append(temp.position)temp=temp.parent path.reverse()temp=find_node(forward_open,current_backward.position)whiletemp:path.append(temp.position)temp=temp.parentreturnpath# 扩展反向搜索forneighbor_posinget_neighbors(current_backward.position,grid):ifneighbor_posinbackward_closed:continueneighbor=Node(neighbor_pos,current_backward)neighbor.g=current_backward.g+1neighbor.h=heuristic(neighbor_pos,start)neighbor.f=neighbor.g+neighbor.h heapq.heappush(backward_open,neighbor)return[]# 没有找到路径

注意事项

  1. 确保启发式函数满足可容性条件,以保证找到最优解
  2. 对于大规模问题,注意内存使用,考虑使用内存限制版本
  3. 在实现时注意处理重复节点和路径重构
  4. 可以根据具体问题调整启发式函数以获得更好的性能

总结

A* 算法作为启发式搜索的经典算法,在路径规划领域具有重要价值。通过结合已知成本和预估成本,A* 算法能够在保证最优解的同时显著提高搜索效率。算法的关键在于启发式函数的设计和优化,合适的启发式函数可以大大减少搜索空间。A* 算法的灵活性和高效性使其成为游戏AI、导航系统、机器人路径规划等领域的首选算法。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/13 1:33:07

AI硬件产品怎么做?——SenseRobot国际象棋教练

目录 简介 软件侧&#xff1a;不只下棋&#xff0c;是一整套 AI 教练系统 硬件侧&#xff1a;一台 13 寸笔记本大小的双机械臂机器人 竞争格局&#xff1a;蚂蚁市场里的品类定义者 Lesson 1&#xff1a;产品定义的两个强价值点是成立的 Lesson 2&#xff1a;SenseRobot在…

作者头像 李华
网站建设 2026/5/13 1:31:07

从ChatGPT-4o Jailbreak项目看提示工程与AI安全防御

1. 项目概述与核心价值最近在开发者社区里&#xff0c;一个名为“Kimonarrow/ChatGPT-4o-Jailbreak”的项目引起了不小的讨论。乍一看这个标题&#xff0c;很多朋友可能会联想到一些“越狱”或破解操作&#xff0c;但深入探究后你会发现&#xff0c;它的核心价值远不止于此。这…

作者头像 李华
网站建设 2026/5/13 1:30:16

QQ音乐加密文件解密终极指南:qmcdump实战深度解析

QQ音乐加密文件解密终极指南&#xff1a;qmcdump实战深度解析 【免费下载链接】qmcdump 一个简单的QQ音乐解码&#xff08;qmcflac/qmc0/qmc3 转 flac/mp3&#xff09;&#xff0c;仅为个人学习参考用。 项目地址: https://gitcode.com/gh_mirrors/qm/qmcdump 你是否遇到…

作者头像 李华
网站建设 2026/5/13 1:30:12

GitHub导航全解析:功能、They Live Adblocker安装及原理大揭秘

导航菜单包含平台、解决方案、资源、开源、企业等多方面导航选项&#xff0c;如AI代码创作、开发者工作流、应用程序安全等功能&#xff0c;还有按公司规模、用例、行业划分的解决方案&#xff0c;以及按主题和类型探索的资源等。davmlaw/they_live_adblocker这是uBlock Origin…

作者头像 李华
网站建设 2026/5/13 1:27:30

2篇3章3节:Trae 的高效小说创作与文件管理实操

在人工智能辅助小说创作的过程中,工具操作方式、内容生成逻辑与文件管理体系,直接决定写作效率与文稿质量。Trae作为适配小说创作的专业工具,不仅支持单章、全章智能化生成正文内容,适配短篇、长篇不同创作场景,还具备多屏拆分、标签页管理、规范化文件收纳等实用功能。熟…

作者头像 李华
网站建设 2026/5/13 1:26:41

Cap框架解析:模块化开发者工具箱的设计哲学与核心实践

1. 项目概述&#xff1a;一个面向开发者的现代化软件工具箱最近在GitHub上看到一个挺有意思的项目&#xff0c;叫“CapSoftware/Cap”。乍一看这个名字&#xff0c;可能会联想到“Cap”这个英文单词的多种含义——帽子、上限、或者电容的单位。但在软件开发的语境里&#xff0c…

作者头像 李华