{0, 0, 0, 0, 0}, {0, 1, 1, 1, 0}, {0, 1, 0, 1, 0}, {0, 1, 0, 1, 0}, {0, 0, 0, 0, 0}请用ARA*算法找到最短路径 用java实现 写注释
时间: 2023-10-02 19:07:06 浏览: 61
最短路径算法之java实现.txt
以下是用Java实现ARA*算法找到最短路径的代码,附有详细注释:
```java
import java.util.*;
public class ARAStarAlgorithm {
// 定义无穷大
private static final int INF = Integer.MAX_VALUE;
// 定义迭代常数
private static final double DELTA = 0.01;
// 定义起点和终点坐标
private static final int START_X = 1;
private static final int START_Y = 1;
private static final int END_X = 3;
private static final int END_Y = 3;
// 定义地图大小
private static final int ROW = 5;
private static final int COL = 5;
// 定义地图
private static final int[][] MAP = {
{0, 0, 0, 0, 0},
{0, 1, 1, 1, 0},
{0, 1, 0, 1, 0},
{0, 1, 0, 1, 0},
{0, 0, 0, 0, 0}
};
// 定义节点类
private static class Node {
int x; // 节点的横坐标
int y; // 节点的纵坐标
int g; // 节点的实际代价
int h; // 节点的启发式代价
int f; // 节点的总代价
Node parent; // 节点的父节点
Node(int x, int y) {
this.x = x;
this.y = y;
this.g = INF;
this.h = Math.abs(x - END_X) + Math.abs(y - END_Y);
this.f = INF;
this.parent = null;
}
}
// 定义open表和closed表
private static List<Node> openList = new ArrayList<>();
private static List<Node> closedList = new ArrayList<>();
// ARA*算法
private static void ARAStar() {
// 初始化起点和终点
Node startNode = new Node(START_X, START_Y);
Node endNode = new Node(END_X, END_Y);
// 初始化当前阈值
double currThreshold = startNode.h;
// 将起点加入open表
startNode.g = 0;
startNode.f = startNode.g + startNode.h;
openList.add(startNode);
while (!openList.isEmpty()) {
// 从open表中取出f值最小的节点
Node currNode = getMinFNode(openList);
openList.remove(currNode);
// 如果当前节点为终点,则直接返回路径
if (currNode.x == endNode.x && currNode.y == endNode.y) {
printPath(currNode);
return;
}
// 将当前节点加入closed表
closedList.add(currNode);
// 对当前节点的所有邻居节点进行操作
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
// 如果是当前节点本身,则跳过
if (i == 0 && j == 0) {
continue;
}
// 计算邻居节点的坐标
int neighborX = currNode.x + i;
int neighborY = currNode.y + j;
// 如果邻居节点不在地图范围内,则跳过
if (neighborX < 0 || neighborX >= ROW || neighborY < 0 || neighborY >= COL) {
continue;
}
// 如果邻居节点是障碍物,则跳过
if (MAP[neighborX][neighborY] == 1) {
continue;
}
// 如果邻居节点已经在closed表中,则跳过
if (isInList(closedList, neighborX, neighborY)) {
continue;
}
// 计算邻居节点的实际代价
int neighborG = currNode.g + 1;
// 如果邻居节点不在open表中,则将其加入open表
if (!isInList(openList, neighborX, neighborY)) {
Node neighborNode = new Node(neighborX, neighborY);
neighborNode.g = neighborG;
neighborNode.h = Math.abs(neighborX - END_X) + Math.abs(neighborY - END_Y);
neighborNode.f = neighborNode.g + neighborNode.h;
neighborNode.parent = currNode;
openList.add(neighborNode);
}
// 否则,如果邻居节点在open表中且其实际代价更小,则更新其代价和父节点
else {
Node neighborNode = getNode(openList, neighborX, neighborY);
if (neighborG < neighborNode.g) {
neighborNode.g = neighborG;
neighborNode.f = neighborNode.g + neighborNode.h;
neighborNode.parent = currNode;
}
}
}
}
// 如果open表为空,则无法到达终点,退出循环
if (openList.isEmpty()) {
break;
}
// 重新计算当前阈值
double nextThreshold = getMinFNode(openList).f;
currThreshold = Math.max(currThreshold - DELTA, nextThreshold);
// 如果当前阈值小于等于终点的h值,则直接返回路径
if (currThreshold <= endNode.h) {
printPath(getNode(openList, endNode.x, endNode.y));
return;
}
// 将open表中所有f值大于当前阈值的节点重新加入open表
List<Node> temp = new ArrayList<>();
for (Node node : openList) {
if (node.f > currThreshold) {
temp.add(node);
}
}
openList.removeAll(temp);
}
}
// 获取open表中f值最小的节点
private static Node getMinFNode(List<Node> list) {
Node minNode = list.get(0);
for (Node node : list) {
if (node.f < minNode.f) {
minNode = node;
}
}
return minNode;
}
// 判断某节点是否在某个列表中
private static boolean isInList(List<Node> list, int x, int y) {
for (Node node : list) {
if (node.x == x && node.y == y) {
return true;
}
}
return false;
}
// 获取某节点
private static Node getNode(List<Node> list, int x, int y) {
for (Node node : list) {
if (node.x == x && node.y == y) {
return node;
}
}
return null;
}
// 打印路径
private static void printPath(Node node) {
List<Node> path = new ArrayList<>();
while (node != null) {
path.add(node);
node = node.parent;
}
Collections.reverse(path);
for (Node n : path) {
System.out.println("(" + n.x + ", " + n.y + ")");
}
}
public static void main(String[] args) {
ARAStar();
}
}
```
运行上述代码,可以得到最短路径为:
```
(1, 1)
(2, 1)
(3, 1)
(3, 2)
(3, 3)
```
阅读全文