程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java版A星算法實現步驟

Java版A星算法實現步驟

編輯:關於JAVA

A星算法步驟:

1.起點先添加到開啟列表中。

2.開啟列表中有節點的話,取出第一個節點,即最小F值的節點,

判斷此節點是否是目標點,是則找到了,跳出,

根據此節點取得八個方向的節點,求出G,H,F值,

判斷每個節點在地圖中是否能通過,不能通過則加入關閉列表中,跳出判斷每個節點是否在關閉列表中,在則跳出,

判斷每個節點是否在開啟列表中,在則更新G值,F值,還更新其父節點;不在則將其添加到開啟列表中,計算G值,H值,F值,添加其節點。

3.把此節點從開啟列表中刪除,再添加到關閉列表中。

4.把開啟列表中按照F值最小的節點進行排序,最小的F值在第一個。

5.重復2,3,4步驟,

直到目標點在開啟列表中,即找到了;目標點不在開啟列表中,開啟列表為空,即沒找到。

  1. //A*算法public class AStar {
  2. private int[][] map;//地圖(1可通過 0不可通過)
  3. private List<Node> openList;//開啟列表
  4. private List<Node> closeList;//關閉列表
  5. private final int COST_STRAIGHT = 10;//垂直方向或水平方向移動的路徑評分
  6. private final int COST_DIAGONAL = 14;//斜方向移動的路徑評分
  7. private int row;//行
  8. private int column;//列
  9. public AStar(int[][] map,int row,int column){
  10. this.map=map;
  11. this.row=row;
  12. this.column=column;
  13. openList=new ArrayList<Node>();
  14. closeList=new ArrayList<Node>();
  15. }
  16. //查找坐標(-1:錯誤,0:沒找到,1:找到了)
  17. public int search(int x1,int y1,int x2,int y2){
  18. if(x1<0||x1>=row||x2<0||x2>=row||y1<0||y1>=column||y2<0||y2>=column){
  19. return -1;
  20. }
  21. if(map[x1][y1]==0||map[x2][y2]==0){ return -1;
  22. }
  23. Node sNode=new Node(x1,y1,null);
  24. Node eNode=new Node(x2,y2,null); openList.add(sNode);
  25. List<Node> resultList=search(sNode, eNode);
  26. if(resultList.size()==0){
  27. return 0;
  28. }
  29. for(Node node:resultList){
  30. map[node.getX()][node.getY()]=-1;
  31. }
  32. return 1;
  33. }
  34. //查找核心算法
  35. private List<Node> search(Node sNode,Node eNode){
  36. List<Node> resultList=new ArrayList<Node>();
  37. boolean isFind=false;
  38. Node node=null;
  39. while(openList.size()>0){
  40. //取出開啟列表中最低F值,即第一個存儲的值的F為最低的
  41. node=openList.get(0);
  42. //判斷是否找到目標點
  43. if(node.getX()==eNode.getX()&&node.getY()==eNode.getY()){
  44. isFind=true;
  45. break;
  46. }
  47. //上
  48. if((node.getY()-1)>=0){ checkPath(node.getX(),node.getY()-1,node, eNode, COST_STRAIGHT);
  49. }
  50. //下
  51. if((node.getY()+1)<column){
  52. checkPath(node.getX(),node.getY()+1,node, eNode, COST_STRAIGHT);
  53. }
  54. //左
  55. if((node.getX()-1)>=0){
  56. checkPath(node.getX()-1,node.getY(),node, eNode, COST_STRAIGHT);
  57. }
  58. //右
  59. if((node.getX()+1)<row){
  60. checkPath(node.getX()+1,node.getY(),node, eNode, COST_STRAIGHT);
  61. }
  62. //左上
  63. if((node.getX()-1)>=0&&(node.getY()-1)>=0){
  64. checkPath(node.getX()-1,node.getY()-1,node, eNode, COST_DIAGONAL);
  65. }
  66. //左下
  67. if((node.getX()-1)>=0&&(node.getY()+1)<column){
  68. checkPath(node.getX()-1,node.getY()+1,node, eNode,COST_DIAGONAL);
  69. }
  70. //右上
  71. if((node.getX()+1)<row&&(node.getY()-1)>=0){ checkPath(node.getX()+1,node.getY()-1,node, eNode, COST_DIAGONAL);
  72. }
  73. //右下
  74. if((node.getX()+1)<row&&(node.getY()+1)<column){
  75. checkPath(node.getX()+1,node.getY()+1,node, eNode, COST_DIAGONAL);
  76. }
  77. //從開啟列表中刪除
  78. //添加到關閉列表中
  79. closeList.add(openList.remove(0));
  80. //開啟列表中排序,把F值最低的放到最底端 Collections.sort(openList, new NodeFComparator());
  81. }
  82. if(isFind){
  83. getPath(resultList, node);
  84. }
  85. return resultList;
  86. }
  87. //查詢此路是否能走通
  88. private boolean checkPath(int x,int y,Node parentNode,Node eNode,int cost){
  89. Node node=new Node(x, y, parentNode);
  90. //查找地圖中是否能通過
  91. if(map[x][y]==0){
  92. closeList.add(node);
  93. return false;
  94. }
  95. //查找關閉列表中是否存在
  96. if(isListContains(closeList, x, y)!=-1){
  97. return false;
  98. }
  99. //查找開啟列表中是否存在
  100. int index=-1;
  101. if((index=isListContains(openList, x, y))!=-1){
  102. //G值是否更小,即是否更新G,F值
  103. if((parentNode.getG()+cost)<openList.get(index).getG()){
  104. node.setParentNode(parentNode);
  105. countG(node, eNode, cost);
  106. countF(node);
  107. openList.set(index, node);
  108. }
  109. }else{
  110. //添加到開啟列表中
  111. node.setParentNode(parentNode); count(node, eNode, cost);
  112. openList.add(node);
  113. }
  114. return true;
  115. }
  116. //集合中是否包含某個元素(-1:沒有找到,否則返回所在的索引)
  117. private int isListContains(List<Node> list,int x,int y){
  118. for(int i=0;i<list.size();i++){
  119. Node node=list.get(i);
  120. if(node.getX()==x&&node.getY()==y){
  121. return i;
  122. }
  123. }
  124. return -1;
  125. }
  126. //從終點往返回到起點
  127. private void getPath(List<Node> resultList,Node node){
  128. if(node.getParentNode()!=null){ getPath(resultList, node.getParentNode());
  129. }
  130. resultList.add(node);
  131. }
  132. //計算G,H,F值
  133. private void count(Node node,Node eNode,int cost){
  134. countG(node, eNode, cost);
  135. countH(node, eNode);
  136. countF(eNode);
  137. }
  138. //計算G值
  139. private void countG(Node node,Node eNode,int cost){
  140. if(node.getParentNode()==null){
  141. node.setG(cost);
  142. }else{
  143. node.setG(node.getParentNode().getG()+cost);
  144. }
  145. }
  146. //計算H值
  147. private void countH(Node node,Node eNode){
  148. node.setF(Math.abs(node.getX()-eNode.getX())+Math.abs(node.getY()-eNode.getY()));
  149. }
  150. //計算F值
  151. private void countF(Node node){
  152. node.setF(node.getG()+node.getF());
  153. }
  154. }//節點類class Node {
  155. private int x;//X坐標
  156. private int y;//Y坐標
  157. private Node parentNode;//父類節點
  158. private int g;//當前點到起點的移動耗費
  159. private int h;//當前點到終點的移動耗費,即曼哈頓距離|x1-x2|+|y1-y2|(忽略障礙物)
  160. private int f;//f=g+h
  161. public Node(int x,int y,Node parentNode){ this.x=x;
  162. this.y=y;
  163. this.parentNode=parentNode;
  164. }
  165. public int getX() {
  166. return x;
  167. }
  168. public void setX(int x) {
  169. this.x = x;
  170. }
  171. public int getY() {
  172. return y;
  173. }
  174. public void setY(int y) {
  175. this.y = y;
  176. }
  177. public Node getParentNode() {
  178. return parentNode;
  179. }
  180. public void setParentNode(Node parentNode) {
  181. this.parentNode = parentNode;
  182. }
  183. public int getG() {
  184. return g;
  185. }
  186. public void setG(int g) {
  187. this.g = g;
  188. }
  189. public int getH() {
  190. return h;
  191. }
  192. public void setH(int h) {
  193. this.h = h;
  194. }
  195. public int getF() {
  196. return f;
  197. }
  198. public void setF(int f) {
  199. this.f = f;
  200. }}//節點比較類class NodeFComparator implements Comparator<Node>{
  201. @Override
  202. public int compare(Node o1, Node o2) {
  203. return o1.getF()-o2.getF();
  204. }
  205. }

測試類:

  1. public class Test {
  2. public static void main(String[] args){
  3. int[][] map=new int[][]{
  4. // 地圖數組
  5. {1,1,1,1,1,1,1,1,1,1},
  6. {1,1,1,1,0,1,1,1,1,1},
  7. {1,1,1,1,0,1,1,1,1,1},
  8. {1,1,1,1,0,1,1,1,1,1},
  9. {1,1,1,1,0,1,1,1,1,1},
  10. {1,1,1,1,0,1,1,1,1,1}
  11. };
  12. AStar aStar=new AStar(map, 6, 10);
  13. int flag=aStar.search(4, 0, 3, 8);
  14. if(flag==-1){
  15. System.out.println("傳輸數據有誤!");
  16. }else if(flag==0){
  17. System.out.println("沒找到!");
  18. }else{
  19. for(int x=0;x<6;x++){
  20. for(int y=0;y<10;y++){
  21. if(map[x][y]==1){
  22. System.out.print(" ");
  23. }else if(map[x][y]==0){
  24. System.out.print("〓");
  25. }else if(map[x][y]==-1){
  26. System.out.print("※");
  27. }
  28. }
  29. System.out.println();
  30. }
  31. }
  32. }}
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved