A*算法的java实现

本文内容参考于 —— [ 理解A*寻路算法具体过程 ]

A*算法是一种启发式最小代价寻路算法,本文是在参考博文的基础上了解A*算法思想之后,使用java实现的,做个记录。
整个过程抽象:

把起始格添加到 "开启列表"
do
{ 寻找开启列表中F值最低的格子, 我们称它为当前格. 把它切换到关闭列表. 对当前格相邻的8格中的每一个 if (它不可通过 || 已经在 "关闭列表" 中) { 什么也不做. } if (它不在开启列表中) { 把它添加进 "开启列表", 把当前格作为这一格的父节点, 计算这一格的 FGH }if (它已经在开启列表中) { if (用G值为参考检查新的路径是否更好, 更低的G值意味着更好的路径) { 把这一格的父节点改成当前格, 并且重新计算这一格的 GF 值. } }目标格已经在 "开启列表", 这时候路径被找到跳出循环;
} while(开启列表不为空)
如果开启列表已经空了,目标格没找到 说明路径不存在.
最后从目标格开始, 沿着每一格的父节点移动直到回到起始格, 这就是路径.

注:这个实现支持斜着走, 如果要实现不支持走沿对角的斜线,可以在此实现的基础上稍作修改即可实现。


JAVA实现的代码如下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.Stack;public class AStarAlgorithm {private static final int[][] DIREC = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};public static void main(String[] args) {Scanner scanner = new Scanner(System.in);System.out.println("please enter (rows cols x1 y1 x2 y2): ");final int rows = scanner.nextInt();final int cols = scanner.nextInt();int x1 = scanner.nextInt();int y1 = scanner.nextInt();int x2 = scanner.nextInt();int y2 = scanner.nextInt();scanner.close();// generate a two-dimension array filled with 0int map[][] = new int[rows][cols];for (int i = 0; i < rows; i++) {int tmp[] = new int[cols];Arrays.fill(tmp, 0);map[i] = tmp;}int midr = rows / 2;int midc = cols / 2;/*map[midr - 1][midc] = 1;map[midr][midc] = 1;map[midr + 1][midc] = 1;*/for (int i = 1; i < rows - 1; i++) {map[i][midc] = 1;}map[2][6] = 1;map[3][6] = 1;map[4][6] = 1;map[5][6] = 1;findPath(map, x1, y1, x2, y2);}private static void findPath(int[][] map, int x1, int y1, int x2, int y2) {List<Position> openList = new ArrayList<AStarAlgorithm.Position>();List<Position> closeList = new ArrayList<AStarAlgorithm.Position>();boolean findFlag = false;Position termPos = null;// 起始点Position startPos = new Position(x1, y1, calcH(x1, y1, x2, y2));openList.add(startPos);do {// 通过在开启列表中找到F值最小的点作为当前点Position currentPos = openList.get(0);for (int i = 0; i < openList.size(); i++) {if (currentPos.F > openList.get(i).F) {currentPos = openList.get(i);}}// 将找到的当前点放到关闭列表中,并从开启列表中删除closeList.add(currentPos);openList.remove(currentPos);//遍历当前点对应的8个相邻点for (int i = 0; i < DIREC.length; i++) {int tmpX = currentPos.row + DIREC[i][0];int tmpY = currentPos.col + DIREC[i][1];if (tmpX < 0 || tmpX >= map.length || tmpY < 0 || tmpY >= map[0].length) {continue;}//创建对应的点Position tmpPos = new Position(tmpX, tmpY, calcH(tmpX, tmpY, x2, y2), currentPos);//map中对应的格子中的值为1(障碍), 或对应的点已经在关闭列表中if (map[tmpX][tmpY] == 1 || closeList.contains(tmpPos)) {continue;}//如果不在开启列表中,则加入到开启列表if (!openList.contains(tmpPos)) {openList.add(tmpPos);} else {// 如果已经存在开启列表中,则用G值考察新的路径是否更好,如果该路径更好,则把父节点改成当前格并从新计算FGHPosition prePos = null;for (Position pos : openList) {if (pos.row == tmpX && pos.col == tmpY) {prePos = pos;break;}}if (tmpPos.G < prePos.G) {prePos.setFaPos(currentPos);}}}// 判断终点是否在开启列表中for (Position tpos : openList) {if (tpos.row == x2 && tpos.col == y2) {termPos = tpos;findFlag = true;break;}}} while(openList.size() != 0);if(!findFlag) {System.out.println("no valid path!");return;}Stack<String> resStack = new Stack<String>();String pattern = "(%d, %d)";if (termPos != null) {resStack.push(String.format(pattern, termPos.row, termPos.col));while(termPos.fa != null) {termPos = termPos.fa;resStack.push(String.format(pattern, termPos.row, termPos.col));}}StringBuilder sb = new StringBuilder();while (!resStack.empty()) {sb.append(resStack.pop());if (!resStack.empty()) {sb.append(" -> ");}}System.out.println(sb.toString());}/*** 计算某个格子的H值* @param x* @param y* @param tx 终点的x值* @param ty 终点的y值* @return*/private static int calcH(int x, int y, int tx, int ty) {int diff = Math.abs(x - tx) + Math.abs(y - ty);return diff * 10;}static class Position {public int F;public int G;public int H;public Position fa;public int row;public int col;public Position() {}public Position(int row, int col, int H) {this(row, col, H, null);}public Position(int row, int col, int H, Position pos) {this.H = H;this.row = row;this.col = col;this.fa = pos;this.G = calcG();this.F = G + H;}/** * 计算某个点到起始点的代价G* @return*/private int calcG() {if (fa == null) return 0;if (fa.row != this.row && fa.col !=  this.col) {return 14 + fa.G;}return 10 + fa.G;} public void setFaPos(Position pos) {this.fa = pos;this.G = calcG();this.F = G + H;}@Overridepublic boolean equals(Object obj) {if (obj == null) {return false;}if (!(obj instanceof Position)) {return false;}Position pos = (Position) obj;return this.row == pos.row && this.col == pos.col;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + row;result = prime * result + col;return result;}}}

A*算法 JAVA实现相关推荐

  1. 推特雪花算法 java实现

    2019独角兽企业重金招聘Python工程师标准>>> package twiter.snowflake;/*** twitter的snowflake算法 -- java实现*/ p ...

  2. java dh算法_dh密钥交换算法java

    dh密钥交换算法java 迪菲-赫尔曼密钥交换(Diffie–Hellman key exchange,简称"D–H") 是一种安全协议. 它可以让双方在完全没有对方任何预先信息的 ...

  3. 数据结构和算法(Java)-张晨光-专题视频课程

    数据结构和算法(Java)-579人已学习 课程介绍         如果说各种编程语言是程序员的招式,那么数据结构和算法就相当于程序员的内功. 想写出精炼.优秀的代码,不通过不断的锤炼,是很难做到的 ...

  4. floyed java_Floyd算法java实现demo

    Floyd算法java实现,如下: package a; /** * ┏┓ ┏┓+ + * ┏┛┻━━━┛┻┓ + + * ┃ ┃ * ┃ ━ ┃ ++ + + + * ████━████ ┃+ * ...

  5. 快速排序算法 java 实现

    快速排序算法 java 实现 快速排序算法Java实现 白话经典算法系列之六 快速排序 快速搞定 各种排序算法的分析及java实现 算法概念 快速排序是C.R.A.Hoare于1962年提出的一种划分 ...

  6. java 哈希一致算法_一致哈希算法Java实现

    一致哈希算法(Consistent Hashing Algorithms)是一个分布式系统中常用的算法.传统的Hash算法当槽位(Slot)增减时,面临所有数据重新部署的问题,而一致哈希算法确可以保证 ...

  7. java进程调度怎么画图,[Java教程]进程调度的两种算法JAVA实现

    [Java教程]进程调度的两种算法JAVA实现 0 2015-10-21 12:00:08 (SJF分为preemptive shortest job first(抢占式)和non-preemptiv ...

  8. LRU算法java实现

    LRU全称是Least Recently Used,即最近最久未使用的意思. LRU算法的设计原则是:如果一个数据在最近一段时间没有被访问到,那么在将来它被访问的可能性也很小.也就是说,当限定的空间已 ...

  9. 数据结构与算法-java笔记一 更新中

    数据结构与算法-java笔记一 更新中 数据结构与算法 什么是数据结构.算法 数据结构学了有什么用: 线性结构 数组 特点 应用 链表 存储结构 链表类型 单链表 双向链表 双向循环链表 链表与数组的 ...

  10. for循环的一个复制算法(Java)

    for循环的一个复制算法(Java) public class ForDemo0 {public static void main(String[] args) {int[] num={10,20,3 ...

最新文章

  1. 求教大牛!关于后缀树
  2. 这样就可以很方便的知道明天的天气了
  3. Tomcat 7 自动加载类及检测文件变动原理
  4. 如何使用Enigma Recovery检查设备未设置为加密备份
  5. php ddl,MySQL定义语言[DDL]
  6. openresty 前端开发入门一 1
  7. 智慧旅游监管平台建设方案
  8. 知识付费系统源码基于PHP开源的网站内容付费源码|知识付费小程序源码
  9. 删除ubuntu双系统后,开机出现grub黑屏,删除双系统引导项解决
  10. java create 透明图片_Java 如何生成透明背景色的图片
  11. java登陆注册界面_java编写登陆注册页面(简单一点的,连接数据库)
  12. 为什么小孩会沉迷游戏?小孩沉迷游戏中不想上学怎么办
  13. 对i++,i--,++i,--i深刻认识以及printf()函数打印的过程
  14. form表单提交既有文字也有图片的情况下,增加enctype属性
  15. 短信业务管理-移动短信接入
  16. Docker 容器仓库之搭建私有仓库、hub仓库
  17. Tomcat项目部署方式
  18. 为什么专业领域里外行领导能让墙倒屋塌?
  19. std::list的pop_front()及front()
  20. 关于performSelector

热门文章

  1. 未来可能的安全焦点:GIS地理信息系统安全问题分析
  2. 吕公奇文——《破窑赋》
  3. 软件设计师---钉子户
  4. 全国计算机二级考试报名入口河南,计算机等级考试报名入口河南(英语四级报名官网入口)...
  5. Linux 使用Nginx 拦截屏蔽异常访问IP并加入黑名单
  6. cobar是什么? 能做什么?
  7. 3-D Quasi-Recurrent Neural Network for Hyperspectral Image Denoising
  8. 【GameMaker】协程——异步执行代码
  9. dhcp应该开启还是关闭(dhcp应该开启还是关闭)
  10. Ubuntu 安装 SSH 服务