Java版A星算法实现步骤

开发 后端 算法
A星算法步骤:1.起点先添加到开启列表中;2.开启列表中有节点的话,取出第一个节点,即最小F值的节点……

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.               
  20. return -1;  
  21.         }  
  22.         if(map[x1][y1]==0||map[x2][y2]==0){            return -1;  
  23.         }  
  24.         Node sNode=new Node(x1,y1,null);  
  25.         Node eNode=new Node(x2,y2,null);        openList.add(sNode);  
  26.         List<Node> resultList=search(sNode, eNode);  
  27.         if(resultList.size()==0){  
  28.             return 0;  
  29.         }  
  30.         for(Node node:resultList){  
  31.             map[node.getX()][node.getY()]=-1;  
  32.         }  
  33.         return 1;  
  34.     }  
  35.         //查找核心算法  
  36.     private List<Node> search(Node sNode,Node eNode){  
  37.         List<Node> resultList=new ArrayList<Node>();  
  38.         boolean isFind=false;  
  39.         Node node=null;  
  40.         while(openList.size()>0){  
  41.             //取出开启列表中***F值,即***个存储的值的F为***的  
  42.             node=openList.get(0);  
  43.             //判断是否找到目标点  
  44.             if(node.getX()==eNode.getX()&&node.getY()==eNode.getY()){  
  45.                 isFind=true;  
  46.                 break;  
  47.             }  
  48.             //上  
  49.             if((node.getY()-1)>=0){                checkPath(node.getX(),node.getY()-1,node, eNode, COST_STRAIGHT);  
  50.             }  
  51.             //下  
  52.             if((node.getY()+1)<column){  
  53.                 checkPath(node.getX(),node.getY()+1,node, eNode, COST_STRAIGHT);  
  54.             }  
  55.             //左  
  56.             if((node.getX()-1)>=0){  
  57.                 checkPath(node.getX()-1,node.getY(),node, eNode, COST_STRAIGHT);  
  58.             }  
  59.             //右  
  60.             if((node.getX()+1)<row){  
  61.                 checkPath(node.getX()+1,node.getY(),node, eNode, COST_STRAIGHT);  
  62.             }  
  63.             //左上  
  64.             if((node.getX()-1)>=0&&(node.getY()-1)>=0){  
  65.                 checkPath(node.getX()-1,node.getY()-1,node, eNode, COST_DIAGONAL);  
  66.             }  
  67.             //左下  
  68.             if((node.getX()-1)>=0&&(node.getY()+1)<column){  
  69.                 checkPath(node.getX()-1,node.getY()+1,node, eNode,COST_DIAGONAL);  
  70.             }  
  71.             //右上  
  72.             if((node.getX()+1)<row&&(node.getY()-1)>=0){                checkPath(node.getX()+1,node.getY()-1,node, eNode, COST_DIAGONAL);  
  73.             }  
  74.             //右下  
  75.             if((node.getX()+1)<row&&(node.getY()+1)<column){  
  76.                 checkPath(node.getX()+1,node.getY()+1,node, eNode, COST_DIAGONAL);  
  77.             }  
  78.             //从开启列表中删除  
  79.             //添加到关闭列表中  
  80.             closeList.add(openList.remove(0));  
  81.             //开启列表中排序,把F值***的放到***端            Collections.sort(openList, new NodeFComparator());  
  82.         }  
  83.         if(isFind){  
  84.             getPath(resultList, node);  
  85.         }  
  86.         return resultList;  
  87.     }  
  88.         //查询此路是否能走通  
  89.     private boolean checkPath(int x,int y,Node parentNode,Node eNode,int cost){  
  90.         Node node=new Node(x, y, parentNode);  
  91.         //查找地图中是否能通过  
  92.         if(map[x][y]==0){  
  93.             closeList.add(node);  
  94.             return false;  
  95.         }  
  96.         //查找关闭列表中是否存在  
  97.         if(isListContains(closeList, x, y)!=-1){  
  98.             return false;  
  99.         }  
  100.         //查找开启列表中是否存在  
  101.         int index=-1;  
  102.         if((index=isListContains(openList, x, y))!=-1){  
  103.             //G值是否更小,即是否更新G,F值  
  104.             if((parentNode.getG()+cost)<openList.get(index).getG()){  
  105.                 node.setParentNode(parentNode);  
  106.                 countG(node, eNode, cost);  
  107.                 countF(node);  
  108.                 openList.set(index, node);  
  109.             }  
  110.         }else{  
  111.             //添加到开启列表中  
  112.             node.setParentNode(parentNode);            count(node, eNode, cost);  
  113.             openList.add(node);  
  114.         }  
  115.         return true;  
  116.     }  
  117.         //集合中是否包含某个元素(-1:没有找到,否则返回所在的索引)  
  118.     private int isListContains(List<Node> list,int x,int y){  
  119.         for(int i=0;i<list.size();i++){  
  120.             Node node=list.get(i);  
  121.             if(node.getX()==x&&node.getY()==y){  
  122.                 return i;  
  123.             }  
  124.         }  
  125.         return -1;  
  126.     }  
  127.         //从终点往返回到起点  
  128.     private void getPath(List<Node> resultList,Node node){  
  129.         if(node.getParentNode()!=null){            getPath(resultList, node.getParentNode());  
  130.         }  
  131.         resultList.add(node);  
  132.     }  
  133.         //计算G,H,F值  
  134.     private void count(Node node,Node eNode,int cost){  
  135.         countG(node, eNode, cost);  
  136.         countH(node, eNode);  
  137.         countF(eNode);  
  138.     }  
  139.     //计算G值  
  140.     private void countG(Node node,Node eNode,int cost){  
  141.         if(node.getParentNode()==null){  
  142.             node.setG(cost);  
  143.         }else{  
  144.             node.setG(node.getParentNode().getG()+cost);  
  145.         }  
  146.     }  
  147.     //计算H值  
  148.     private void countH(Node node,Node eNode){  
  149.         node.setF(Math.abs(node.getX()-eNode.getX())+Math.abs(node.getY()-eNode.getY()));  
  150.     }  
  151.     //计算F值  
  152.     private void countF(Node node){  
  153.         node.setF(node.getG()+node.getF());  
  154.     }  
  155.     }//节点类class Node {  
  156.     private int x;//X坐标  
  157.     private int y;//Y坐标  
  158.     private Node parentNode;//父类节点  
  159.     private int g;//当前点到起点的移动耗费  
  160.     private int h;//当前点到终点的移动耗费,即曼哈顿距离|x1-x2|+|y1-y2|(忽略障碍物)  
  161.     private int f;//f=g+h  
  162.         public Node(int x,int y,Node parentNode){        this.x=x;  
  163.         this.y=y;  
  164.         this.parentNode=parentNode;  
  165.     }  
  166.         public int getX() {  
  167.         return x;  
  168.     }  
  169.     public void setX(int x) {  
  170.         this.x = x;  
  171.     }  
  172.     public int getY() {  
  173.         return y;  
  174.     }  
  175.     public void setY(int y) {  
  176.         this.y = y;  
  177.     }  
  178.     public Node getParentNode() {  
  179.         return parentNode;  
  180.     }  
  181.     public void setParentNode(Node parentNode) {  
  182.         this.parentNode = parentNode;  
  183.     }  
  184.     public int getG() {  
  185.         return g;  
  186.     }  
  187.     public void setG(int g) {  
  188.         this.g = g;  
  189.     }  
  190.     public int getH() {  
  191.         return h;  
  192.     }  
  193.     public void setH(int h) {  
  194.         this.h = h;  
  195.     }  
  196.     public int getF() {  
  197.         return f;  
  198.     }  
  199.     public void setF(int f) {  
  200.         this.f = f;  
  201.     }}//节点比较类class NodeFComparator implements Comparator<Node>{  
  202.     @Override 
  203.     public int compare(Node o1, Node o2) {  
  204.         return o1.getF()-o2.getF();  
  205.     }  
  206.     }  

 测试类:

  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, 610);  
  13.         int flag=aStar.search(4038);  
  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.     }} 

原文链接:http://www.cnblogs.com/xmmdream/archive/2011/12/12/2284627.html

【编辑推荐】

  1. Tomcat运行Java Web内存溢出总结
  2. Java NIO如何处理慢速的连接
  3. Java数据缓存实现的核心机制
  4. Java与Cobol对决:Cobol软件质量最过硬
  5. Java NIO类库关系图解
责任编辑:林师授 来源: 尘锋的博客
相关推荐

2020-05-19 14:27:10

GitHubPythonAI算法

2011-04-20 10:58:34

Java

2020-08-21 13:41:04

代码开发工具

2023-06-13 06:51:09

Spark机器学习回归

2019-08-12 08:43:53

GitHub代码开发者

2010-06-08 10:34:23

opensuse 10

2011-10-17 10:15:12

iMessageChatON三星

2018-03-07 15:27:57

三星笔记本

2010-06-09 09:33:41

Opensuse硬盘

2010-06-09 11:05:48

Opensuse安装m

2010-06-04 16:47:49

实现Hadoop

2015-07-29 10:31:16

Java缓存算法

2017-02-09 16:16:24

Java负载均衡算法

2023-06-25 07:42:02

2020-04-14 15:00:04

PyTorchGitHub检测

2020-07-30 07:52:13

JavaLRU算法

2010-04-06 16:36:55

Oracle绑定变量

2009-10-09 16:40:45

RHEL5安装

2010-07-22 13:23:46

telnet SMTP

2010-09-09 08:52:19

JavascriptDIV
点赞
收藏

51CTO技术栈公众号