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 }

 

posted @ 2017-09-11 23:58  Qcer  阅读(216)  评论(0编辑  收藏  举报