Java A*搜索

A(A-star)搜索是一种启发式搜索算法,通常用于路径查找和图搜索问题。它结合了Dijkstra算法的优点和最佳优先搜索的优点,通过使用启发式函数来引导搜索过程,使其能够更快地找到最短路径。以下是一个Java实现的A搜索算法的示例。

在这个示例中,我们将使用一个二维网格来表示搜索空间,每个网格单元可以是一个可通过的节点或障碍物。启发式函数将使用曼哈顿距离(在二维网格中,两个节点之间的水平和垂直距离之和)。

import java.util.*;  
  
class Node implements Comparable<Node> {  
    int x, y, gCost, hCost, fCost;  
    Node parent;  
  
    public Node(int x, int y) {  
        this.x = x;  
        this.y = y;  
        this.gCost = 0;  
        this.hCost = 0;  
        this.fCost = 0;  
        this.parent = null;  
    }  
  
    @Override  
    public int compareTo(Node other) {  
        return Integer.compare(this.fCost, other.fCost);  
    }  
  
    @Override  
    public boolean equals(Object obj) {  
        if (this == obj) return true;  
        if (obj == null || getClass() != obj.getClass()) return false;  
        Node node = (Node) obj;  
        return x == node.x && y == node.y;  
    }  
  
    @Override  
    public int hashCode() {  
        return Objects.hash(x, y);  
    }  
}  
  
public class AStarSearch {  
    private static final int[][] DIRECTIONS = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};  
    private static final int OBSTACLE = 1;  
    private static final int EMPTY = 0;  
  
    public static List<Node> aStarSearch(int[][] grid, Node start, Node goal) {  
        PriorityQueue<Node> openSet = new PriorityQueue<>();  
        Set<Node> closedSet = new HashSet<>();  
        Map<Node, Node> cameFrom = new HashMap<>();  
        Map<Node, Integer> gScore = new HashMap<>();  
  
        start.gCost = 0;  
        start.hCost = heuristic(start, goal);  
        start.fCost = start.gCost + start.hCost;  
        openSet.add(start);  
  
        while (!openSet.isEmpty()) {  
            Node current = openSet.poll();  
  
            if (current.equals(goal)) {  
                return reconstructPath(cameFrom, current);  
            }  
  
            closedSet.add(current);  
  
            for (int[] direction : DIRECTIONS) {  
                int neighborX = current.x + direction[0];  
                int neighborY = current.y + direction[1];  
  
                if (neighborX < 0 || neighborX >= grid.length || neighborY < 0 || neighborY >= grid[0].length || grid[neighborX][neighborY] == OBSTACLE) {  
                    continue;  
                }  
  
                Node neighbor = new Node(neighborX, neighborY);  
  
                if (closedSet.contains(neighbor)) {  
                    continue;  
                }  
  
                int tentativeGCost = gScore.get(current) + 1;  
  
                if (!openSet.contains(neighbor) || tentativeGCost < gScore.getOrDefault(neighbor, Integer.MAX_VALUE)) {  
                    cameFrom.put(neighbor, current);  
                    gScore.put(neighbor, tentativeGCost);  
                    neighbor.gCost = tentativeGCost;  
                    neighbor.hCost = heuristic(neighbor, goal);  
                    neighbor.fCost = neighbor.gCost + neighbor.hCost;  
                    if (!openSet.contains(neighbor)) {  
                        openSet.add(neighbor);  
                    }  
                }  
            }  
        }  
  
        return Collections.emptyList(); // No path found  
    }  
  
    private static int heuristic(Node a, Node b) {  
        return Math.abs(a.x - b.x) + Math.abs(a.y - b.y); // Manhattan distance  
    }  
  
    private static List<Node> reconstructPath(Map<Node, Node> cameFrom, Node current) {  
        List<Node> path = new ArrayList<>();  
        while (current != null) {  
            path.add(current);  
            current = cameFrom.get(current);  
        }  
        Collections.reverse(path);  
        return path;  
    }  
  
    public static void main(String[] args) {  
        int[][] grid = {  
                {EMPTY, EMPTY, EMPTY, EMPTY, EMPTY},  
                {EMPTY, OBSTACLE, EMPTY, OBSTACLE, EMPTY},  
                {EMPTY, EMPTY, EMPTY, EMPTY, EMPTY},  
                {EMPTY, OBSTACLE, EMPTY, OBSTACLE, EMPTY},  
                {EMPTY, EMPTY, EMPTY, EMPTY, EMPTY}  
        };  
  
        Node start = new Node(0, 0);  
        Node goal = new Node(4, 4);  
  
        List<Node> path = aStarSearch(grid, start, goal);  
  
        if (!path.isEmpty()) {  
            System.out.println("Path found:");  
            for (Node node : path) {  
                System.out.println("(" + node.x + ", " + node.y + ")");  
            }  
        } else {  
            System.out.println("No path found.");  
        }  
    }  
}

代码解释

  1. Node 类:表示网格中的一个节点,包含坐标 (x, y)gCost(从起点到当前节点的实际代价),hCost(启发式代价),fCost(总代价,gCost + hCost),以及父节点 parent

  2. AStarSearch 类:包含A*搜索算法的实现。

  3. aStarSearch 方法:这是A*搜索算法的核心。它使用优先队列 openSet 来存储待处理的节点,并根据节点的 fCost 进行排序。closedSet 存储已经处理过的节点,cameFrom 用于路径重构,gScore 存储每个节点的 gCost

  4. heuristic 方法:计算启发式代价,这里使用曼哈顿距离。

  5. reconstructPath 方法:根据 cameFrom 映射重构路径。

  6. main 方法:定义了一个简单的网格,并调用 aStarSearch 方法查找从起点到终点的路径。

这个示例是一个基本的A*搜索算法实现,可以根据具体需求进行扩展和优化。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值