帮我写个A*搜索算法java代码
时间: 2023-09-06 16:13:49 浏览: 93
A*算法代码
4星 · 用户满意度95%
### 回答1:
好的,以下是A*搜索算法的Java代码:
```
import java.util.*;
public class AStar {
static class Node {
int x;
int y;
int f;
int g;
int h;
Node parent;
Node(int x, int y) {
this.x = x;
this.y = y;
}
}
public static List<Node> findPath(int[][] map, int startX, int startY, int endX, int endY) {
List<Node> openList = new ArrayList<>();
List<Node> closeList = new ArrayList<>();
Node startNode = new Node(startX, startY);
Node endNode = new Node(endX, endY);
openList.add(startNode);
while (openList.size() > 0) {
Node curNode = openList.get(0);
for (int i = 1; i < openList.size(); i++) {
if (openList.get(i).f < curNode.f) {
curNode = openList.get(i);
}
}
openList.remove(curNode);
closeList.add(curNode);
if (curNode.x == endX && curNode.y == endY) {
return traceBackPath(curNode);
}
List<Node> neighbors = getNeighbors(curNode, map, endNode);
for (Node neighbor : neighbors) {
if (closeList.contains(neighbor)) {
continue;
}
int g = curNode.g + 1;
int h = getHeuristic(neighbor, endNode);
int f = g + h;
if (!openList.contains(neighbor) || f < neighbor.f) {
neighbor.f = f;
neighbor.g = g;
neighbor.h = h;
neighbor.parent = curNode;
if (!openList.contains(neighbor)) {
openList.add(neighbor);
}
}
}
}
return null;
}
private static List<Node> traceBackPath(Node node) {
List<Node> path = new ArrayList<>();
while (node != null) {
path.add(0, node);
node = node.parent;
}
return path;
}
private static int getHeuristic(Node curNode, Node endNode) {
int dx = Math.abs(curNode.x - endNode.x);
int dy = Math.abs(curNode.y - endNode.y);
return dx + dy;
}
private static List<Node> getNeighbors(Node curNode, int[][] map, Node endNode) {
List<Node> neighbors = new ArrayList<>();
int x = curNode.x;
int y = curNode.y;
if (x > 0 && map[x - 1][y] == 0) {
### 回答2:
A*搜索算法是一种常用的启发式搜索算法,用于求解路径规划问题。它基于广度优先搜索算法,并给每个搜索节点增加一个启发式估价函数,通过估价函数来评估当前节点到目标节点的代价。
以下是一个简单的A*搜索算法的Java代码示例:
```java
import java.util.*;
class Node {
int x; // 节点的x坐标
int y; // 节点的y坐标
int g; // 从初始节点到当前节点的实际代价
int h; // 从当前节点到目标节点的估计代价
int f; // g和h的和,表示当前节点的总代价
Node parent; // 当前节点的父节点
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
public class AStarSearch {
private static final int[][] GRID = { // 地图数据,0表示可通行,1表示障碍物
{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 static final int[][] DIRECTIONS = { // 移动方向
{-1, 0}, // 上
{1, 0}, // 下
{0, -1}, // 左
{0, 1} // 右
};
private static int heuristic(Node current, Node goal) { // 启发式函数,这里使用曼哈顿距离
return Math.abs(current.x - goal.x) + Math.abs(current.y - goal.y);
}
private static List<Node> getNeighbors(Node current) { // 获得当前节点的邻居节点
List<Node> neighbors = new ArrayList<>();
for (int[] direction : DIRECTIONS) {
int newX = current.x + direction[0];
int newY = current.y + direction[1];
if (newX < 0 || newX >= GRID.length || newY < 0 || newY >= GRID[0].length) {
continue; // 忽略越界的邻居节点
}
if (GRID[newX][newY] == 0) { // 只考虑可通行的邻居节点
Node neighbor = new Node(newX, newY);
neighbors.add(neighbor);
}
}
return neighbors;
}
private static List<Node> reconstructPath(Node goal) { // 从目标节点回溯路径
List<Node> path = new ArrayList<>();
Node current = goal;
while (current != null) {
path.add(current);
current = current.parent;
}
Collections.reverse(path);
return path;
}
public static List<Node> findPath(Node start, Node goal) {
PriorityQueue<Node> openNodes = new PriorityQueue<>((n1, n2) -> n1.f - n2.f);
Set<Node> closedNodes = new HashSet<>();
start.g = 0;
start.h = heuristic(start, goal);
start.f = start.g + start.h;
openNodes.add(start);
while (!openNodes.isEmpty()) {
Node current = openNodes.poll();
if (current.equals(goal)) {
return reconstructPath(current);
}
closedNodes.add(current);
List<Node> neighbors = getNeighbors(current);
for (Node neighbor : neighbors) {
if (closedNodes.contains(neighbor)) {
continue;
}
int tentativeG = current.g + 1;
boolean isNewPath = false;
if (!openNodes.contains(neighbor)) {
isNewPath = true;
neighbor.h = heuristic(neighbor, goal);
openNodes.add(neighbor);
} else if (tentativeG < neighbor.g) {
isNewPath = true;
}
if (isNewPath) {
neighbor.g = tentativeG;
neighbor.f = neighbor.g + neighbor.h;
neighbor.parent = current;
}
}
}
return null; // 未找到路径
}
public static void main(String[] args) {
Node start = new Node(0, 0);
Node goal = new Node(4, 4);
List<Node> path = findPath(start, goal);
if (path != null) {
for (Node node : path) {
System.out.println("[" + node.x + ", " + node.y + "]");
}
} else {
System.out.println("未找到路径");
}
}
}
```
这段代码实现了一个简单的A*搜索算法,用于在一个5x5的网格地图中寻找从起始节点(0, 0)到目标节点(4, 4)的最短路径。其中,地图数据存储在一个二维数组中,0表示可通行,1表示障碍物。A*搜索算法会根据地图数据和启发式函数,通过优先队列进行搜索,最终返回找到的最短路径。如果未找到路径,则返回null。
### 回答3:
A*搜索算法是一种常用于图的最短路径搜索的算法,它基于贪心思想,在综合考虑了顶点之间的距离和启发式函数的值后,选择最有可能导致最短路径的点进行搜索。以下是一个简单实现A*搜索算法的Java代码:
```java
import java.util.*;
class Node implements Comparable<Node> {
int x; // 顶点的横坐标
int y; // 顶点的纵坐标
int g; // 从起点到当前顶点的代价
int h; // 从当前顶点到目标顶点的预估代价
int f; // g + h,表示从起点经过当前顶点到目标顶点的总代价
Node parent; // 父节点,表示当前顶点是从哪个顶点扩展而来的
public Node(int x, int y, int g, int h) {
this.x = x;
this.y = y;
this.g = g;
this.h = h;
this.f = g + h;
this.parent = null;
}
@Override
public int compareTo(Node other) {
return Integer.compare(this.f, other.f);
}
}
public class AStarSearch {
private static final int[] dx = {-1, 0, 1, 0}; // 上、右、下、左的移动方向
private static final int[] dy = {0, 1, 0, -1};
public static ArrayList<Node> findPath(int[][] grid, Node start, Node end) {
PriorityQueue<Node> openHeap = new PriorityQueue<>();
HashSet<Node> closedSet = new HashSet<>();
openHeap.add(start);
while (!openHeap.isEmpty()) {
Node current = openHeap.poll();
closedSet.add(current);
if (current.x == end.x && current.y == end.y) {
// 找到了目标顶点,返回路径
ArrayList<Node> path = new ArrayList<>();
while (current != null) {
path.add(current);
current = current.parent;
}
Collections.reverse(path);
return path;
}
for (int i = 0; i < 4; i++) {
int nx = current.x + dx[i];
int ny = current.y + dy[i];
if (nx >= 0 && nx < grid.length && ny >= 0 && ny < grid[0].length && grid[nx][ny] == 0) {
int ng = current.g + 1;
int nh = Math.abs(nx - end.x) + Math.abs(ny - end.y);
int nf = ng + nh;
Node next = new Node(nx, ny, ng, nh);
boolean isOpen = openHeap.contains(next);
boolean isClosed = closedSet.contains(next);
if (!isOpen && !isClosed) {
openHeap.add(next);
next.parent = current;
} else if (isOpen && ng < next.g) {
openHeap.remove(next);
openHeap.add(next);
next.parent = current;
}
}
}
}
return null; // 如果无法到达目标顶点,返回空路径
}
public static void main(String[] args) {
int[][] grid = {
{0, 0, 0, 0},
{0, 1, 1, 0},
{0, 0, 0, 0},
{0, 0, 0, 0}
};
Node start = new Node(0, 0, 0, 0);
Node end = new Node(3, 3, 0, 0);
ArrayList<Node> path = findPath(grid, start, end);
if (path != null) {
for (Node node : path) {
System.out.println("(" + node.x + ", " + node.y + ")");
}
} else {
System.out.println("Cannot find path.");
}
}
}
```
这是一个简单的A*搜索算法的实现,其中涉及到节点类Node,使用优先队列存放待扩展的节点,并通过HashSet记录已经扩展过的节点。具体实现包括寻找最短路径的findPath方法、计算启发式函数值的估价函数、启发式函数值的排序规则等。代码中给出了一个示例的地图,起点为(0, 0),终点为(3, 3),运行程序会输出从起点到终点的最短路径。
阅读全文