A 星寻路算法代码 --java 版(A* 搜索算法)

本贴最后更新于 1487 天前,其中的信息可能已经物是人非
import java.util.*;

/**
 * @author sunze
 * @date 2020/10/26 4:55 下午
 */
public class Astar {

    /**
     * 公式 :F=G+H
     *
     * 含义:G:起点到当前点的距离 H :当前点到终点的距离。
     *
     * F:等于前面两者之和,用于判定下一节点该往哪里走。如下图,此时,我们先不考虑障碍物先。
     */

    /**
     * 初始化地图
     */
    public static final String[][] MAP={
    //              0  1  2  3  4  5  6  7  8
            /*0*/ { "0", "0", "0", "0", "0", "0", "0", "0", "0" },
            /*1*/ { "0", "0", "0", "0", "0", "0", "0", "0", "0" },
            /*2*/ { "0", "0", "0", "0", "0", "0", "0", "0", "0" },
            /*3*/ { "0", "0", "0", "1", "0", "0", "0", "0", "0" },
            /*4*/ { "0", "0", "0", "1", "0", "0", "0", "0", "0" },
            /*5*/ { "0", "0", "0", "1", "0", "0", "0", "0", "0" },
            /*6*/ { "0", "0", "0", "1", "0", "0", "0", "0", "0" },
            /*7*/ { "0", "0", "0", "1", "0", "0", "0", "0", "0" },
            /*8*/ { "0", "0", "0", "1", "0", "0", "0", "0", "0" }
    };

    /**
     * 横着走所需能量
     */
    public static final Integer HORIZONTAL_STEP= 10;
    /**
     * 斜着走所需能量
     */
    public static final Integer OBLIQUE_STEP= 14;

    /**
     * 可使用列表
     */
    public static List<Node> OPEN=new ArrayList<>();
    /**
     * 不可使用列表
     */
    public static List<Node> CLOSE=new ArrayList<>();

    private static final Node END_NODE=new Node(6,7);
    private static final Node START_NODE=new Node(7,1);

//    private static void
//                0  1  2  3  4  5  6  7  8
    //    /*0*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    //    /*1*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    //    /*2*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    //    /*3*/ { 0, 0, 0, 1, 0, 0, 0, 0, 0 },
    //    /*4*/ { 0, 0, 0, 1, 0, 0, 0, 0, 0 },
    //    /*5*/ { 0, 0, 0, 1, 0, 0, 0, 0, 0 },
    //    /*6*/ { 0, 0, 0, 1, 0, 0, 0, 0, 0 },
    //    /*7*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 },
    //    /*8*/ { 0, 0, 0, 0, 0, 0, 0, 0, 0 }
    public static void main(String[] args) {
        //将开始节点加入可使用列表
        START_NODE.parent=START_NODE;
        OPEN.add(START_NODE);
        while (CLOSE.indexOf(END_NODE)<0){
            //查找open中的F值最小的节点
            Node minFNodeInOpenList = OPEN.remove(0);
            //将这个节点放到close节点中
            CLOSE.add(0,minFNodeInOpenList);
            //获取这个节点周围的可移动节点并放入到open中
            findNeighborNodes(minFNodeInOpenList);
        }

        //回溯查找最短路径
        Node temp = CLOSE.get(0);
        List<Node> result = new ArrayList<>();
        while (temp.parent!=null&&temp!=temp.parent){
            result.add(0,temp);
            temp=temp.parent;
        }
        result.add(0,START_NODE);
        String[][] resultMap = MAP;
        for (Node node : result) {
            resultMap[node.x][node.y]="$";
        }
        showResult(resultMap);
        System.out.println("-------------------");
        String[][] tempMap = MAP;
        for (Node node : CLOSE) {
            System.out.println(node.x+":"+node.y);
            tempMap[node.x][node.y]="*";
        }
        showResult(tempMap);
    }


    private static void showResult(String[][] arr){
        for (int i = 0, j = 0; i < arr.length;) {
            System.out.print(arr[i][j]+" ");
            j++;
            if (j >= arr[i].length) {
                i++;
                j = 0;
                System.out.print("\n");
            }
        }
    }

    /**
     * 包括斜着周围一共有8个节点
     * @param currentNode
     */
    public static void findNeighborNodes(Node currentNode) {
        List<Node> temp = new ArrayList<>();
        int x = currentNode.x;
        int y = currentNode.y;
        //
        for (int i=x-1>=0?x-1:0;i<=(x+1<=8?x+1:8);i++){
            for (int j=y-1>=0?y-1:0;j<=(y+1<=8?y+1:8);j++){
                //去除当前节点并且此节点不在close列表中
                if(!(i==x&&j==y)&&CLOSE.indexOf(new Node(i,j))<0&&OPEN.indexOf(new Node(i,j))<0){
                    //除去障碍物
                    if(MAP[i][j]!="1"){
                        //计算F值
                        Node node = new Node(i, j);
                        node.parent=currentNode;
                        int g = calcG(currentNode, node);
                        int h = calcH(END_NODE, node);
                        node.H=h;
                        node.G=g;
                        node.calcF();
                        temp.add(node);
                    }
                }
            }
        }
        OPEN.addAll(temp);
        Collections.sort(OPEN);
    }

    private static int calcG(Node start, Node node) {
        if(start.x==node.x||start.y==node.y){
            return HORIZONTAL_STEP+node.parent.G;
        }else{
            return OBLIQUE_STEP+node.parent.G;
        }
    }

    /**
     *     这个是最简单粗暴的计算H值得方法,当然还有其它方法,这里先理解AStar的思想先,以后可以自己改进这个计算H值得方法
      */
    private static int calcH(Node end, Node node) {
        int step = Math.abs(node.x - end.x) + Math.abs(node.y - end.y);
        return step * HORIZONTAL_STEP;
    }

    public static class Node implements Comparable<Node>{
        public Node(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int x;
        public int y;

        public int F;
        public int G;
        public int H;

        public void calcF() {
            this.F = this.G + this.H;
        }

        public Node parent;

        @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);
        }

        @Override
        public int compareTo(Node o) {
            if(this.F > o.F){
                return 1;
            }
            if(this.F < o.F){
                return -1;
            }
            return 0;
        }
    }

}

demo:https://github.com/sunzeJAVA/AStar.git

  • 算法
    428 引用 • 254 回帖 • 24 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Openfire

    Openfire 是开源的、基于可拓展通讯和表示协议 (XMPP)、采用 Java 编程语言开发的实时协作服务器。Openfire 的效率很高,单台服务器可支持上万并发用户。

    6 引用 • 7 回帖 • 94 关注
  • C++

    C++ 是在 C 语言的基础上开发的一种通用编程语言,应用广泛。C++ 支持多种编程范式,面向对象编程、泛型编程和过程化编程。

    107 引用 • 153 回帖 • 3 关注
  • CSDN

    CSDN (Chinese Software Developer Network) 创立于 1999 年,是中国的 IT 社区和服务平台,为中国的软件开发者和 IT 从业者提供知识传播、职业发展、软件开发等全生命周期服务,满足他们在职业发展中学习及共享知识和信息、建立职业发展社交圈、通过软件开发实现技术商业化等刚性需求。

    14 引用 • 155 回帖 • 1 关注
  • WebSocket

    WebSocket 是 HTML5 中定义的一种新协议,它实现了浏览器与服务器之间的全双工通信(full-duplex)。

    48 引用 • 206 回帖 • 334 关注
  • Google

    Google(Google Inc.,NASDAQ:GOOG)是一家美国上市公司(公有股份公司),于 1998 年 9 月 7 日以私有股份公司的形式创立,设计并管理一个互联网搜索引擎。Google 公司的总部称作“Googleplex”,它位于加利福尼亚山景城。Google 目前被公认为是全球规模最大的搜索引擎,它提供了简单易用的免费服务。不作恶(Don't be evil)是谷歌公司的一项非正式的公司口号。

    49 引用 • 192 回帖 • 1 关注
  • 心情

    心是产生任何想法的源泉,心本体会陷入到对自己本体不能理解的状态中,因为心能产生任何想法,不能分出对错,不能分出自己。

    59 引用 • 369 回帖 • 1 关注
  • Solidity

    Solidity 是一种智能合约高级语言,运行在 [以太坊] 虚拟机(EVM)之上。它的语法接近于 JavaScript,是一种面向对象的语言。

    3 引用 • 18 回帖 • 399 关注
  • PWA

    PWA(Progressive Web App)是 Google 在 2015 年提出、2016 年 6 月开始推广的项目。它结合了一系列现代 Web 技术,在网页应用中实现和原生应用相近的用户体验。

    14 引用 • 69 回帖 • 155 关注
  • Vim

    Vim 是类 UNIX 系统文本编辑器 Vi 的加强版本,加入了更多特性来帮助编辑源代码。Vim 的部分增强功能包括文件比较(vimdiff)、语法高亮、全面的帮助系统、本地脚本(Vimscript)和便于选择的可视化模式。

    29 引用 • 66 回帖 • 2 关注
  • Dubbo

    Dubbo 是一个分布式服务框架,致力于提供高性能和透明化的 RPC 远程服务调用方案,是 [阿里巴巴] SOA 服务化治理方案的核心框架,每天为 2,000+ 个服务提供 3,000,000,000+ 次访问量支持,并被广泛应用于阿里巴巴集团的各成员站点。

    60 引用 • 82 回帖 • 597 关注
  • Bug

    Bug 本意是指臭虫、缺陷、损坏、犯贫、窃听器、小虫等。现在人们把在程序中一些缺陷或问题统称为 bug(漏洞)。

    75 引用 • 1737 回帖 • 3 关注
  • 旅游

    希望你我能在旅途中找到人生的下一站。

    90 引用 • 899 回帖 • 1 关注
  • Maven

    Maven 是基于项目对象模型(POM)、通过一小段描述信息来管理项目的构建、报告和文档的软件项目管理工具。

    186 引用 • 318 回帖 • 304 关注
  • JWT

    JWT(JSON Web Token)是一种用于双方之间传递信息的简洁的、安全的表述性声明规范。JWT 作为一个开放的标准(RFC 7519),定义了一种简洁的,自包含的方法用于通信双方之间以 JSON 的形式安全的传递信息。

    20 引用 • 15 回帖 • 2 关注
  • Chrome

    Chrome 又称 Google 浏览器,是一个由谷歌公司开发的网页浏览器。该浏览器是基于其他开源软件所编写,包括 WebKit,目标是提升稳定性、速度和安全性,并创造出简单且有效率的使用者界面。

    62 引用 • 289 回帖
  • 负能量

    上帝为你关上了一扇门,然后就去睡觉了....努力不一定能成功,但不努力一定很轻松 (° ー °〃)

    88 引用 • 1235 回帖 • 411 关注
  • Logseq

    Logseq 是一个隐私优先、开源的知识库工具。

    Logseq is a joyful, open-source outliner that works on top of local plain-text Markdown and Org-mode files. Use it to write, organize and share your thoughts, keep your to-do list, and build your own digital garden.

    6 引用 • 63 回帖
  • Lute

    Lute 是一款结构化的 Markdown 引擎,支持 Go 和 JavaScript。

    25 引用 • 191 回帖 • 15 关注
  • PostgreSQL

    PostgreSQL 是一款功能强大的企业级数据库系统,在 BSD 开源许可证下发布。

    22 引用 • 22 回帖
  • Sym

    Sym 是一款用 Java 实现的现代化社区(论坛/BBS/社交网络/博客)系统平台。

    下一代的社区系统,为未来而构建

    524 引用 • 4601 回帖 • 699 关注
  • Docker

    Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的操作系统上。容器完全使用沙箱机制,几乎没有性能开销,可以很容易地在机器和数据中心中运行。

    491 引用 • 917 回帖 • 2 关注
  • JSON

    JSON (JavaScript Object Notation)是一种轻量级的数据交换格式。易于人类阅读和编写。同时也易于机器解析和生成。

    52 引用 • 190 回帖 • 1 关注
  • 深度学习

    深度学习(Deep Learning)是机器学习的分支,是一种试图使用包含复杂结构或由多重非线性变换构成的多个处理层对数据进行高层抽象的算法。

    53 引用 • 40 回帖
  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3187 引用 • 8213 回帖 • 1 关注
  • ZeroNet

    ZeroNet 是一个基于比特币加密技术和 BT 网络技术的去中心化的、开放开源的网络和交流系统。

    1 引用 • 21 回帖 • 638 关注
  • API

    应用程序编程接口(Application Programming Interface)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码,或理解内部工作机制的细节。

    77 引用 • 430 回帖 • 1 关注
  • Q&A

    提问之前请先看《提问的智慧》,好的问题比好的答案更有价值。

    8128 引用 • 37049 回帖 • 160 关注