喵星之旅-阴险的布谷鸟-A*

简介

A*算法是一种常用的寻路算法,用于在图形化的环境中找到从起点到目标点的最短路径。其核心思想是通过启发式函数来评估每个节点的价值,以选择下一个要探索的节点。该算法结合了Dijkstra算法和贪心算法的优点,能够高效地找到最佳路径。

A*算法的主要工作流程是从起点开始,按照一定的顺序搜索所有可能的状态,并加以评估。当找到目标状态时,算法停止,并输出从起点到目标状态的最优解。其启发函数由两部分组成:已搜索过的路径代价和估价函数,后者用于估计从当前状态到目标状态的代价。这个估价函数通常是基于距离公式来计算的,例如曼哈顿距离或欧几里得距离。

A*算法在搜索过程中能够有效地剪枝,避免搜索无效状态,从而保证了找到的解是最优解。它的应用领域非常广泛,包括计算机图形学中的路径搜索、自动导航系统中的路径规划、网络规划中的路由选择,以及游戏开发中的角色移动等。

总之,A*算法是一种高效且实用的寻路算法,通过启发式搜索策略,能够在复杂的图形或网格环境中找到最短路径。如需更深入的了解,建议查阅相关计算机科学或人工智能领域的专业书籍或文献。

主要实现步骤

A*算法的运行机制如下:

创建两个列表:closedList用于存放不可访问的数据,openHeap用于存放可访问的数据。OpenHeap是一个小根堆,以便于取出f(n)值最小的节点。

将起始节点放入openHeap。

当openHeap不为空时,取出f(n)值最小的节点currentNode。
如果currentNode是目标节点,则路径查找结束。

遍历currentNode的所有相邻节点。对于每个相邻节点neighborNode,如果它是一个无效节点(如障碍物),则跳过;如果它已经在closedList中,则检查是否通过currentNode到达neighborNode的代价更低,如果是,则更新其g值并设置父节点为currentNode。

如果neighborNode不在openList中,或者通过currentNode到达neighborNode的代价更低,则将其加入openList,并设置父节点为currentNode。

例题

题目

在一个 8×8 的网格中,从左上角 (0,0) 到右下角 (7,7),每步只能向右、下、右下三个方向移动,且不能经过标记为障碍物的格子。求最短路径长度。

示例

1
2
3
4
5
6
7
8
S . . . . . . .
. . . # . . . .
. . . . . . . .
. # . . # . . .
. . . . . . . .
. . # . . . # .
. . . . . . . .
. . . . . . . E
  • S = 起点 (0,0)
  • E = 终点 (7,7)
  • # = 障碍物
  • 可移动方向:右(R)、下(D)、右下(DR)

解答

启发函数

使用曼哈顿距离作为启发函数:

1
h(n) = |n.x - goal.x| + |n.y - goal.y|

代价函数

  • g(n):从起点到节点 n 的实际代价
  • f(n) = g(n) + h(n)

移动代价:

  • 右/下:1
  • 右下:√2 ≈ 1.414(对角线)

算法流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
open = [(0,0)]          # 小根堆,按 f 值排序
closed = {}
parent = {}

while open:
current = pop_min_f(open)

if current == (7,7):
break # 找到终点

closed.add(current)

for neighbor in neighbors(current):
if is_wall(neighbor) or neighbor in closed:
continue

tentative_g = g(current) + move_cost(current, neighbor)

if neighbor not in parent or tentative_g < g(neighbor):
parent[neighbor] = current
g(neighbor) = tentative_g
f(neighbor) = g(neighbor) + h(neighbor)
push(open, neighbor)

最短路径

通过回溯 parent 字典得到路径:

1
2
(0,0) → (1,0) → (2,0) → (3,0) → (4,0) → (5,0) → (6,0) → (7,0)
→ (7,1) → (7,2) → (7,3) → (7,4) → (7,5) → (7,6) → (7,7)

路径长度:14(14 步,全部向下和向右)

复杂度

  • 时间复杂度:O(b^d),b 是分支因子,d 是深度
  • 空间复杂度:O(b^d)

A* 的高效之处在于启发函数 h(n) 引导搜索方向,减少无效探索。当 h(n) 满足可采纳性(不夸大实际代价)时,A* 保证找到最优解。

... 阅读 ...
文章目录
  1. 简介
  2. 主要实现步骤
  3. 例题
    1. 题目
    2. 示例
    3. 解答
      1. 启发函数
      2. 代价函数
      3. 算法流程
      4. 最短路径
      5. 复杂度

评论

加载中...
|