

























作者:吴屏珊
1、图的说明:有一个8*8的地图,其中绿色的点为起点,红色的点为终点,黑色的点为障碍点(即不可达点),当然边界也是不可达点。
2、将要实现的目标:从起点走到终点,其中要求所走距离最短并且要绕开所有不可达点。
3、移动方向:每个点只有上,下,左,右四个方向可以行进。
Math.abs(x1-x2)+Math.abs(y1-y2)1、点的坐标(x,y)
2、计算点的代价时所需数值:F,G,H
3、父节点:Father;父节点记录的是该节点的上一个节点(即该节点是由哪个节点遍历到的)。
父节点的作用:A*算法从起点开始寻路,当找到终点的时候代表最短路径已经找到,这时我们可以利用终点结构的Father来回溯到起点(起点的Father为NULL),从而找出并且输出这条最短路径。
1、优先队列Open表:记录由该点下一步可以到达的所有点,并且每次将F值最小的点放在队首。
2、Close表:记录所有已经走过的点。
3、Exist表:记录所有遍历过的点(即在Open与Close中出现过的点)。
4、Close表与Exist表的区别:Close中存储的点是已走过的点,Exist表中存储的点是已遍历过,但不一定走过的点。








class Node implements Comparable<Node> {
public int x; //x坐标
public int y; //y坐标
public int F; //F属性
public int G; //G属性
public int H; //H属性
public Node Father; //此结点的上一个结点
//获取当前结点的坐标
public Node(int x, int y) {
this.x = x;
this.y = y;
}
//通过结点的坐标可以得到F, G, H三个属性
//需要传入这个节点的上一个节点和最终的结点
public void init_node(Node father, Node end) {//father是父节点
this.Father = father;
if (this.Father != null) {
this.G = father.G + 1;
} else { //父节点为空代表它是第一个结点
this.G = 0;
}
//计算通过现在的结点的位置和最终结点的位置计算H值
this.H = Math.abs(this.x - end.x) + Math.abs(this.y - end.y);
this.F = this.G + this.H;
}
// 用来进行和其他的Node类进行比较
@Override
public int compareTo(Node o) {
return Integer.compare(this.F, o.F);
}
}
public boolean is_exist(Node node)
{
for (Node exist_node : Exist) {
if (node.x == exist_node.x && node.y == exist_node.y) {
return true;
}
}
return false;
}
public boolean is_valid(int x, int y) {
// 如果结点的位置是-1,则不合法
if (map[x][y] == -1) return false;
for (Node node : Exist) {
//如果结点出现过,不合法
// if (node.x == x && node.y == y) {
// return false;
// }
if (is_exist(new Node(x, y))) {
return false;
}
}
//以上情况都没有则合法
return true;
}
public ArrayList<Node> extend_current_node(Node current_node) {
int x = current_node.x;
int y = current_node.y;
ArrayList<Node> neighbour_node = new ArrayList<Node>();
if (is_valid(x + 1, y))
{
Node node = new Node(x + 1, y);
neighbour_node.add(node);
}
if (is_valid(x - 1, y))
{
Node node = new Node(x -1, y);
neighbour_node.add(node);
}
if (is_valid(x, y + 1))
{
Node node = new Node(x, y + 1);
neighbour_node.add(node);
}
if (is_valid(x, y - 1))
{
Node node = new Node(x, y - 1);
neighbour_node.add(node);
}
return neighbour_node;
}
public Node astarSearch(Node start, Node end) {
//把第一个开始的结点加入到Open表中
this.Open.add(start);
//把出现过的结点加入到Exist表中
this.Exist.add(start);
//主循环
while (Open.size() > 0) {
//取优先队列顶部元素并且把这个元素从Open表中删除
Node current_node = Open.poll();
//将这个结点加入到Close表中
Close.add(current_node);
//对当前结点进行扩展,得到一个四周结点的数组
ArrayList<Node> neighbour_node = extend_current_node(current_node);
//对这个结点遍历,看是否有目标结点出现
//没有出现目标结点再看是否出现过
for (Node node : neighbour_node) {
if (node.x == end.x && node.y == end.y) {//找到目标结点就返回
node.init_node(current_node,end);
return node;//返回的是终止结点
}
if (!is_exist(node)) { //没出现过的结点加入到Open表中并且设置父节点
node.init_node(current_node, end);
Open.add(node);
Exist.add(node);
}
}
}
//如果遍历完所有出现的结点都没有找到最终的结点,返回null
return null;
}
int[][] map = {
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
{-1, 0, 0, 0, 0, 0, 0, 0, 0, -1},
{-1, 0, 0, 0, 0, -1, 0, 0, 0, -1},
{-1, 0, 0, 0, -1, 0, 0, 0, 0, -1},
{-1, 0, 0, 0, -1, 0, 0, 0, 0, -1},
{-1, 0, 0, 0, 0, -1, 0, 0, 0, -1},
{-1, 0, 0, 0, -1, 0, 0, 0, 0, -1},
{-1, 0, 0, 0, 0, -1, 0, 0, 0, -1},
{-1, 0, 0, 0, 0, 0, 0, 0, 0, -1},
{-1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
};
Node start = new Node(4, 2);
map[start.x][start.y]=1;
start.Father = null;
Node end = new Node(4, 7);
map[end.x][end.y]=2;
Solution solution = new Solution();
Node res_node = solution.astarSearch(start, end);//res—node最先接收的是该地图的终止
while (res_node != null) {
map[res_node.x][res_node.y] = res_node.G;
res_node = res_node.Father;//迭代操作,从终止结点开始向后退,直到起点的父节点为null。循环终止
}
//渲染迷宫
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
Node nownode =new Node(i,j);
if(map[i][j]==-1)
System.out.printf("\033[31m%3d\033[0m", map[i][j]);//red
else if (equal_node(nownode,start) || equal_node(nownode,end))
System.out.printf("\033[32m%3d\033[0m", map[i][j]);//green
else if(map[i][j]==0 && !equal_node(nownode,start))
System.out.printf("%3d", map[i][j]);//black
else
System.out.printf("\033[34m%3d\033[0m", map[i][j]);//blue
}
System.out.println();
}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。