A星寻路算法

本文介绍了A*寻路算法的基本原理和计算方法,包括如何计算G值和H值,以及A*算法的开启列表和关闭列表的使用。A*算法通过评估f=g+h来寻找最短路径,其中f是总成本,g是从起点到当前点的距离,h是从当前点到终点的预估距离。寻路结束后,通过追溯关闭列表中的父对象来确定路径。当开放列表为空且未达到终点时,表示存在死路。此外,提供了A*寻路的伪代码及DEMO下载链接。
摘要由CSDN通过智能技术生成

众所周知,A*寻路是用来计算行进路径的,通过它可以计算出避开阻挡到达终点的最短路径。基本原理也很简单,就是遍历周围所有可以行进的点选出一个最优点再次遍历,直到到达终点。

A*寻路有一套固定的公式:f = g + h

f:寻路消耗;g:离起点的距离;h:离终点的距离

如何计算G值

顾名思义,G是离起点的距离,就是从起点到达格子要走的距离,比如从起点到上、下、左、右四个点都是紧挨着起点,距离可以用1来表示,左上、左下、右上、右下这种顶点相邻的格子,根据勾股定理可以判断出距离为√2约等于1.4。

如何计算H值

H值的计算通过曼哈顿街区算法判定,即从该格子走到终点一共需要走多少个格子。

A*算法还需要两个列表:开启列表和关闭列表

开启列表:用来存储可以考虑行进的格子。
关闭列表:用来存储不再考虑的格子。

A*寻路伪代码

1、将起点记录为当前点a
2、将当前点a放入关闭列表,并设置父对象为空
3、将当前点a周围所有能行进的格子放入开启列表,如果周围的点已经在开启列表或者关闭列表中,就不用管它了
4、记录当前点a周围所有能行进的格子的F值和父对象(父对象为当前点)
5、寻找最优点将其放入关闭列表,每次往关闭列表放点时,要判断该点是否为终点,如果是证明路径已经找完了,跳到步骤8,如果不是继续步骤6
6、将最优点作为起点b
7、跳回步骤3
8、找到终点,寻路结束

确定路径

那么寻路结束后要怎么确定路径呢?虽然最优点都在关闭列表中,但是并不能直接使用关闭列表中的点作为路径,而是在关闭列表中从终点开始查找父对象,再查找父对象的父对象。。。直到找到父对象为空。

特殊情况,判断死路

当开放列表为空时,说明找遍了所有的点没有到达终点,说明是死路,寻路失败

DEMO下载链接

链接: A*寻路DEMO.

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
A寻路算法(A*算法)是一种常用于解决路径寻找问题的算法,特别适用于在网格图中寻找最短路径。下面是一个使用PHP实现A*算法的简单示例: ```php <?php class Node { public $x; public $y; public $f; public $g; public $h; public $parent; function __construct($x, $y) { $this->x = $x; $this->y = $y; $this->f = 0; $this->g = 0; $this->h = 0; $this->parent = null; } } function astar($start, $goal, $grid) { $open = array(); $closed = array(); $start->g = 0; $start->h = heuristic($start, $goal); $start->f = $start->g + $start->h; array_push($open, $start); while (!empty($open)) { $current = $open[0]; foreach ($open as $node) { if ($node->f < $current->f || ($node->f == $current->f && $node->h < $current->h)) { $current = $node; } } $key = array_search($current, $open); array_splice($open, $key, 1); array_push($closed, $current); if ($current->x == $goal->x && $current->y == $goal->y) { $path = array(); while ($current->parent) { array_push($path, $current); $current = $current->parent; } return array_reverse($path); } $neighbors = getNeighbors($current, $grid); foreach ($neighbors as $neighbor) { $gScore = $current->g + 1; $hScore = heuristic($neighbor, $goal); $fScore = $gScore + $hScore; if (in_array($neighbor, $closed) && $fScore >= $neighbor->f) { continue; } if (!in_array($neighbor, $open) || $fScore < $neighbor->f) { $neighbor->g = $gScore; $neighbor->h = $hScore; $neighbor->f = $fScore; $neighbor->parent = $current; if (!in_array($neighbor, $open)) { array_push($open, $neighbor); } } } } return null; } function heuristic($node, $goal) { return abs($node->x - $goal->x) + abs($node->y - $goal->y); } function getNeighbors($node, $grid) { $neighbors = array(); $offsets = array(array(-1, -1), array(-1, 0), array(-1, 1), array(0, -1), array(0, 1), array(1, -1), array(1, 0), array(1, 1)); foreach ($offsets as $offset) { $x = $node->x + $offset[0]; $y = $node->y + $offset[1]; if ($x >= 0 && $x < count($grid) && $y >= 0 && $y < count($grid[0]) && $grid[$x][$y] != 1) { array_push($neighbors, new Node($x, $y)); } } return $neighbors; } // 测试 $grid = array( array(0, 0, 0, 0), array(1, 1, 0, 1), array(0, 0, 0, 0), array(0, 0, 0, 0) ); $start = new Node(0, 0); $goal = new Node(3, 3); $path = astar($start, $goal, $grid); if ($path) { foreach ($path as $node) { echo "(" . $node->x . ", " . $node->y . ") "; } } else { echo "No Path Found"; } ?> ``` 上述代码实现了A*寻路算法,其中`astar`函数用于执行算法的主要逻辑,`heuristic`函数用于计算启发式函数的,`getNeighbors`函数用于获取节点的相邻节点。在给定的网格图中,我们从起点`(0, 0)`到目标点`(3, 3)`寻找最短路径。路径的结果将根据节点坐标依次打印出来。若找不到路径,则输出"No Path Found"。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值