A*寻路算法
一、算法思路:
1、两个集合:openList和closeList
openList:存放每走一步后可能的搜索节点集合。
closeList:存放已经走过的节点的集合。
2、估值函数:F = G + H
F:起始节点startNode到终止节点endNode的距离
G:起始节点startNode到当前节点的距离
H:当前节点到终止节点endNode的距离
初始条件现将startNode加入openList中
进入while主循环:
1)、以checkedNode节点为中心,分别从上下左右四个方向搜寻剩余可达的节点,如果能够搜寻到,则加入openList,同时将该搜寻到的节点标记为不可达(isOpen置为false)
2)、从openList中的所有节点中选出一个F值最小的节点(这样的节点很可能不止一个,但是这些同时获得最小F的节点都会被“走到”),这个节点将被标记为checkedNode,将checkedNode移除openList,加入closeList,至此一轮循环完毕,进入下一轮循环。
3)、直到checkedNode等于endNode,循环结束。
为方便获取路径,在第一步以checkedNode为中心搜寻剩余可达节点时,新加入openList的节点都为checkedNode的子节点。
nextNode.parent = checkedNode;
不难发现,openList和closeList中节点的父子关系共同构成了一颗搜索树。
例如
int row = 5,column = 7;
Node startNode = data[2][1];
Node endNode = data[0][2];
在不设置任何障碍的情况下,其搜索树为:
当算法结束之后,不难发现:
1、所有openList中的节点都是叶节点,所有closeList中的节点有孩子,除了endNode外其余均为非叶节点。
2、每轮搜寻都是从当前的搜索树中的叶节点中展开搜索的。
3、沿着endNode逐渐往上同过parent属性,可以获得一条最短路径。当然这唯一的最短路径。
4、最终路径中所有节点的F值均相等等于搜索树中所有节点的F值的最小值(本例minF为3)。
二、java代码实现
1 package agstring; 2 3 import java.util.ArrayList; 4 import java.util.*; 5 class Node{ 6 public final int x,y; 7 public final double weight; 8 public boolean isOpen = true; 9 public Node parent; 10 public int varF = 0,varG = 0,varH = 0; 11 public Node(int x,int y,double weight){ 12 this.x = x; 13 this.y = y; 14 this.weight = weight; 15 } 16 public Node(int x,int y){ 17 this(x, y, 0.0); 18 } 19 public String toString(){ 20 return "("+"x:"+this.x+","+"y:"+this.y+","+"w:"+this.weight+")"; 21 } 22 } 23 public class AStar { 24 25 public static Node[][] initData(int row,int column){ 26 Node[][] tableOf2D = new Node[row][column]; 27 for (int i = 0; i < row; i++) { 28 for (int j = 0; j < column; j++) { 29 tableOf2D[i][j] = new Node(i,j); 30 } 31 } 32 return tableOf2D; 33 } 34 private static int getDistance(Node startNode,Node endNode){ 35 return Math.abs(endNode.x - startNode.x) + Math.abs(endNode.y - startNode.y); 36 } 37 38 private static void updateFGH(Node node,Node startNode,Node endNode){ 39 node.varG = getDistance(startNode, node); 40 node.varH = getDistance(node, endNode); 41 node.varF = node.varG + node.varH; 42 } 43 44 public static Node[] AStarAlgo(Node[][] tableOf2D,Node startNode,Node endNode){ 45 int row = tableOf2D.length,column = tableOf2D[0].length; 46 ArrayList<Node> openList = new ArrayList<Node>(); 47 ArrayList<Node> closeList = new ArrayList<Node>(); 48 Node nextNode,checkedNode = startNode; 49 int minF; 50 closeList.add(startNode); 51 startNode.isOpen = false; 52 while(!checkedNode.equals(endNode)){//!checkedNode.equals(endNode) 53 if (checkedNode.y-1 >= 0 && tableOf2D[checkedNode.x][checkedNode.y-1].isOpen ) { 54 nextNode = tableOf2D[checkedNode.x][checkedNode.y-1]; 55 nextNode.parent = checkedNode; 56 openList.add(nextNode); 57 updateFGH(nextNode,startNode,endNode); 58 nextNode.isOpen = false; 59 } 60 if (checkedNode.y+1 <= column-1 && tableOf2D[checkedNode.x][checkedNode.y+1].isOpen ) { 61 nextNode = tableOf2D[checkedNode.x][checkedNode.y+1]; 62 nextNode.parent = checkedNode; 63 openList.add(nextNode); 64 updateFGH(nextNode,startNode,endNode); 65 nextNode.isOpen = false; 66 } 67 if (checkedNode.x-1 >= 0 && tableOf2D[checkedNode.x-1][checkedNode.y].isOpen ) { 68 nextNode = tableOf2D[checkedNode.x-1][checkedNode.y]; 69 nextNode.parent = checkedNode; 70 openList.add(nextNode); 71 updateFGH(nextNode,startNode,endNode); 72 nextNode.isOpen = false; 73 } 74 if (checkedNode.x+1 <= row-1 && tableOf2D[checkedNode.x+1][checkedNode.y].isOpen ) { 75 nextNode = tableOf2D[checkedNode.x+1][checkedNode.y]; 76 nextNode.parent = checkedNode; 77 openList.add(nextNode); 78 updateFGH(nextNode,startNode,endNode); 79 nextNode.isOpen = false; 80 } 81 82 minF = Integer.MAX_VALUE; 83 for (int i = 0; i < openList.size(); i++) { 84 if (openList.get(i).varF < minF) { 85 checkedNode = openList.get(i); 86 minF = checkedNode.varF; 87 } 88 } 89 closeList.add(checkedNode); 90 openList.remove(checkedNode); 91 92 } 93 return closeList.toArray(new Node[closeList.size()]); 94 } 95 public static void main(String[] args) { 96 // TODO Auto-generated method stub 97 try { 98 int row = 5,column = 7; 99 Node[][] data = initData(row, column); 100 // for (int i = 0; i < row ; i++) { 101 // for (int j = 0; j < column; j++) { 102 // System.out.println(data[i][j]); 103 // } 104 // } 105 // data[1][3].isOpen = data[2][3].isOpen = data[3][3].isOpen = data[4][3].isOpen = false; 106 // data[0][5].isOpen = data[1][5].isOpen = data[2][5].isOpen = data[3][5].isOpen = false; 107 Node startNode = data[2][1]; 108 Node endNode = data[0][2]; 109 Node[] pathAry = AStarAlgo(data,startNode,endNode); 110 111 Node tmpNode = endNode; 112 while(!(tmpNode == null)){ 113 System.out.println(tmpNode); 114 tmpNode = tmpNode.parent; 115 } 116 } catch (Exception e) { 117 // TODO: handle exception 118 e.printStackTrace(); 119 } 120 } 121 122 }