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. Toncat-OpenSSL双向认证配置(iOS)

    OpenSSL生成证书 要生成证书的目录下建立几个文件和文件夹,有./demoCA/ ./demoCA/newcerts/ ./demoCA/private/ ./demoCA/index.txt ( ...

  2. 分析公司shareaholic报告:Chrome浏览器使用量居首

    社交分析公司Shareaholic周四发布研究报告称,今年9月份,Chrome浏览器的使用量已经跃居行业榜首. 根据Shareaholic的数据,Chrome今年9月的使用量超过了火狐.IE和Oper ...

  3. Alpha冲刺一 (10/10)

    前言 队名:拖鞋旅游队 组长博客:https://www.cnblogs.com/Sulumer/p/10034872.html 作业博客:https://edu.cnblogs.com/campus ...

  4. Linux 进程、线程运行在指定CPU核上

    /******************************************************************************** * Linux 进程.线程运行在指定 ...

  5. Dijkstra算法(C语言)

    Dijkstra算法 1.定义概览 Dijkstra(迪杰斯特拉)算法是典型的单源最短路径算法,用于计算一个节点到其他所有节点的最短路径.主要特点是以起始点为中心向外层层扩展,直到扩展到终点为止.Di ...

  6. 【C#】Lambda

    介绍 Lambda 表达式是一种可用于创建 委托 或 表达式目录树 类型的 匿名函数 . 通过使用 lambda 表达式,可以写入可作为参数传递或作为函数调用值返回的本地函数. Lambda 表达式对 ...

  7. python api接口认证脚本

    import requests import sys def acces_api_with_cookie(url_login, USERNAME, PASSWORD, url_access):     ...

  8. 32位C#程序连接64位ORACLE数据库

    VS2008 生成32位程序,安装在64位服务器上,调用System.data.oracleclient            oracleConn = new OracleConnection(); ...

  9. Eclipse添加中文javadoc

    SUN官方API中文版[JDK1.6]1.6API文档(中文)的下载地址:ZIP格式用来设置javadoc,下载地址:http://download.java.net/jdk/jdk-api-loca ...

  10. WiFi密码破解详细图文教程

    每天都能看到有不少网友在回复论坛之前发布的一篇破解WiFi密码的帖子,并伴随各种疑问.今天流云就为大家准备一篇实战型的文章吧,详细图文从思维CDlinux U盘启动到中文设置,如何进行路由SSID扫描 ...