java ARA*算法 请写注释 并实现
时间: 2024-05-10 10:17:38 浏览: 84
A*算法 java实现
5星 · 资源好评率100%
ARA*算法是A*算法的改进,它在保证A*算法的最优性的同时,通过减少计算量来提高搜索效率。ARA*算法是基于A*算法的启发式搜索算法,它通过动态调节启发式函数中的权重来控制搜索深度。
注释如下:
```java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.PriorityQueue;
public class ARAStar {
//定义节点类
class Node {
int x; //节点的x坐标
int y; //节点的y坐标
int g; //从起点到该节点的实际代价
int h; //从该节点到目标节点的估计代价
int f; //节点的总代价
Node parent; //指向该节点的父节点
public Node(int x, int y) {
this.x = x;
this.y = y;
g = Integer.MAX_VALUE;
h = Integer.MAX_VALUE;
f = Integer.MAX_VALUE;
parent = null;
}
}
//定义比较器,用于比较节点的f值大小
class NodeComparator implements Comparator<Node> {
@Override
public int compare(Node o1, Node o2) {
return o1.f - o2.f;
}
}
//定义地图,0表示可通过,1表示障碍物
private int[][] map = {
{0, 0, 0, 0, 0},
{0, 1, 1, 0, 0},
{0, 0, 0, 0, 0},
{0, 0, 1, 1, 0},
{0, 0, 0, 0, 0}
};
private int startX = 0; //起点x坐标
private int startY = 0; //起点y坐标
private int endX = 4; //目标节点x坐标
private int endY = 4; //目标节点y坐标
private int rows = map.length; //地图的行数
private int cols = map[0].length; //地图的列数
private double weight = 2; //初始权重
private double epsilon = 0.1; //每次减少的权重值
private int[][] gValues = new int[rows][cols]; //起点到每个节点的实际代价
private PriorityQueue<Node> openList = new PriorityQueue<>(new NodeComparator()); //开放列表
private ArrayList<Node> closeList = new ArrayList<>(); //关闭列表
public void search() {
Node startNode = new Node(startX, startY);
startNode.g = 0;
startNode.h = heuristic(startX, startY, endX, endY);
startNode.f = startNode.g + (int) (weight * startNode.h);
openList.add(startNode);
gValues[startX][startY] = 0;
while (!openList.isEmpty()) {
Node currentNode = openList.poll();
if (currentNode.x == endX && currentNode.y == endY) {
System.out.println("找到了目标节点!");
return;
}
closeList.add(currentNode);
for (int i = -1; i <= 1; i++) {
for (int j = -1; j <= 1; j++) {
if (i == 0 && j == 0) {
continue;
}
int neighborX = currentNode.x + i;
int neighborY = currentNode.y + j;
if (neighborX < 0 || neighborX >= rows || neighborY < 0 || neighborY >= cols) {
continue;
}
if (map[neighborX][neighborY] == 1) {
continue;
}
if (closeListContains(neighborX, neighborY)) {
continue;
}
int tentativeG = gValues[currentNode.x][currentNode.y] + getCost(currentNode.x, currentNode.y, neighborX, neighborY);
if (!openListContains(neighborX, neighborY)) {
Node neighborNode = new Node(neighborX, neighborY);
gValues[neighborX][neighborY] = tentativeG;
neighborNode.g = tentativeG;
neighborNode.h = heuristic(neighborX, neighborY, endX, endY);
neighborNode.f = neighborNode.g + (int) (weight * neighborNode.h);
neighborNode.parent = currentNode;
openList.add(neighborNode);
} else {
Node neighborNode = getOpenListNode(neighborX, neighborY);
if (tentativeG < gValues[neighborX][neighborY]) {
gValues[neighborX][neighborY] = tentativeG;
neighborNode.g = tentativeG;
neighborNode.f = neighborNode.g + (int) (weight * neighborNode.h);
neighborNode.parent = currentNode;
openList.remove(neighborNode);
openList.add(neighborNode);
}
}
}
}
weight -= epsilon;
}
System.out.println("无法找到目标节点!");
}
//判断关闭列表中是否包含指定节点
private boolean closeListContains(int x, int y) {
for (Node node : closeList) {
if (node.x == x && node.y == y) {
return true;
}
}
return false;
}
//判断开放列表中是否包含指定节点
private boolean openListContains(int x, int y) {
for (Node node : openList) {
if (node.x == x && node.y == y) {
return true;
}
}
return false;
}
//获取开放列表中指定节点的引用
private Node getOpenListNode(int x, int y) {
for (Node node : openList) {
if (node.x == x && node.y == y) {
return node;
}
}
return null;
}
//获取两个节点之间的代价
private int getCost(int x1, int y1, int x2, int y2) {
if (x1 == x2 || y1 == y2) {
return 10;
} else {
return 14;
}
}
//获取从一个节点到另一个节点的估计代价
private int heuristic(int x1, int y1, int x2, int y2) {
return Math.abs(x1 - x2) + Math.abs(y1 - y2);
}
public static void main(String[] args) {
ARAStar araStar = new ARAStar();
araStar.search();
}
}
```
注:以上代码中,启发式函数采用曼哈顿距离计算。ARA*算法在搜索过程中,会逐渐减小权重值epsilon,使得搜索深度逐渐增加,直到找到目标节点为止。
阅读全文