人工智能算法之A*搜索算法
创作时间:
作者:
@小白创作中心
人工智能算法之A*搜索算法
引用
CSDN
1.
https://m.blog.csdn.net/weixin_50153843/article/details/143379550
A搜索算法是一种广泛应用于路径寻找和优化问题的图形搜索算法。它结合了实际代价和启发式代价,能够高效地找到从起点到目标点的最优路径。本文将详细介绍A算法的基本原理、实现方法及其应用场景。
A搜索算法是一种广泛使用的图形搜索算法,适用于路径寻找和图形遍历。它结合了最佳优先搜索和Dijkstra算法的优点,通过利用启发式信息来引导搜索过程,能够高效地找到从起点到目标点的最优路径。A算法在很多应用场景中表现出色,包括游戏开发、机器人导航和地图路由等。
A*算法的基本原理
A*算法通过维护一个优先队列来管理待处理的节点。每个节点的代价由两部分组成:
- 实际代价 ( g(n) ):从起点到当前节点 ( n ) 的实际代价。
- 启发式代价 ( h(n) ):从当前节点 ( n ) 到目标节点的估算代价。
A*算法的核心思想是使用代价函数 ( f(n) ) 来评估节点 ( n ):
- f(n) 表示从起点到目标节点的总估计代价。
- g(n) 是实际成本。
- h(n) 是从当前节点到目标节点的启发式估算。
A*算法通过不断扩展代价函数最小的节点,逐步找到目标节点。
启发式函数的选择
启发式函数 ( h(n) ) 是A*算法的关键,它决定了算法的效率和效果。一个有效的启发式函数应满足以下条件:
- 可接受性(Admissibility):启发式函数永远不应高估从当前节点到目标节点的真实代价。
- 一致性(Consistency):对于每个节点 ( n ) 和它的每个相邻节点 ( m ),启发式函数应满足:
其中 ( c(n, m) ) 是从 ( n ) 到 ( m ) 的实际代价。
常见的启发式函数包括:
- 曼哈顿距离:在网格地图中,适用于只能上下左右移动的场景:
- 欧几里得距离:适用于可以在任意方向移动的场景:
A*算法的步骤
- 初始化:创建一个开启列表(Open List)和关闭列表(Closed List)。将起点放入开启列表。
- 循环处理节点:
- 从开启列表中选择代价函数 f(n) 最小的节点 n 。
- 如果 n 是目标节点,则找到路径,算法结束。
- 将 n 移动到关闭列表。
- 对于每个相邻节点 m :
- 如果 m 在关闭列表中,跳过。
- 计算 g(m) 和 f(m) 。
- 如果 m 不在开启列表中,添加到开启列表。
- 路径重建:从目标节点反向重建路径。
A*算法的Python实现
下面的代码实现了A*算法在一个简单网格上的路径寻找,假设可以上下左右移动。
import heapq
class Node:
def __init__(self, position, parent=None):
self.position = position # 节点位置 (x, y)
self.parent = parent # 父节点
self.g = 0 # 从起点到当前节点的实际代价
self.h = 0 # 从当前节点到目标节点的启发式代价
self.f = 0 # 总的估计代价 f(n) = g(n) + h(n)
def __eq__(self, other):
return self.position == other.position
def __lt__(self, other):
return self.f < other.f
def heuristic(node1, node2):
""" 计算曼哈顿距离作为启发式函数 """
return abs(node1.position[0] - node2.position[0]) + abs(node1.position[1] - node2.position[1])
def a_star_search(start, goal, grid):
open_list = []
closed_list = set()
start_node = Node(start)
goal_node = Node(goal)
# 将起点加入开启列表
heapq.heappush(open_list, start_node)
while open_list:
# 取出f值最小的节点
current_node = heapq.heappop(open_list)
# 如果达到目标节点
if current_node == goal_node:
path = []
while current_node:
path.append(current_node.position)
current_node = current_node.parent
return path[::-1] # 返回反向路径
closed_list.add(current_node)
# 生成邻居节点
neighbors = [(0, 1), (1, 0), (0, -1), (-1, 0)] # 上、右、下、左
for new_position in neighbors:
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])
# 检查是否在网格范围内
if (node_position[0] > (len(grid) - 1) or node_position[0] < 0 or
node_position[1] > (len(grid[len(grid) - 1]) - 1) or node_position[1] < 0):
continue
# 检查是否为障碍物
if grid[node_position[0]][node_position[1]] != 0:
continue
neighbor_node = Node(node_position, current_node)
if neighbor_node in closed_list:
continue
# 计算g, h, f值
neighbor_node.g = current_node.g + 1
neighbor_node.h = heuristic(neighbor_node, goal_node)
neighbor_node.f = neighbor_node.g + neighbor_node.h
# 检查邻居是否已经在开启列表中
if any(neighbor_node == open_node and neighbor_node.g > open_node.g for open_node in open_list):
continue
# 将邻居添加到开启列表
heapq.heappush(open_list, neighbor_node)
return None # 没有找到路径
# 示例网格(0表示可通行,1表示障碍物)
grid = [
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0],
[0, 1, 1, 1, 0],
[0, 0, 0, 0, 0]
]
start = (0, 0) # 起点
goal = (4, 4) # 终点
# 执行A*搜索
path = a_star_search(start, goal, grid)
print(f"Path from {start} to {goal}: {path}")
代码解读
- 节点类:
Node 类表示搜索中的每个节点,包含位置、父节点、实际代价、启发式代价和总估计代价。 - 启发式函数:
heuristic 函数计算曼哈顿距离,作为启发式代价。 - A*搜索函数:
a_star_search 实现了A*算法的核心逻辑,包括初始化、循环处理、生成邻居节点、计算代价等。 - 示例网格:示例网格中,0表示可通行的路径,1表示障碍物。
- 路径输出:程序输出从起点到终点的路径。
A*算法的复杂度
A算法的时间复杂度和空间复杂度在最坏情况下都是 O(b^d) ,其中 b 是分支因子(每个节点的子节点数), d 是解的深度。由于A算法在搜索中保持了开启列表和关闭列表,因此其空间复杂度较高,特别是在大规模问题上。
A*算法的优缺点
优点
- 高效性:A*算法通过使用启发式函数引导搜索,可以快速找到最优解。
- 灵活性:启发式函数可以根据具体问题的特点进行调整,灵活应对不同的场景。
- 保证最优性:只要启发式函数是可接受的,A*算法保证找到最优路径。
缺点
- 内存消耗:由于需要维护开启列表和关闭列表,A*算法在处理大规模问题时可能会消耗大量内存。
- 启发式函数的选择:选择合适的启发式函数至关重要,错误的选择可能导致效率降低。
A*算法的应用场景
- 路径规划:在地图上为机器人或游戏角色寻找最短路径。
- 游戏开发:用于非玩家角色(NPC)的智能移动。
- 网络路由:寻找网络中最优数据传输路径。
- 物流与运输:优化配送路径和调度问题。
总结
A搜索算法是一种高效的图形搜索算法,广泛应用于路径寻找和优化问题。通过结合实际代价和启发式代价,A算法能够快速找到最优路径。虽然在大规模问题上存在内存消耗等问题,但其灵活性和保证最优性的特性使其在众多领域中仍然具有广泛的应用前景。
热门推荐
毕加索笔下的女性魅力:从文字到画布
手机内存大小真的影响性能吗?一篇文章让你明白真相
英语论文写作中,如何使用冒号?
冒号的正确写法与使用技巧全解析
酒精依赖:家庭成员如何有效支持
古人喝酒竟有这种奇葩姿势?你敢试试吗?
职场女性如何在酒席上优雅拒绝喝酒?
职场酒局攻略:从青铜到王者
美国心理学会推荐:睡前五分钟写待办事项,助你更快入睡
妙佑医疗国际推荐:科学助眠指南
失眠与焦虑:如何打破这个恶性循环?
蒸汽熨斗使用全攻略:让衣物焕然一新!
秋冬换季,你真的懂如何正确熨烫衣物吗?
吃大蒜后如何摆脱尿液蒜味?
陕西老火锅:古都风味,麻辣与香醇的碰撞
跨年新宠:湖北-重庆8日深度游攻略
如何挑选抽油烟机及日常清洗技巧
重庆三峡博物馆:开放时间、门票信息、交通方式及参观注意事项
近视手术后,多久能恢复视力?注意视力的稳定期
激光手术治疗近视眼的效果及危害有哪些?究竟是利大于弊还是弊大于利?
“探索恐龙时代巨兽:吕文扬与三角龙的研究”
霸王龙吃什么?食物链顶端的统治者,没有天敌
吃大蒜后尿液变臭?真相揭秘!
尿黄有怪味?当心是肝脏在"求救"!
如何避免尿路感染?这些小习惯你做到了吗?
秋冬季节,你的小便异味可能是这个原因!
糖尿病患者注意!尿液异味可能是重要信号
“红事礼到人不怪,白事礼到人不收”,啥意思,啥讲究,有道理?
口干口苦是大病的前兆吗?或和三种疾病相关
保护心脏健康的中医妙招