import java.util.ArrayList;

// A*算法寻路
public class AStar2 {
public static final int[][] maps = {
{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, 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},
}; public static int straight = 10;
public static int diagonal = 14; // 开放列表
public static ArrayList<Node> openList = new ArrayList<>();
// 闭合列表
public static ArrayList<Node> colseList = new ArrayList<>();
// 方向
public static int[][] direct = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; public static void main(String[] args) {
//定点:起点终点
Node start = new Node(5, 1);
Node end = new Node(5, 4); Node endNode = findPath(start, end); printMap(maps, start, end); ArrayList<Node> arrayList = endNode != null ? getPaths(endNode) : null; printPaths(arrayList); } // 从起点开始,找到到终点的一条最短路径
private static Node findPath(Node start, Node end) {
start.G = 0;
openList.add(start); while (!openList.isEmpty()) {
//从开放列表中拿到最小F节点
Node cureNode = minFINOpenList(openList);
openList.remove(cureNode);
// 将该节点加入到闭合列表中
colseList.add(cureNode); // 当前节点的全部合法邻居
ArrayList<Node> neighbors = getNeighbor(cureNode);
for (Node nbrNode : neighbors) {
// 邻居已经在openList
if (exists(openList, nbrNode) != null)
updateG(cureNode, nbrNode);
// 邻居不在openList
else joinOpenList(cureNode, nbrNode, end);
}
if (exists(openList, end) != null)
return exists(openList, end);
} return null;
} private static ArrayList<Node> getPaths(Node endNode) {
ArrayList<Node> arrayList = new ArrayList<>();
Node parent = endNode;
while (parent != null) {
arrayList.add(parent);
parent = parent.parent;
}
return arrayList;
} private static int calStep(Node node, Node cur) {
if (inLine(node, cur))
return straight;
else return diagonal;
} private static int calH(Node endNode, Node nbrNode) {
return Math.abs(endNode.y - nbrNode.y) + Math.abs(endNode.x - nbrNode.x);
} // 计算距离起点的距离
private static int calG(Node cureNode, Node nbrNode) {
int step = calStep(cureNode, nbrNode);
return cureNode.G + step;
} private static boolean inLine(Node nbr, Node cur) {
if (nbr.x == cur.x || nbr.y == cur.y)
return true;
return false;
} // 途径当前节点到达节点node的路径G会不会更短
private static void updateG(Node cureNode, Node nbrNode) {
int step = calStep(cureNode, nbrNode);
int G = calG(cureNode, nbrNode);
if (G < nbrNode.G) {
nbrNode.G = G;
nbrNode.parent = cureNode;
nbrNode.calcF();
}
} private static void joinOpenList(Node curNode, Node nbrNode, Node endNode) {
openList.add(nbrNode);
nbrNode.parent = curNode;
nbrNode.G = calG(curNode, nbrNode);
nbrNode.H = calH(endNode, nbrNode);
nbrNode.calcF();
} // 达到当前节点的可达,且不在closeList中的邻居节点
private static ArrayList<Node> getNeighbor(Node cureNode) {
ArrayList<Node> arrayList = new ArrayList<>();
//从当前节点想八个方向扩散
for (int i = 0; i < 8; i++) {
int newRow = cureNode.x + direct[i][0];
int newCol = cureNode.y + direct[i][1];
//当前邻居节点: 可达、不在closeList中
if (isAccesse(newRow, newCol) && !exists(colseList, newRow, newCol)) {
arrayList.add(new Node(newRow, newCol));
}
}
return arrayList;
} private static Node exists(ArrayList<Node> colseList, Node cur) {
for (Node node : colseList) {
if (node.x == cur.x && node.y == cur.y)
return node;
}
return null;
} private static boolean exists(ArrayList<Node> colseList, int newX, int newY) {
for (Node node : colseList) {
if (node.x == newX && node.y == newY)
return true;
}
return false;
} // 可达性分析(非障碍物)
private static boolean isAccesse(int newX, int newY) {
if (0 <= newX && newX < maps.length && 0 <= newY && newY < maps[0].length)
return maps[newX][newY] == 0;
return false;
} // 从开放列表中找到最小F=G+H的节点
private static Node minFINOpenList(ArrayList<Node> openList) {
Node min = openList.get(0);
for (Node node : openList) {
if (node.F < min.F)
min = node;
}
return min;
} private static void printMap(int[][] maps, Node start, Node end) { for (int col = 0; col < maps[0].length; col++) {
System.out.print("\t" + col + "");
}
System.out.print("\n-----------------------------------------\n");
int count = 0;
for (int row = 0; row < maps.length; row++) {
for (int col = 0; col < maps[0].length; col++) {
if (col == 0)
System.out.print(count++ + "|\t");
if (row == start.x && col == start.y || row == end.x && col == end.y)
System.out.print("X\t");
else
System.out.print(maps[row][col] + "\t");
}
System.out.println();
}
System.out.println();
} public static void printPaths(ArrayList<Node> arrayList) {
if (arrayList == null) {
System.out.println("无路可走");
return;
} // 地图形式
for (int col = 0; col < maps[0].length; col++) {
System.out.print("\t" + col + "");
}
System.out.print("\n-----------------------------------------\n");
int count = 0; for (int row = 0; row < maps.length; row++) {
for (int col = 0; col < maps[0].length; col++) {
if (col == 0)
System.out.print(count++ + "|\t");
if (exists(arrayList, row, col)) {
System.out.print("X\t");
} else {
System.out.print(maps[row][col] + "\t");
} }
System.out.println();
}
System.out.println();
// 路径形式
for (int i = arrayList.size() - 1; i >= 0; i--) {
if (i == 0)
System.out.print(arrayList.get(i));
else
System.out.print(arrayList.get(i) + "->");
}
System.out.println();
} }

结果

    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 X 0 1 X 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 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 X 0 0 0 0 0
3| 0 0 X 1 X 0 0 0 0
4| 0 X 0 1 X 0 0 0 0
5| 0 X 0 1 X 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 (5,1)->(4,1)->(3,2)->(2,3)->(3,4)->(4,4)->(5,4)
    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 X 0 0 X 0 0 0 0
6| 0 0 0 0 0 0 0 0 0
7| 0 0 0 1 0 0 0 0 0
8| 0 0 0 0 0 0 0 0 0 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 X X X X 0 0 0 0
6| 0 0 0 0 0 0 0 0 0
7| 0 0 0 1 0 0 0 0 0
8| 0 0 0 0 0 0 0 0 0 (5,1)->(5,2)->(5,3)->(5,4)
    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 X 0 1 X 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 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 X 0 1 X 0 0 0 0
6| 0 0 X 1 X 0 0 0 0
7| 0 0 0 X 0 0 0 0 0
8| 0 0 0 0 0 0 0 0 0 (5,1)->(6,2)->(7,3)->(6,4)->(5,4)
    0    1    2    3    4    5    6    7    8
-----------------------------------------
0| 0 0 0 1 0 0 0 0 0
1| 0 0 0 1 0 0 0 0 0
2| 0 0 0 1 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 X 0 1 X 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 无路可走
    0    1    2    3    4    5    6    7    8
-----------------------------------------
0| 0 0 0 1 0 0 0 0 0
1| 0 0 0 1 0 0 0 0 0
2| 0 0 0 1 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 X 0 1 X 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 0 0 0 0 0 0 0 1 2 3 4 5 6 7 8
-----------------------------------------
0| 0 0 0 1 0 0 0 0 0
1| 0 0 0 1 0 0 0 0 0
2| 0 0 0 1 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 X 0 1 X 0 0 0 0
6| 0 X 0 1 X 0 0 0 0
7| 0 0 X 1 X 0 0 0 0
8| 0 0 0 X 0 0 0 0 0 (5,1)->(6,1)->(7,2)->(8,3)->(7,4)->(6,4)->(5,4)

A*—java代码的更多相关文章

  1. 对一致性Hash算法,Java代码实现的深入研究

    一致性Hash算法 关于一致性Hash算法,在我之前的博文中已经有多次提到了,MemCache超详细解读一文中"一致性Hash算法"部分,对于为什么要使用一致性Hash算法.一致性 ...

  2. 怎样编写高质量的java代码

    代码质量概述     怎样辨别一个项目代码写得好还是坏?优秀的代码和腐化的代码区别在哪里?怎么让自己写的代码既漂亮又有生命力?接下来将对代码质量的问题进行一些粗略的介绍.也请有过代码质量相关经验的朋友 ...

  3. 数据结构笔记--二叉查找树概述以及java代码实现

    一些概念: 二叉查找树的重要性质:对于树中的每一个节点X,它的左子树任一节点的值均小于X,右子树上任意节点的值均大于X. 二叉查找树是java的TreeSet和TreeMap类实现的基础. 由于树的递 ...

  4. java代码的初始化过程研究

        刚刚在ITeye上看到一篇关于java代码初始化的文章,看到代码我试着推理了下结果,虽然是大学时代学的知识了,没想到还能做对.(看来自己大学时掌握的基础还算不错,(*^__^*) 嘻嘻……)但 ...

  5. JDBC——Java代码与数据库链接的桥梁

    常用数据库的驱动程序及JDBC URL: Oracle数据库: 驱动程序包名:ojdbc14.jar 驱动类的名字:oracle.jdbc.driver.OracleDriver JDBC URL:j ...

  6. 利用Java代码在某些时刻创建Spring上下文

    上一篇中,描述了如何使用Spring隐式的创建bean,但当我们需要引进第三方类库添加到我们的逻辑上时,@Conponent与@Autowired是无法添加到类上的,这时,自动装配便不适用了,我们需要 ...

  7. lombok 简化java代码注解

    lombok 简化java代码注解 安装lombok插件 以intellij ide为例 File-->Setting-->Plugins-->搜索"lombok plug ...

  8. 远程debug调试java代码

    远程debug调试java代码 日常环境和预发环境遇到问题时,可以用远程调试的方法本地打断点,在本地调试.生产环境由于网络隔离和系统稳定性考虑,不能进行远程代码调试. 整体过程是通过修改远程服务JAV ...

  9. 几种简单的负载均衡算法及其Java代码实现

    什么是负载均衡 负载均衡,英文名称为Load Balance,指由多台服务器以对称的方式组成一个服务器集合,每台服务器都具有等价的地位,都可以单独对外提供服务而无须其他服务器的辅助.通过某种负载分担技 ...

  10. 希尔排序及希尔排序java代码

    原文链接:http://www.orlion.ga/193/ 由上图可看到希尔排序先约定一个间隔(图中是4),然后对0.4.8这个三个位置的数据进行插入排序,然后向右移一位对位置1.5.9进行插入排序 ...

随机推荐

  1. POJ 3279 Fliptile 状态压缩,思路 难度:2

    http://poj.org/problem?id=3279 明显,每一位上只需要是0或者1, 遍历第一行的所有取值可能,(1<<15,时间足够)对每种取值可能: 对于第0-n-2行,因为 ...

  2. 安装wamp后,127.0.0.1可以访问,localhost不能访问

    今天安装wamp后,127.0.0.1可以访问,localhost不能访问,出现 “error You don't have permission to access”的错误, 网上查了下,很多方法都 ...

  3. java中可以让程序暂停几秒执行的代码

    //n为毫秒数 try { Thread.sleep ( n ) ; } catch (InterruptedException ie){} try { TimeUnit.SECONDS.sleep( ...

  4. Mysql5.7的gtid主从半同步复制和组复制

    (一)gtid主从半同步复制 一.半同步复制原理 mysql默认的复制是异步的,主库在执行完客户端提交的事务后会立即将结果返回给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主库如果cr ...

  5. WebGL编程指南案例解析之绘制三角形

    //案例3.绘制三角形,将顶点数据存到缓冲区对象(gl.ARRAY_BUFFER)中,然后顶点着色器从里面读数据(3个顶点) //顶点着色器中去掉gl_PointSize = 10.0,绘制三角不能设 ...

  6. 使用eclipse启动系统时报错“ java.lang.OutOfMemoryError: PermGen space”问题的解决

    转载请注明出处:http://blog.csdn.net/dongdong9223/article/details/76571611 本文出自[我是干勾鱼的博客] 有的时候,使用eclipse启动系统 ...

  7. 如何优化tomcat配置优化

    tomcat默认参数是为开发环境制定,而非适合生产环境,尤其是内存和线程的配置,默认都很低,容易成为性能瓶颈. tomcat内存优化 linux修改TOMCAT_HOME/bin/catalina.s ...

  8. 第33课 main函数与命令行参数

    main函数的概念: 测试程序: 以上四种定义main函数的方法都是正确的. main函数的本质: 操作系统是希望main函数的有返回值的,这样可以知道main函数的退出状态. 如果程序时异常退出的, ...

  9. CNN中卷积层的计算细节

    原文链接: https://zhuanlan.zhihu.com/p/29119239 卷积层尺寸的计算原理 输入矩阵格式:四个维度,依次为:样本数.图像高度.图像宽度.图像通道数 输出矩阵格式:与输 ...

  10. mysql配置调优-开启慢查询日志-slow_query_log

    工作中,会遇到需要查看mysql的top 20 慢sql,逐个进行优化,加上必要的索引这种需求,这时就需要开启数据库的慢查询日志的功能 1.查询当前慢查询日志的状态 # 默认为关闭状态 mysql - ...