a 寻路算法 java_A*(也叫A star, A星)寻路算法Java版 | 学步园

寻路

首先要理解什么是A*寻路算法,可以参考这三篇文章:

下面为测试地图,0表示可以通行,1表示障碍物:

8b763b40bbbc7d45eb6fc43bc0b2a69f.png

要从点(5, 1)到点(5, 5),通过A*寻路算法找到以路径为@所示:

cb9c3fc1776ccbfdef70ad6a67ecf053.png

在代码中可以修改障碍物,起点和终点来测试算法。

最后代码:

import java.util.ArrayList;

import java.util.List;

public class AStar {

public static final int[][] NODES = {

{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 1, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 1, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 1, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 1, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },

{ 0, 0, 0, 0, 0, 0, 0, 0, 0 },

};

public static final int STEP = 10;

private ArrayList openList = new ArrayList();

private ArrayList closeList = new ArrayList();

public Node findMinFNodeInOpneList() {

Node tempNode = openList.get(0);

for (Node node : openList) {

if (node.F < tempNode.F) {

tempNode = node;

}

}

return tempNode;

}

public ArrayList findNeighborNodes(Node currentNode) {

ArrayList arrayList = new ArrayList();

// 只考虑上下左右,不考虑斜对角

int topX = currentNode.x;

int topY = currentNode.y - 1;

if (canReach(topX, topY) && !exists(closeList, topX, topY)) {

arrayList.add(new Node(topX, topY));

}

int bottomX = currentNode.x;

int bottomY = currentNode.y + 1;

if (canReach(bottomX, bottomY) && !exists(closeList, bottomX, bottomY)) {

arrayList.add(new Node(bottomX, bottomY));

}

int leftX = currentNode.x - 1;

int leftY = currentNode.y;

if (canReach(leftX, leftY) && !exists(closeList, leftX, leftY)) {

arrayList.add(new Node(leftX, leftY));

}

int rightX = currentNode.x + 1;

int rightY = currentNode.y;

if (canReach(rightX, rightY) && !exists(closeList, rightX, rightY)) {

arrayList.add(new Node(rightX, rightY));

}

return arrayList;

}

public boolean canReach(int x, int y) {

if (x >= 0 && x < NODES.length && y >= 0 && y < NODES[0].length) {

return NODES[x][y] == 0;

}

return false;

}

public Node findPath(Node startNode, Node endNode) {

// 把起点加入 open list

openList.add(startNode);

while (openList.size() > 0) {

// 遍历 open list ,查找 F值最小的节点,把它作为当前要处理的节点

Node currentNode = findMinFNodeInOpneList();

// 从open list中移除

openList.remove(currentNode);

// 把这个节点移到 close list

closeList.add(currentNode);

ArrayList neighborNodes = findNeighborNodes(currentNode);

for (Node node : neighborNodes) {

if (exists(openList, node)) {

foundPoint(currentNode, node);

} else {

notFoundPoint(currentNode, endNode, node);

}

}

if (find(openList, endNode) != null) {

return find(openList, endNode);

}

}

return find(openList, endNode);

}

private void foundPoint(Node tempStart, Node node) {

int G = calcG(tempStart, node);

if (G < node.G) {

node.parent = tempStart;

node.G = G;

node.calcF();

}

}

private void notFoundPoint(Node tempStart, Node end, Node node) {

node.parent = tempStart;

node.G = calcG(tempStart, node);

node.H = calcH(end, node);

node.calcF();

openList.add(node);

}

private int calcG(Node start, Node node) {

int G = STEP;

int parentG = node.parent != null ? node.parent.G : 0;

return G + parentG;

}

private int calcH(Node end, Node node) {

int step = Math.abs(node.x - end.x) + Math.abs(node.y - end.y);

return step * STEP;

}

public static void main(String[] args) {

Node startNode = new Node(5, 1);

Node endNode = new Node(5, 5);

Node parent = new AStar().findPath(startNode, endNode);

for (int i = 0; i < NODES.length; i++) {

for (int j = 0; j < NODES[0].length; j++) {

System.out.print(NODES[i][j] + ", ");

}

System.out.println();

}

ArrayList arrayList = new ArrayList();

while (parent != null) {

// System.out.println(parent.x + ", " + parent.y);

arrayList.add(new Node(parent.x, parent.y));

parent = parent.parent;

}

System.out.println("\n");

for (int i = 0; i < NODES.length; i++) {

for (int j = 0; j < NODES[0].length; j++) {

if (exists(arrayList, i, j)) {

System.out.print("@, ");

} else {

System.out.print(NODES[i][j] + ", ");

}

}

System.out.println();

}

}

public static Node find(List nodes, Node point) {

for (Node n : nodes)

if ((n.x == point.x) && (n.y == point.y)) {

return n;

}

return null;

}

public static boolean exists(List nodes, Node node) {

for (Node n : nodes) {

if ((n.x == node.x) && (n.y == node.y)) {

return true;

}

}

return false;

}

public static boolean exists(List nodes, int x, int y) {

for (Node n : nodes) {

if ((n.x == x) && (n.y == y)) {

return true;

}

}

return false;

}

public static class 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;

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/298294.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python多线程队列处理_Python线程和队列使用的一点思考

Python线程和队列使用的一点思考1. 斗哥采访环节请问为什么要使用线程&#xff1f;答&#xff1a;为了提高程序速度&#xff0c;代码效率呀。请问为什么要使用队列&#xff1f;答&#xff1a;个人认为队列可以保证线程安全&#xff0c;实现线程间的同步&#xff0c;比较稳。线程…

安装debian的zabbix-agent客户端

1. 下载软件源wget http://repo.zabbix.com/zabbix/2.2/debian/pool/main/z/zabbix-release/zabbix-release_2.2-1wheezy_all.deb2. 安装软件源dpkg -i zabbix-release_2.2-1wheezy_all.deb3. 更新软件源apt-get update4. 安装zabbix-agentapt-get install zabbix-agent其实deb…

看到喜欢的人时的心跳​

1 第一次和女孩子约会的猫咪.......好羞涩啊2 我要吃蛋糕&#xff01;不给买我就不走了~3 感觉自己活得都没小螃蟹精致4 完美的过程5 漫画真人6 哈哈哈哈哈哈真实合理慌的一批7 人最大的烦恼就是记性太好&#xff01;你点的每个赞&#xff0c;我都认真当成了喜欢

[Buzz.Today]2011.06.26

>> Microsoft推出Kinect for Windows SDK Kinect这玩意不得了&#xff0c;号称刚出世时比iPad和iPhone还卖得好。和当年iPhone一样&#xff0c;这玩意颇受一堆Hacker的青睐&#xff0c;做出了很多很炫的东西。 Piaoger当年曾经做过VR&#xff0c;虽然没搞出什么名堂&…

ARM公版架构迭代迅速 国产ARM架构落伍

近年来&#xff0c;ARM CPU性能可谓是突飞猛进&#xff0c;根据ARM官方消息&#xff0c;Cortex A78 CPU最高性能比5年前推出的Cortex A73 CPU提升2.5倍。ARM下一代的Matterhorn架构及Makalu架构会相对于X1/A78这一代保持30%以上的IPC性能提升&#xff0c;如果ARM的PPT不注水&am…

python 字符编码处理_浅析Python 字符编码与文件处理

Python字符编码目前计算机内存的字符编码都是Unicode&#xff0c;目前国内的windows操作系统采用的是gbk。python2默认的字符编码方式是ASCIIpython3默认的字符编码方式是Unicode.py文件头部的#coding:utf-8是帮助python识别.py文件的编码方式&#xff0c;故在写.py文件时要注意…

java 匿名初始化_关于java匿名内部类初始化法

最近无意间发现一种对象的初始化方法&#xff1a;匿名内部类初始化法List list new ArrayList(){{add("爱飘de小子");add("flyingkid");}};Map map new HashMap(){{put("name","爱飘de小子");put("age",24);}};还有这种操…

感谢生活的磨砺

感谢伤害你的人&#xff0c;因为他磨炼了你的心志&#xff01;  感谢绊倒你的人&#xff0c;因为他强化了你的双腿&#xff01;  感谢欺骗你的人&#xff0c;因为他增进了你的智慧&#xff01;  感谢藐视你的人&#xff0c;因为他觉醒了你的自尊&#xff01;  感谢遗弃…

MemoryCache 使用不当导致的一个 BUG

MemoryCache 使用不当导致的一个 BUGIntro前几天发现代码里的一个 BUG&#xff0c;原因是 MemoryCache 使用不当&#xff0c;可以对于很多人来说可能都知道&#xff0c;但还是想分享记录一下&#xff0c;避免以后写出同样的 BUGSample直接来看下面的示例吧await using var serv…

Llinux 磁盘配额的搭建和常规问题解答

1 磁盘配额的使用限制仅针对整个分区&#xff1a;磁盘配额实际运行时&#xff0c;是针对“整个分区”进行限制的&#xff0c;例如&#xff0c;如果/dev/hda5载入在/home下&#xff0c;那么&#xff0c;在/home下面的所有目 录都会受到限制。只对一般身份用户有效&#xff1a;并…

22岁少年破解史上最严重网络攻击,拯救全球互联网,三个月后却被FBI逮捕

转自&#xff1a;大数据文摘编译&#xff1a;牛婉杨2017年&#xff0c;一位名叫Marcus Hutchins的少年从有史以来最严重的网络攻击事件“WannaCry 勒索病毒”中拯救了互联网。如果你是个geek&#xff0c;那么你对WannaCry这个名字一定不陌生&#xff0c; 这是一种可以自行传播的…

python安装beautifulsoup失败_Win10环境下python36安装BeautifulSoup出现错误的解决办法

说明&#xff1a;win10 64位系统&#xff0c;Python3.6.3Win10环境下安装BeautifulSoup4貌似没有任何问题&#xff0c;但是当使用时就会报错&#xff0c;错误如下&#xff1a;通过报错信息到相应的位置去查看文件try:is_file os.path.exists(possible_filename)except Excepti…

使用 Git Extensions 简单入门 Git

使用 Git Extensions 简单入门 Git—— 独立观察员 2015.11.25前言关于这个主题&#xff0c;之前我录了段视频教程&#xff0c;在本地看清晰度还可以&#xff0c;但传到优酷上就很不清晰了&#xff0c;即使是后来重制后还是一样不清晰&#xff0c;所以现在想整理成文字版。当然…

各省地图都像些什么?

全世界只有3.14 % 的人关注了爆炸吧知识人们常说中国地图的形状像一只雄鸡&#xff0c;但具体到每一个省区则并没有一个明确的说法。看看下面这一套省区地图对应的有趣的想象&#xff0c;你觉得像还是不像&#xff1f;★安徽有人说安徽像一只斜倒挂着的蝙蝠&#xff0c;你能看出…

android 蓝牙各种UUID(转载)

android 蓝牙各种UUID ServiceDiscoveryServerServiceClassID_UUID {00001000-0000-1000-8000-00805F9B34FB} BrowseGroupDescriptorServiceClassID_UUID {00001001-0000-1000-8000-00805F9B34FB} PublicBrowseGroupServiceClass_UUID {00001002-0000-1000-8000-00805F9B34F…

Silverlight中摄像头的运用—part2

Silverlight 4 中摄像头的运用—part1将跟踪颜色视作输入 好了&#xff0c;我们能够跟踪到这个颜色了&#xff0c;那这么做的意义是什么呢&#xff1f;实际上&#xff0c;我们可以根据它的位置来移动东西。接下来的例子中&#xff0c;创建的一个球会跟随这个颜色一起移动。你可…

python静态变量和静态方法_python的静态成员变量、实例成员变量、静态方法、类方法、实例方法...

标签&#xff1a;静态成员变量(类变量)和普通成员变量(实例变量)静态成员变量只能通过类名.变量名获得&#xff0c;实例成员变量&#xff0c;通过该实例引用.变量名获得。在实例对静态成员变量赋值时&#xff0c;实例python是动态类型的语言&#xff0c;没有特别的标志区分静态…

同学,解决下这个 Bug!

一些解决 Bug 的小技巧大家好&#xff0c;我是鱼皮。学编程的过程中&#xff0c;我们会遇到各式各样的 Bug&#xff0c;也常常因为它们而感到头秃。但随着你不断解决 Bug、积累经验&#xff0c;就会发现其实解决 Bug 也是有套路的。今天分享下鱼皮自己总结的解决 Bug 套路&…

C#编写串口通信程序(转)

一&#xff0e;概述 在Visual Studio 6.0中编写串口通讯程序&#xff0c;一般都使用Microsoft Communication Control&#xff08;简称MSComm&#xff09;的通讯控件&#xff0c;只要通 过对此控件的属性和事件进行相应编程操作&#xff0c;就可以轻松地实现串口通讯。但在Micr…