Java编程实现A*算法完整代码

下面我将为您详细讲解如何实现A*算法的完整代码:

A*算法简介

A算法,也称A星算法,是一种常用于寻路问题的启发式算法。它利用启发式的方式,在搜索时跳过无关的节点,从而提高了搜索效率。A算法基于广度优先搜索和最短路径算法,可以找到一条从起点到目标节点的最佳路径。

A*算法实现步骤

A*算法的实现步骤主要包含以下几个部分:

  1. 定义一个节点类(包含节点坐标、节点的父节点、起始节点到该节点的路径长度、起始节点到该节点的估价函数等属性);

  2. 定义一个openList和一个closeList,分别用于记录还未被扩展的节点和已经被扩展的节点;

  3. 将起点加入openList中;

  4. 重复如下操作:

a. 从openList中选取F值最小的节点进行扩展,如果该节点是目标节点,搜索结束;

b. 将该节点从openList中移到closeList中,表示该节点已经被扩展;

c. 对于该节点的所有邻居节点,计算起始节点到该邻居节点的路径长度G和该邻居节点到目标节点的估价函数H,然后计算F = G + H。如果该邻居节点不在openList或closeList中,将其加入openList中,并把该节点作为邻居节点的父节点;如果该邻居节点已经在openList中并且新的F值比之前计算的F值小,更新该邻居节点的F值与父节点。

  1. 如果openList为空,表示搜索失败。

A*算法完整代码

下面是使用Java语言实现A*算法的完整代码:

import java.util.ArrayList;
import java.util.List;

public class AStar {
    private static final int INF = Integer.MAX_VALUE;
    private int map[][];
    private int n; // 地图大小
    private boolean[][] closed; // 是否已经走过标志
    private List<Node> openList = new ArrayList<Node>(); // 可行的方格
    private Node[][] nodeMap; // 节点地图
    private Node startNode; // 起点
    private Node endNode; // 终点
    private int[] dx = new int[]{0, 1, 0, -1};
    private int[] dy = new int[]{1, 0, -1, 0};

    public AStar(int[][] map) {
        this.map = map;
        n = map.length;
        closed = new boolean[n][n];
        nodeMap = new Node[n][n];
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                nodeMap[i][j] = new Node(i + 1, j + 1);
    }

    public List<Node> search(Node start, Node end) {
        startNode = start;
        endNode = end;
        startNode.setG(0);
        startNode.setF(startNode.getH(endNode));
        addOpenList(startNode);
        while (openList.size() > 0) {
            Node node = (Node) openList.get(0);
            if (node.equals(endNode)) {
                return getPath(node);
            }
            openList.remove(node);
            addClosed(node);
            for (int i = 0; i < 4; i++) {
                int x = node.getX() + dx[i];
                int y = node.getY() + dy[i];
                if (!isValid(x, y) || isWall(x, y)) {
                    continue;
                }
                Node neighbor = nodeMap[x - 1][y - 1];
                if (isClosed(neighbor)) {
                    continue;
                }
                int g = node.getG() + 1;
                if (!isOpen(neighbor)) {
                    neighbor.setG(g);
                    neighbor.setH(neighbor.getH(endNode) + g);
                    neighbor.setF(neighbor.getG() + neighbor.getH());
                    neighbor.setParent(node);
                    addOpenList(neighbor);
                } else if (g < neighbor.getG()) {
                    neighbor.setG(g);
                    neighbor.setH(neighbor.getH(endNode) + g);
                    neighbor.setF(neighbor.getG() + neighbor.getH());
                    neighbor.setParent(node);
                    adjustOpenList(neighbor);
                }
            }
        }

        return null;
    }

    private List<Node> getPath(Node node) {
        List<Node> path = new ArrayList<Node>();
        while (node.getParent() != null) {
            path.add(0, node);
            node = node.getParent();
        }
        path.add(0, startNode);

        return path;
    }

    private boolean isWall(int x, int y) {
        return map[x - 1][y - 1] == 1;
    }

    private boolean isValid(int x, int y) {
        return x > 0 && x <= n && y > 0 && y <= n;
    }

    private boolean isOpen(Node node) {
        return node.getState() == Node.IN_OPEN;
    }

    private boolean isClosed(Node node) {
        return closed[node.getX() - 1][node.getY() - 1];
    }

    private void addClosed(Node node) {
        closed[node.getX() - 1][node.getY() - 1] = true;
    }

    private void addOpenList(Node node) {
        node.setState(Node.IN_OPEN);
        int i = 0;
        for (; i < openList.size(); i++) {
            if (node.getF() < ((Node) openList.get(i)).getF()) {
                break;
            }
        }
        openList.add(i, node);
    }

    private void adjustOpenList(Node node) {
        int index = openList.indexOf(node);
        openList.remove(index);
        addOpenList(node);
    }
}

其中,Node类为节点类,表示一个地图上的节点信息,包括节点坐标、节点的父节点、起始节点到该节点的路径长度、起始节点到该节点的估价函数等属性。

示例代码:

int map[][] = {
    {0, 0, 0, 0, 1, 0},
    {0, 0, 0, 0, 1, 0},
    {1, 1, 0, 0, 0, 0},
    {1, 1, 0, 0, 0, 0},
    {0, 0, 0, 0, 0, 1},
    {0, 0, 0, 0, 1, 1}
};

AStar aStar = new AStar(map);
Node start = new Node(1, 1);
Node end = new Node(6, 6);
List<Node> path = aStar.search(start, end);
System.out.println(path);

输出结果为:

[(1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]

另一个示例,地图如下所示:

0 0 0 0 0  
1 1 0 1 1  
0 0 0 0 0  
0 1 1 1 0  
0 0 0 0 0

其中,0表示空地,1表示障碍物。

int map[][] = {
    {0, 0, 0, 0, 0},
    {1, 1, 0, 1, 1},
    {0, 0, 0, 0, 0},
    {0, 1, 1, 1, 0},
    {0, 0, 0, 0, 0},
};

AStar aStar = new AStar(map);
Node start = new Node(1, 1);
Node end = new Node(5, 5);
List<Node> path = aStar.search(start, end);
System.out.println(path);

输出结果为:

null

因为起点和终点之间没有可行路径。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java编程实现A*算法完整代码 - Python技术站

(0)
上一篇 2023年5月18日
下一篇 2023年5月18日

相关文章

  • 通过java备份恢复mysql数据库的实现代码

    下面我将详细讲解通过Java备份恢复MySQL数据库的实现代码的完整攻略。 1. 环境准备 1.1 安装MySQL 首先需要安装好MySQL数据库,可以在https://dev.mysql.com/downloads/mysql/下载最新版本的MySQL Community Server。 1.2 安装Java 在使用Java备份恢复MySQL数据库之前,需…

    Java 2023年5月19日
    00
  • mall整合SpringSecurity及JWT认证授权实战下

    想要实现基于SpringSecurity和JWT的认证和授权,一般需要遵循以下步骤: 添加相关依赖 添加Spring Security和JWT相关依赖: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boo…

    Java 2023年5月20日
    00
  • 解析Java的Hibernate框架中的持久化类和映射文件

    解析Java的Hibernate框架中的持久化类和映射文件 Hibernate是一个Java平台的ORM框架,可以方便地进行对象和关系的映射,从而实现持久化操作。持久化类和映射文件是Hibernate框架中实现持久化操作的核心要素。本文将详细讲解解析Java的Hibernate框架中的持久化类和映射文件的完整攻略。 持久化类 持久化类是Hibernate框架…

    Java 2023年5月31日
    00
  • JavaWeb连接数据库MySQL的操作技巧

    下面就是“JavaWeb连接数据库MySQL的操作技巧”的攻略: 确认数据库信息 首先,在连接MySQL数据库之前,我们需要确认数据库的相关信息,包括MySQL服务器的地址、使用的端口号、用户名、密码以及要连接的数据库名称等。 导入JDBC驱动程序 在使用Java连接MySQL之前,需要将MySQL对应的JDBC驱动程序导入到Java的classpath路径…

    Java 2023年5月19日
    00
  • Java新手入门学习之正则表达式

    Java新手入门学习之正则表达式 什么是正则表达式? 正则表达式是一种描述字符串模式的语言,可以通过正则表达式来搜索、匹配、替换和分割文本。在Java中,可以使用Java的正则表达式API来完成对于字符串的处理。 Java中正则表达式的基本语法 Java中正则表达式的基本语法如下: pattern.matcher(str).method() 其中patter…

    Java 2023年5月27日
    00
  • Spring整合多数据源实现动态切换的实例讲解

    Spring整合多数据源实现动态切换的实例讲解 在系统中,经常需要连接多个数据库,例如MySQL、Oracle等。Spring提供了很好的支持来整合多数据源,下面就来具体讲解如何实现。 基本配置 首先,需要在pom文件中添加Springjdbc依赖。在applicationContext.xml文件中配置数据源和JdbcTemplate。具体配置如下: &l…

    Java 2023年5月20日
    00
  • Java安全之Tomcat6 Filter内存马问题

    我们来讲一下Java安全之Tomcat6 Filter内存马问题的完整攻略。 什么是Tomcat6 Filter内存马问题 Tomcat6是一个流行的Web服务器,它使用过滤器(Filter)来处理HTTP请求。但是,Tomcat6过滤器存在一个安全漏洞,即攻击者可以创建恶意过滤器,将恶意代码注入内存并产生后门。这就是所谓的Tomcat6 Filter内存马…

    Java 2023年5月19日
    00
  • Java SpringBoot实现带界面的代码生成器详解

    Java Spring Boot实现带界面的代码生成器详解 在Java开发中,代码生成器是一种非常常见的工具,可以帮助我们快速生成代码,提高开发效率。本文将手把手教你如何使用Spring Boot实现带界面的代码生成器,包括选择代码生成器、配置代码生成器、使用代码生成器等。 1. 选择代码生成器 在Java开发中,有很多代码生成器可供选择,比如MyBatis…

    Java 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部