A* - 启发式搜索

A*

算法特点

  • 启发式搜索算法
  • 适用于静态环境中的路径规划
  • 求解源点到目标点之间的最短路径,需要指明目标点(即目标点位置已知,这样才能有效的计算 h ( x ) h(x) h(x))。

1 基本概念

  • 启发式方法:

    一种根据经验规则进行发现的方法

  • 启发函数 h ( x ) h(x) h(x):

    1. 曼哈顿距离: 只允许上下左右移动的情况
      D = ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ D= |x_1-x_2| + |y_1-y_2| D=x1x2+y1y2

    2. 欧几里得距离: 允许朝任意方向移动
      D = ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 D=\sqrt{(x_1-x_2)^2+(y_1-y_2)^2} D=(x1x2)2+(y1y2)2

    3. 其他: 例如对角距离等

2 算法实现

评价函数

f ( n ) = g ( n ) + h ( n ) f(n)=g(n)+h(n) f(n)=g(n)+h(n)

  • g ( n ) g(n) g(n) 表示从起点 S S S 到的最优路径的实际成本, 即从起点到当前节点已经走过的路程。(其实可以理解为 Dijkstra 算法中的 dis 数组)
  • h ( n ) h(n) h(n) 表示从当前节点到目标节点 T T T 的预估成本, 使用启发函数来计算, 根据具体问题, 一般为曼哈顿距离或者欧氏距离

算法输入

要具体研究一个算法,首先定义输入结构:

  • 起点 S S S 坐标已知 ( x 1 , y 1 ) (x_1,y_1) (x1,y1),终点 E 坐标已知 ( x 2 , y 2 ) (x_2,y_2) (x2,y2)
  • 输入地图为一个 N ∗ N N*N NN 的方阵,其中每个元素代表一个实际地图的像素,假设每一个相邻像素之间的距离为 1 1 1,斜对角相邻元素的距离为 2 \sqrt{2} 2 ,其中有一些像素为障碍物。

这里首先定义两个集合:

  • 开放列表(OpenList):已经访问过,但是没有确定最短路径的节点。
  • 关闭列表(CloseList):已经确定了源点到其的最短路径的节点。

算法流程

  1. 将起点 S S S 放入开放列表 (openList) 中.

  2. 遍历开放列表

    1. 计算列表中的每一个节点 n n n 的评价函数 f ( n ) f(n) f(n) , 查找 f ( n ) f(n) f(n) 函数值最小的节点, 将这个节点作为当前要处理的节点 N N N

    2. 对于当前正在处理的节点 N N N , 遍历与之相邻的其他所有节点 N n e a r N_{near} Nnear

      • 假设当前正在处理的相邻节点为 N n e a r N_{near} Nnear

        1. N n e a r N_{near} Nnear 已经在关闭列表中(已经确定最短路径),或者不可达(障碍物),则忽略该节点

        2. N n e a r N_{near} Nnear 不在开放列表中(未被访问过),则将其加入开放列表,将当前节点 N N N 设置为 N n e a r N_{near} Nnear 的父结点,计算节点 N n e a r N_{near} Nnear 的评价函数 f ( N n e a r ) f(N_{near}) f(Nnear) , g ( N n e a r ) g(N_{near}) g(Nnear)

        3. N n e a r N_{near} Nnear 已经在开放列表中(已经访问过但未确定最短路径),则需要检查这条路径(节点 N N N 到节点 N n e a r N_{near} Nnear 的路径)是否更好,参考指标为 g ( N n e a r ) g(N_{near}) g(Nnear) ,若 g ( N n e a r ) g(N_{near}) g(Nnear) 更小,则说明该路径更好,则将它的父亲节点(设为节点)设置为当前节点 N N N ,并重新计算 f ( N n e a r ) f(N_{near}) f(Nnear)

          g ( N n e a r ) = m i n {   g ( N ) + d i s t a c e ( N , N n e a r )   ,   g ( N n e a r )   } g(N_{near}) = min\left\{\ g(N)+distace(N,N_{near})\ ,\ g(N_{near}) \ \right\} g(Nnear)=min{ g(N)+distace(N,Nnear) , g(Nnear) }

    3. 当前节点 N N N 处理完毕, 移动到关闭列表,表示该节点已经不需要被继续关注。

  3. 重复步骤「2」直到满足以下条件之一,算法结束:

    1. 终点进入了开放(找到了起点到终点的路径)
    2. 开放列表为空,仍未找到终点(无法找到起点到终点的路径)
  4. 路径回溯:如果在步骤「3」中,存在从终点到起点的路径,则回溯找到最短路径:

    从终点开始,每一个节点都沿着父亲节点移动,直到找到起点。

样例以及源码

github仓库

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值