java 实现a*算法定义邻居节点只包含上下左右四个方向
时间: 2024-05-05 07:21:12 浏览: 5
好的,下面是 Java 实现 A* 算法,定义邻居节点只包含上下左右四个方向的示例代码:
```java
import java.util.*;
public class AStar {
private static final int[][] DIRECTIONS = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}}; // 上下左右四个方向
private PriorityQueue<Node> openSet; // 存放未探索的节点
private Set<Node> closedSet; // 存放已探索的节点
private int[][] grid; // 地图,0 表示可以通过,1 表示障碍物
private int startRow; // 起点的行号
private int startCol; // 起点的列号
private int endRow; // 终点的行号
private int endCol; // 终点的列号
public AStar(int[][] grid, int startRow, int startCol, int endRow, int endCol) {
this.openSet = new PriorityQueue<>(Comparator.comparingInt(node -> node.f));
this.closedSet = new HashSet<>();
this.grid = grid;
this.startRow = startRow;
this.startCol = startCol;
this.endRow = endRow;
this.endCol = endCol;
}
public List<Node> search() {
Node startNode = new Node(startRow, startCol);
startNode.g = 0;
startNode.h = heuristic(startRow, startCol);
startNode.f = startNode.g + startNode.h;
openSet.offer(startNode);
while (!openSet.isEmpty()) {
Node currentNode = openSet.poll();
if (currentNode.row == endRow && currentNode.col == endCol) {
return getPath(currentNode);
}
closedSet.add(currentNode);
for (int[] direction : DIRECTIONS) {
int newRow = currentNode.row + direction[0];
int newCol = currentNode.col + direction[1];
if (newRow < 0 || newRow >= grid.length || newCol < 0 || newCol >= grid[0].length
|| grid[newRow][newCol] == 1) {
continue;
}
Node neighbor = new Node(newRow, newCol);
if (closedSet.contains(neighbor)) {
continue;
}
int tentativeGScore = currentNode.g + 1;
if (!openSet.contains(neighbor)) {
neighbor.h = heuristic(newRow, newCol);
openSet.offer(neighbor);
} else if (tentativeGScore >= neighbor.g) {
continue;
}
neighbor.parent = currentNode;
neighbor.g = tentativeGScore;
neighbor.f = neighbor.g + neighbor.h;
}
}
return null;
}
private List<Node> getPath(Node node) {
List<Node> path = new ArrayList<>();
Node currentNode = node;
while (currentNode != null) {
path.add(currentNode);
currentNode = currentNode.parent;
}
Collections.reverse(path);
return path;
}
private int heuristic(int row, int col) {
return Math.abs(row - endRow) + Math.abs(col - endCol);
}
private static class Node {
int row;
int col;
int f; // f = g + h
int g; // 起点到该节点的距离
int h; // 该节点到终点的估计距离
Node parent;
Node(int row, int col) {
this.row = row;
this.col = col;
}
@Override
public int hashCode() {
return Objects.hash(row, col);
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null || getClass() != obj.getClass()) {
return false;
}
Node node = (Node) obj;
return row == node.row && col == node.col;
}
}
}
```
使用时只需传入地图、起点和终点的坐标,调用 `search` 方法即可得到一条从起点到终点的最短路径。例如:
```java
int[][] grid = {
{0, 0, 0, 0},
{0, 1, 1, 0},
{0, 0, 0, 0},
{0, 1, 0, 0},
{0, 0, 0, 1},
{0, 1, 0, 0}
};
int startRow = 0;
int startCol = 0;
int endRow = 5;
int endCol = 3;
AStar aStar = new AStar(grid, startRow, startCol, endRow, endCol);
List<AStar.Node> path = aStar.search();
if (path != null) {
for (AStar.Node node : path) {
System.out.println("(" + node.row + ", " + node.col + ")");
}
} else {
System.out.println("No path found.");
}
```