本节主要讲述A星寻路算法,下面通过一个经典案例开始。
案例:在下面的图片中,小人想要找到五角星,主要有2条路径,一条是蓝色部分,从上面开始寻找,此时总步数为9步;另外一种就是从下面开始寻找,此时总步数为7步,我们通过步数得出,最短路径的步数为7步,怎么通过代码实现搜索步数呢,下面我们开始。
A星寻路法主要是为每个节点定义一下几个内容,通过公式计算得出最短路径的步数以及打印最短路径。
1、父节点:保存每个节点对应的父节点,在我们找到目标节点时,可以通过父节点寻找每个节点的位置,从而打印出节点路径。
2、已使用步数:从开始节点到当前节点已使用的步数,每个节点一步
3、无障碍距离 :当前节点到目标节点无视障碍的距离,等于行坐标距离+列坐标距离
4、期望完成步数:已使用步数+无障碍的步数,搜索最短步数时的依据。
5、节点的行、列坐标,标识当前节点所在的位置。
为了方便看图,每个节点左上角表示期望完成步数,左下角表示已使用步数,右下角表示无障碍距离。
class Node{
/** 行坐标 **/
int x;
/** 列坐标 **/
int y;
/** 已使用步数 :从开始节点到当前节点已使用的步数**/
int usedSteps;
/** 无障碍距离 :当前节点到目标节点无视障碍的距离**/
int distance;
/** 期望步数 = 已使用步数+无障碍距离**/
int expectedSteps;
/** 父节点:打印路径时需要 **/
Node parent;
}
下面开始对案例的详细步骤解答:
首先我们定义一个迷宫:
/** 迷宫 1表示障碍物 **/
public static int[][] MAZE = {
{
0, 0, 0, 1, 0 },
{
0, 1, 0, 1, 0 },
{
0, 1, 0, 0, 0 },
{
0, 0, 0, 1, 0 }
};
我们需要建立2个list,用以保存那些节点已经被访问过,那些节点准备访问。
/** 待访问的节点 **/
ArrayList<Node> readyList = new ArrayList<>();
/** 已访问的节点 **/
ArrayList<Node> visitedList = new ArrayList<>();
我们计算开始节点周围节点已使用步数、无障碍距离、期望完成步数,并将结果放到待访问节点列表中。由于每个节点都有上下左右4个方向,为了避免写4次,我们用一个数组表示方向。
/** 定义上下左右方向 **/
static int[][] stepArray = {
{
0, 1 }, {
0, -1 }, {
1, 0 }, {
-1, 0