Java语言实现A算法

A算法是一种启发式搜索算法,用于寻找从起点到终点的最短路径。以下是使用Java语言实现A算法的示例代码:

import java.util.*;

class Node {
    int x, y;
    Node parent;
    double gCost, hCost, fCost;

    public Node(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

public class AStarAlgorithm {
    private static final int[][] DIRECTIONS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};

    public static List<Node> findPath(int[][] grid, Node start, Node end) {
        PriorityQueue<Node> openList = new PriorityQueue<>(Comparator.comparingDouble(node -> node.fCost));
        Set<Node> closedList = new HashSet<>();

        start.gCost = 0;
        start.hCost = heuristic(start, end);
        start.fCost = start.gCost + start.hCost;

        openList.add(start);

        while (!openList.isEmpty()) {
            Node currentNode = openList.poll();
            closedList.add(currentNode);

            if (currentNode.equals(end)) {
                return buildPath(currentNode);
            }

            for (int[] direction : DIRECTIONS) {
                int newX = currentNode.x + direction[0];
                int newY = currentNode.y + direction[1];

                if (isValid(grid, newX, newY) && !closedList.contains(new Node(newX, newY))) {
                    Node neighbor = new Node(newX, newY);
                    neighbor.parent = currentNode;
                    neighbor.gCost = currentNode.gCost + 1;
                    neighbor.hCost = heuristic(neighbor, end);
                    neighbor.fCost = neighbor.gCost + neighbor.hCost;

                    if (!openList.contains(neighbor)) {
                        openList.add(neighbor);
                    }
                }
            }
        }

        return null; // No path found
    }

    private static boolean isValid(int[][] grid, int x, int y) {
        return x >= 0 && x < grid.length && y >= 0 && y < grid[0].length && grid[x][y] == 0;
    }

    private static double heuristic(Node a, Node b) {
        return Math.abs(a.x - b.x) + Math.abs(a.y - b.y);
    }

    private static List<Node> buildPath(Node node) {
        List<Node> path = new ArrayList<>();
        while (node != null) {
            path.add(node);
            node = node.parent;
        }
        Collections.reverse(path);
        return path;
    }

    public static void main(String[] args) {
        int[][] grid = {
            {0, 0, 0, 0, 0},
            {0, 1, 1, 1, 0},
            {0, 0, 0, 0, 0},
            {0, 1, 1, 1, 0},
            {0, 0, 0, 0, 0}
        };
        Node start = new Node(0, 0);
        Node end = new Node(4, 4);

        List<Node> path = findPath(grid, start, end);
        if (path != null) {
            for (Node node : path) {
                System.out.println("[" + node.x + ", " + node.y + "]");
            }
        } else {
            System.out.println("No path found");
        }
    }
}
 

这段代码定义了一个Node类,用于表示地图上的每个点。AStarAlgorithm类包含了实现A*算法的主要逻辑。findPath方法接受一个二维数组grid作为地图,以及起点和终点节点。它返回一个包含从起点到终点的路径的节点列表。如果没有找到路径,它将返回null

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的Java实现A*算法的示例代码: ``` import java.util.*; public class AStar { private static final int DIAGONAL_COST = 14; private static final int VERTICAL_COST = 10; private Queue<Node> openList; private Set<Node> closedSet; private Map<Node, Node> parentNodes; private Map<Node, Integer> gScore; private Map<Node, Integer> fScore; public AStar() { this.openList = new PriorityQueue<>(Comparator.comparingInt(Node::getfScore)); this.closedSet = new HashSet<>(); this.parentNodes = new HashMap<>(); this.gScore = new HashMap<>(); this.fScore = new HashMap<>(); } public List<Node> findPath(Node startNode, Node goalNode, Map<Node, List<Node>> adjacencyList) { openList.add(startNode); gScore.put(startNode, 0); fScore.put(startNode, calculateHeuristic(startNode, goalNode)); while (!openList.isEmpty()) { Node currentNode = openList.poll(); if (currentNode.equals(goalNode)) { return reconstructPath(currentNode); } closedSet.add(currentNode); for (Node neighbor : adjacencyList.get(currentNode)) { if (closedSet.contains(neighbor)) { continue; } int tentativeGScore = gScore.get(currentNode) + getDistance(currentNode, neighbor); if (!openList.contains(neighbor)) { openList.add(neighbor); } else if (tentativeGScore >= gScore.get(neighbor)) { continue; } parentNodes.put(neighbor, currentNode); gScore.put(neighbor, tentativeGScore); fScore.put(neighbor, tentativeGScore + calculateHeuristic(neighbor, goalNode)); } } return Collections.emptyList(); } private int getDistance(Node nodeA, Node nodeB) { int distanceX = Math.abs(nodeA.getX() - nodeB.getX()); int distanceY = Math.abs(nodeA.getY() - nodeB.getY()); if (distanceX > distanceY) { return DIAGONAL_COST * distanceY + VERTICAL_COST * (distanceX - distanceY); } else { return DIAGONAL_COST * distanceX + VERTICAL_COST * (distanceY - distanceX); } } private int calculateHeuristic(Node nodeA, Node nodeB) { return Math.abs(nodeA.getX() - nodeB.getX()) + Math.abs(nodeA.getY() - nodeB.getY()); } private List<Node> reconstructPath(Node currentNode) { List<Node> path = new ArrayList<>(); path.add(currentNode); while (parentNodes.containsKey(currentNode)) { currentNode = parentNodes.get(currentNode); path.add(0, currentNode); } return path; } } class Node { private final int x; private final int y; private int fScore; public Node(int x, int y) { this.x = x; this.y = y; this.fScore = Integer.MAX_VALUE; } public int getX() { return x; } public int getY() { return y; } public int getfScore() { return fScore; } public void setfScore(int fScore) { this.fScore = fScore; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Node node = (Node) o; return x == node.x && y == node.y; } @Override public int hashCode() { return Objects.hash(x, y); } } ``` 在这个实现中,`AStar`类包含了A*算法实现。在`findPath`方法中,我们传递起始节点、目标节点和一个邻接列表,该列表表示每个节点的相邻节点。 在A*算法实现中,我们使用几个数据结构来跟踪算法的状态。我们使用一个优先队列(`openList`)来保存所有尚未扩展的节点,该队列按f分数从低到高排序。我们还使用一个集合(`closedSet`)来跟踪已经扩展过的节点。我们使用两个Map(`parentNodes`和`gScore`)来跟踪每个节点的父节点和g分数。最后,我们使用一个Map(`fScore`)来跟踪每个节点的f分数。 在`findPath`方法的主循环中,我们从`openList`中获取具有最低f分数的节点,将其添加到`closedSet`中,并考虑其每个相邻节点。对于每个相邻节点,我们计算新的g分数并更新父节点,g分数和f分数。如果相邻节点不在`openList`中,则将其添加到`openList`中。否则,如果新的g分数不比现有的g分数更好,则跳过该节点。 如果我们成功找到目标节点,则返回重构的路径。在重构路径时,我们从目标节点开始,并沿着每个节点的父节点向后遍历,直到达到起始节点。这将产生一条路径,其中第一个节点是起始节点,最后一个节点是目标节点。 在这个示例代码中,我们只考虑了水平和垂直移动,而没有考虑对角线移动。我们还假设每个节点都是相同的大小。如果需要考虑对角线移动或不同大小的节点,请相应地更改`getDistance`和`calculateHeuristic`方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亚丁号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值