A*(也叫A star, A星)寻路算法Java版

来源:互联网 发布:内向工作知乎 编辑:程序博客网 时间:2024/05/18 03:31

转载自:http://blog.csdn.net/ruils/article/details/40780657


寻路算法有很多种,A*寻路算法被公认为最好的寻路算法。

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

http://www.gamedev.net/page/resources/_/technical/artificial-intelligence/a-pathfinding-for-beginners-r2003(英文)

http://www.cppblog.com/christanxw/archive/2006/04/07/5126.html(中文)

http://www.cnblogs.com/technology/archive/2011/05/26/2058842.html(中文)


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


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


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

最后代码:


[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. import java.util.ArrayList;  
  2. import java.util.List;  
  3.   
  4. public class AStar {  
  5.   
  6.     public static final int[][] NODES = {   
  7.         { 000000000 },  
  8.         { 000000000 },  
  9.         { 000000000 },   
  10.         { 000100000 },   
  11.         { 000100000 },  
  12.         { 000100000 },   
  13.         { 000100000 },   
  14.         { 000000000 },  
  15.         { 000000000 },   
  16.     };  
  17.   
  18.     public static final int STEP = 10;  
  19.   
  20.     private ArrayList<Node> openList = new ArrayList<Node>();  
  21.     private ArrayList<Node> closeList = new ArrayList<Node>();  
  22.   
  23.     public Node findMinFNodeInOpneList() {  
  24.         Node tempNode = openList.get(0);  
  25.         for (Node node : openList) {  
  26.             if (node.F < tempNode.F) {  
  27.                 tempNode = node;  
  28.             }  
  29.         }  
  30.         return tempNode;  
  31.     }  
  32.   
  33.     public ArrayList<Node> findNeighborNodes(Node currentNode) {  
  34.         ArrayList<Node> arrayList = new ArrayList<Node>();  
  35.         // 只考虑上下左右,不考虑斜对角  
  36.         int topX = currentNode.x;  
  37.         int topY = currentNode.y - 1;  
  38.         if (canReach(topX, topY) && !exists(closeList, topX, topY)) {  
  39.             arrayList.add(new Node(topX, topY));  
  40.         }  
  41.         int bottomX = currentNode.x;  
  42.         int bottomY = currentNode.y + 1;  
  43.         if (canReach(bottomX, bottomY) && !exists(closeList, bottomX, bottomY)) {  
  44.             arrayList.add(new Node(bottomX, bottomY));  
  45.         }  
  46.         int leftX = currentNode.x - 1;  
  47.         int leftY = currentNode.y;  
  48.         if (canReach(leftX, leftY) && !exists(closeList, leftX, leftY)) {  
  49.             arrayList.add(new Node(leftX, leftY));  
  50.         }  
  51.         int rightX = currentNode.x + 1;  
  52.         int rightY = currentNode.y;  
  53.         if (canReach(rightX, rightY) && !exists(closeList, rightX, rightY)) {  
  54.             arrayList.add(new Node(rightX, rightY));  
  55.         }  
  56.         return arrayList;  
  57.     }  
  58.   
  59.     public boolean canReach(int x, int y) {  
  60.         if (x >= 0 && x < NODES.length && y >= 0 && y < NODES[0].length) {  
  61.             return NODES[x][y] == 0;  
  62.         }  
  63.         return false;  
  64.     }  
  65.   
  66.     public Node findPath(Node startNode, Node endNode) {  
  67.   
  68.         // 把起点加入 open list  
  69.         openList.add(startNode);  
  70.   
  71.         while (openList.size() > 0) {  
  72.             // 遍历 open list ,查找 F值最小的节点,把它作为当前要处理的节点  
  73.             Node currentNode = findMinFNodeInOpneList();  
  74.             // 从open list中移除  
  75.             openList.remove(currentNode);  
  76.             // 把这个节点移到 close list  
  77.             closeList.add(currentNode);  
  78.   
  79.             ArrayList<Node> neighborNodes = findNeighborNodes(currentNode);  
  80.             for (Node node : neighborNodes) {  
  81.                 if (exists(openList, node)) {  
  82.                     foundPoint(currentNode, node);  
  83.                 } else {  
  84.                     notFoundPoint(currentNode, endNode, node);  
  85.                 }  
  86.             }  
  87.             if (find(openList, endNode) != null) {  
  88.                 return find(openList, endNode);  
  89.             }  
  90.         }  
  91.   
  92.         return find(openList, endNode);  
  93.     }  
  94.   
  95.     private void foundPoint(Node tempStart, Node node) {  
  96.         int G = calcG(tempStart, node);  
  97.         if (G < node.G) {  
  98.             node.parent = tempStart;  
  99.             node.G = G;  
  100.             node.calcF();  
  101.         }  
  102.     }  
  103.   
  104.     private void notFoundPoint(Node tempStart, Node end, Node node) {  
  105.         node.parent = tempStart;  
  106.         node.G = calcG(tempStart, node);  
  107.         node.H = calcH(end, node);  
  108.         node.calcF();  
  109.         openList.add(node);  
  110.     }  
  111.   
  112.     private int calcG(Node start, Node node) {  
  113.         int G = STEP;  
  114.         int parentG = node.parent != null ? node.parent.G : 0;  
  115.         return G + parentG;  
  116.     }  
  117.   
  118.     private int calcH(Node end, Node node) {  
  119.         int step = Math.abs(node.x - end.x) + Math.abs(node.y - end.y);  
  120.         return step * STEP;  
  121.     }  
  122.   
  123.     public static void main(String[] args) {  
  124.         Node startNode = new Node(51);  
  125.         Node endNode = new Node(55);  
  126.         Node parent = new AStar().findPath(startNode, endNode);  
  127.   
  128.         for (int i = 0; i < NODES.length; i++) {  
  129.             for (int j = 0; j < NODES[0].length; j++) {  
  130.                 System.out.print(NODES[i][j] + ", ");  
  131.             }  
  132.             System.out.println();  
  133.         }  
  134.         ArrayList<Node> arrayList = new ArrayList<Node>();  
  135.   
  136.         while (parent != null) {  
  137.             // System.out.println(parent.x + ", " + parent.y);  
  138.             arrayList.add(new Node(parent.x, parent.y));  
  139.             parent = parent.parent;  
  140.         }  
  141.         System.out.println("\n");  
  142.   
  143.         for (int i = 0; i < NODES.length; i++) {  
  144.             for (int j = 0; j < NODES[0].length; j++) {  
  145.                 if (exists(arrayList, i, j)) {  
  146.                     System.out.print("@, ");  
  147.                 } else {  
  148.                     System.out.print(NODES[i][j] + ", ");  
  149.                 }  
  150.   
  151.             }  
  152.             System.out.println();  
  153.         }  
  154.   
  155.     }  
  156.   
  157.     public static Node find(List<Node> nodes, Node point) {  
  158.         for (Node n : nodes)  
  159.             if ((n.x == point.x) && (n.y == point.y)) {  
  160.                 return n;  
  161.             }  
  162.         return null;  
  163.     }  
  164.   
  165.     public static boolean exists(List<Node> nodes, Node node) {  
  166.         for (Node n : nodes) {  
  167.             if ((n.x == node.x) && (n.y == node.y)) {  
  168.                 return true;  
  169.             }  
  170.         }  
  171.         return false;  
  172.     }  
  173.   
  174.     public static boolean exists(List<Node> nodes, int x, int y) {  
  175.         for (Node n : nodes) {  
  176.             if ((n.x == x) && (n.y == y)) {  
  177.                 return true;  
  178.             }  
  179.         }  
  180.         return false;  
  181.     }  
  182.   
  183.     public static class Node {  
  184.         public Node(int x, int y) {  
  185.             this.x = x;  
  186.             this.y = y;  
  187.         }  
  188.   
  189.         public int x;  
  190.         public int y;  
  191.   
  192.         public int F;  
  193.         public int G;  
  194.         public int H;  
  195.   
  196.         public void calcF() {  
  197.             this.F = this.G + this.H;  
  198.         }  
  199.   
  200.         public Node parent;  
  201.     }  
  202. }  
0 0
原创粉丝点击