java a*算法 请写注释
时间: 2023-12-23 07:02:11 浏览: 33
好的,以下是A*算法的Java实现,带有详细注释。
```java
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.PriorityQueue;
/**
* A*算法实现类
*/
public class AStar {
/**
* 寻路方法
*
* @param start 起点
* @param end 终点
* @param map 地图,用二维数组表示,1表示可通过,0表示障碍物
* @return 返回最短路径,如果没有路径则返回null
*/
public static List<Node> findPath(Node start, Node end, int[][] map) {
// 定义开启列表和关闭列表
PriorityQueue<Node> openList = new PriorityQueue<>();
List<Node> closeList = new ArrayList<>();
// 把起点加入开启列表
openList.offer(start);
// 主循环,每一轮检查一个当前方格节点
while (!openList.isEmpty()) {
// 在开启列表中查找F值最小的节点作为当前节点
Node current = openList.poll();
// 如果当前节点是终点,则说明已经找到了一条路径
if (current.equals(end)) {
return getPath(start, end);
}
// 把当前节点加入关闭列表,同时从开启列表中删除
closeList.add(current);
// 获取当前节点的所有邻居节点
List<Node> neighbors = getNeighbors(current, map);
// 对于每个邻居节点
for (Node neighbor : neighbors) {
// 如果邻居节点已经在关闭列表中,跳过它
if (closeList.contains(neighbor)) {
continue;
}
// 如果邻居节点不在开启列表中,把它加入开启列表
if (!openList.contains(neighbor)) {
// 计算邻居节点的F、G、H值
neighbor.g = current.g + 1;
neighbor.h = getDistance(neighbor, end);
neighbor.f = neighbor.g + neighbor.h;
// 设置邻居节点的父节点为当前节点
neighbor.parent = current;
// 把邻居节点加入开启列表
openList.offer(neighbor);
} else {
// 如果邻居节点已经在开启列表中,检查这条路径是否更优,如果更优则更新父节点
int tempG = current.g + 1;
if (tempG < neighbor.g) {
neighbor.g = tempG;
neighbor.f = neighbor.g + neighbor.h;
neighbor.parent = current;
}
}
}
}
// 如果开启列表已经为空,仍然没有找到终点,说明无法到达
return null;
}
/**
* 获取当前节点的所有邻居节点
*
* @param node 当前节点
* @param map 地图
* @return 返回所有邻居节点列表
*/
private static List<Node> getNeighbors(Node node, int[][] map) {
List<Node> neighbors = new ArrayList<>();
int x = node.x;
int y = node.y;
// 左
if (x > 0 && map[x - 1][y] == 1) {
neighbors.add(new Node(x - 1, y));
}
// 上
if (y > 0 && map[x][y - 1] == 1) {
neighbors.add(new Node(x, y - 1));
}
// 右
if (x < map.length - 1 && map[x + 1][y] == 1) {
neighbors.add(new Node(x + 1, y));
}
// 下
if (y < map[0].length - 1 && map[x][y + 1] == 1) {
neighbors.add(new Node(x, y + 1));
}
return neighbors;
}
/**
* 获取起点到当前节点的距离
*
* @param node 当前节点
* @param end 终点
* @return 返回距离值
*/
private static int getDistance(Node node, Node end) {
return Math.abs(node.x - end.x) + Math.abs(node.y - end.y);
}
/**
* 获取最短路径
*
* @param start 起点
* @param end 终点
* @return 返回最短路径
*/
private static List<Node> getPath(Node start, Node end) {
List<Node> path = new ArrayList<>();
// 从终点开始,沿着父节点一直往上找直到起点
Node node = end;
while (!node.equals(start)) {
path.add(node);
node = node.parent;
}
// 把起点加入路径
path.add(start);
// 反转路径
Collections.reverse(path);
return path;
}
/**
* 节点类
*/
private static 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 parent; // 父节点
public Node(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int compareTo(Node o) {
return this.f - o.f;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (obj instanceof Node) {
Node node = (Node) obj;
return this.x == node.x && this.y == node.y;
}
return false;
}
@Override
public int hashCode() {
return this.x * 31 + this.y;
}
}
}
```
希望对你有帮助!