java语言该怎么实现呢?
时间: 2024-01-30 09:06:53 浏览: 18
以下是Java语言的示例代码:
```java
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.PriorityQueue;
import java.util.Set;
public class AStar {
private final int[][] directions = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}}; // 四个方向
private final int[][] grid; // 网格
private final int rows; // 行数
private final int cols; // 列数
private final int[] start; // 起点坐标
private final int[] end; // 终点坐标
private int heuristic(int[] a, int[] b) { // 启发式函数
return Math.abs(b[0] - a[0]) + Math.abs(b[1] - a[1]);
}
private boolean isInGrid(int row, int col) { // 判断坐标是否在网格内
return row >= 0 && row < rows && col >= 0 && col < cols;
}
private boolean isObstacle(int row, int col) { // 判断坐标是否为障碍物
return grid[row][col] == 1;
}
private List<int[]> getNeighbors(int row, int col) { // 获取相邻节点列表
List<int[]> neighbors = new ArrayList<>();
for (int[] dir : directions) {
int r = row + dir[0];
int c = col + dir[1];
if (isInGrid(r, c) && !isObstacle(r, c)) {
neighbors.add(new int[]{r, c});
}
}
return neighbors;
}
public List<int[]> findPath() { // A*算法主函数
PriorityQueue<int[]> openList = new PriorityQueue<>(Comparator.comparingInt(node -> node[2])); // open列表,按f值排序
Set<String> closeSet = new HashSet<>(); // close列表,存储已访问的节点
openList.offer(new int[]{start[0], start[1], 0, heuristic(start, end), -1}); // 将起点加入open列表
while (!openList.isEmpty()) {
int[] current = openList.poll(); // 选取f值最小的节点作为当前节点
if (current[0] == end[0] && current[1] == end[1]) { // 到达终点,回溯得到路径
List<int[]> path = new ArrayList<>();
int curr = current[4];
while (curr != -1) {
path.add(new int[]{curr / cols, curr % cols});
curr = current[4] = curr / cols;
}
return path;
}
closeSet.add(current[0] + "," + current[1]); // 将当前节点加入close列表
for (int[] neighbor : getNeighbors(current[0], current[1])) { // 处理相邻节点
String key = neighbor[0] + "," + neighbor[1];
if (closeSet.contains(key)) { // 如果相邻节点已经在close列表中,忽略它
continue;
}
int g = current[2] + 1; // 计算相邻节点的g值
int h = heuristic(neighbor, end); // 计算相邻节点的h值
int f = g + h; // 计算相邻节点的f值
int idx = neighbor[0] * cols + neighbor[1];
for (int[] node : openList) { // 如果相邻节点已经在open列表中,更新它的f值和父节点
if (node[4] == idx) {
if (f < node[2] + node[3]) {
node[2] = g;
node[3] = h;
node[4] = current[0] * cols + current[1];
}
break;
}
}
if (!openList.contains(neighbor)) { // 否则,将相邻节点加入open列表中
openList.offer(new int[]{neighbor[0], neighbor[1], g, h, current[0] * cols + current[1]});
}
}
}
return new ArrayList<>(); // open列表为空,无法找到路径
}
public AStar(int[][] grid, int[] start, int[] end) { // 构造函数
this.grid = grid;
this.rows = grid.length;
this.cols = grid[0].length;
this.start = start;
this.end = end;
}
}
```
调用示例:
```java
public class Main {
public static void main(String[] args) {
int[][] grid = {{0, 0, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 0, 0}}; // 网格
int[] start = {0, 0}; // 起点坐标
int[] end = {4, 4}; // 终点坐标
AStar aStar = new AStar(grid, start, end);
List<int[]> path = aStar.findPath();
for (int[] node : path) {
System.out.println(node[0] + "," + node[1]); // 打印路径节点坐标
}
}
}
```