`
whoyuhui
  • 浏览: 22783 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java版A星算法实现步骤

    博客分类:
  • java
 
阅读更多

A星算法步骤: 1.起点先添加到开启列表中。 2.开启列表中有节点的话,取出第一个节点,即最小F值的节点, 判断此节点是否是目标点,是则找到了,跳出, 根据此节点取得八个方向的节点,求出G,H,F值, 判断每个节点在地图中是否能通过,不能通过则加入关闭列表中,跳出判断每个节点是否在关闭列表中,在则跳出, 判断每个节点是否在开启列表中,在则更新G值,F值,还更新其父节点;不在则将其添加到开启列表中,计算G值,H值,F值,添加其节点。 3.把此节点从开启列表中删除,再添加到关闭列表中。 4.把开启列表中按照F值最小的节点进行排序,最小的F值在第一个。 5.重复2,3,4步骤, 直到目标点在开启列表中,即找到了;目标点不在开启列表中,开启列表为空,即没找到

 

//A*算法public class AStar {  
    private int[][] map;//地图(1可通过 0不可通过)  
    private List<Node> openList;//开启列表  
    private List<Node> closeList;//关闭列表  
    private final int COST_STRAIGHT = 10;//垂直方向或水平方向移动的路径评分  
    private final int COST_DIAGONAL = 14;//斜方向移动的路径评分  
    private int row;//行  
    private int column;//列  
        public AStar(int[][] map,int row,int column){  
        this.map=map;  
        this.row=row;  
        this.column=column;  
        openList=new ArrayList<Node>();  
        closeList=new ArrayList<Node>();  
    }  
        //查找坐标(-1:错误,0:没找到,1:找到了)  
    public int search(int x1,int y1,int x2,int y2){  
        if(x1<0||x1>=row||x2<0||x2>=row||y1<0||y1>=column||y2<0||y2>=column){  
              
return -1;  
        }  
        if(map[x1][y1]==0||map[x2][y2]==0){            return -1;  
        }  
        Node sNode=new Node(x1,y1,null);  
        Node eNode=new Node(x2,y2,null);        openList.add(sNode);  
        List<Node> resultList=search(sNode, eNode);  
        if(resultList.size()==0){  
            return 0;  
        }  
        for(Node node:resultList){  
            map[node.getX()][node.getY()]=-1;  
        }  
        return 1;  
    }  
        //查找核心算法  
    private List<Node> search(Node sNode,Node eNode){  
        List<Node> resultList=new ArrayList<Node>();  
        boolean isFind=false;  
        Node node=null;  
        while(openList.size()>0){  
            //取出开启列表中最低F值,即第一个存储的值的F为最低的  
            node=openList.get(0);  
            //判断是否找到目标点  
            if(node.getX()==eNode.getX()&&node.getY()==eNode.getY()){  
                isFind=true;  
                break;  
            }  
            //上  
            if((node.getY()-1)>=0){                checkPath(node.getX(),node.getY()-1,node, eNode, COST_STRAIGHT);  
            }  
            //下  
            if((node.getY()+1)<column){  
                checkPath(node.getX(),node.getY()+1,node, eNode, COST_STRAIGHT);  
            }  
            //左  
            if((node.getX()-1)>=0){  
                checkPath(node.getX()-1,node.getY(),node, eNode, COST_STRAIGHT);  
            }  
            //右  
            if((node.getX()+1)<row){  
                checkPath(node.getX()+1,node.getY(),node, eNode, COST_STRAIGHT);  
            }  
            //左上  
            if((node.getX()-1)>=0&&(node.getY()-1)>=0){  
                checkPath(node.getX()-1,node.getY()-1,node, eNode, COST_DIAGONAL);  
            }  
            //左下  
            if((node.getX()-1)>=0&&(node.getY()+1)<column){  
                checkPath(node.getX()-1,node.getY()+1,node, eNode,COST_DIAGONAL);  
            }  
            //右上  
            if((node.getX()+1)<row&&(node.getY()-1)>=0){                checkPath(node.getX()+1,node.getY()-1,node, eNode, COST_DIAGONAL);  
            }  
            //右下  
            if((node.getX()+1)<row&&(node.getY()+1)<column){  
                checkPath(node.getX()+1,node.getY()+1,node, eNode, COST_DIAGONAL);  
            }  
            //从开启列表中删除  
            //添加到关闭列表中  
            closeList.add(openList.remove(0));  
            //开启列表中排序,把F值最低的放到最底端            Collections.sort(openList, new NodeFComparator());  
        }  
        if(isFind){  
            getPath(resultList, node);  
        }  
        return resultList;  
    }  
        //查询此路是否能走通  
    private boolean checkPath(int x,int y,Node parentNode,Node eNode,int cost){  
        Node node=new Node(x, y, parentNode);  
        //查找地图中是否能通过  
        if(map[x][y]==0){  
            closeList.add(node);  
            return false;  
        }  
        //查找关闭列表中是否存在  
        if(isListContains(closeList, x, y)!=-1){  
            return false;  
        }  
        //查找开启列表中是否存在  
        int index=-1;  
        if((index=isListContains(openList, x, y))!=-1){  
            //G值是否更小,即是否更新G,F值  
            if((parentNode.getG()+cost)<openList.get(index).getG()){  
                node.setParentNode(parentNode);  
                countG(node, eNode, cost);  
                countF(node);  
                openList.set(index, node);  
            }  
        }else{  
            //添加到开启列表中  
            node.setParentNode(parentNode);            count(node, eNode, cost);  
            openList.add(node);  
        }  
        return true;  
    }  
        //集合中是否包含某个元素(-1:没有找到,否则返回所在的索引)  
    private int isListContains(List<Node> list,int x,int y){  
        for(int i=0;i<list.size();i++){  
            Node node=list.get(i);  
            if(node.getX()==x&&node.getY()==y){  
                return i;  
            }  
        }  
        return -1;  
    }  
        //从终点往返回到起点  
    private void getPath(List<Node> resultList,Node node){  
        if(node.getParentNode()!=null){            getPath(resultList, node.getParentNode());  
        }  
        resultList.add(node);  
    }  
        //计算G,H,F值  
    private void count(Node node,Node eNode,int cost){  
        countG(node, eNode, cost);  
        countH(node, eNode);  
        countF(eNode);  
    }  
    //计算G值  
    private void countG(Node node,Node eNode,int cost){  
        if(node.getParentNode()==null){  
            node.setG(cost);  
        }else{  
            node.setG(node.getParentNode().getG()+cost);  
        }  
    }  
    //计算H值  
    private void countH(Node node,Node eNode){  
        node.setF(Math.abs(node.getX()-eNode.getX())+Math.abs(node.getY()-eNode.getY()));  
    }  
    //计算F值  
    private void countF(Node node){  
        node.setF(node.getG()+node.getF());  
    }  
    }//节点类class Node {  
    private int x;//X坐标  
    private int y;//Y坐标  
    private Node parentNode;//父类节点  
    private int g;//当前点到起点的移动耗费  
    private int h;//当前点到终点的移动耗费,即曼哈顿距离|x1-x2|+|y1-y2|(忽略障碍物)  
    private int f;//f=g+h  
        public Node(int x,int y,Node parentNode){        this.x=x;  
        this.y=y;  
        this.parentNode=parentNode;  
    }  
        public int getX() {  
        return x;  
    }  
    public void setX(int x) {  
        this.x = x;  
    }  
    public int getY() {  
        return y;  
    }  
    public void setY(int y) {  
        this.y = y;  
    }  
    public Node getParentNode() {  
        return parentNode;  
    }  
    public void setParentNode(Node parentNode) {  
        this.parentNode = parentNode;  
    }  
    public int getG() {  
        return g;  
    }  
    public void setG(int g) {  
        this.g = g;  
    }  
    public int getH() {  
        return h;  
    }  
    public void setH(int h) {  
        this.h = h;  
    }  
    public int getF() {  
        return f;  
    }  
    public void setF(int f) {  
        this.f = f;  
    }}//节点比较类class NodeFComparator implements Comparator<Node>{  
    @Override 
    public int compare(Node o1, Node o2) {  
        return o1.getF()-o2.getF();  
    }  
    }  


测试类:


public class Test {  
        public static void main(String[] args){
        int[][] map=new int[][]{
// 地图数组
                {1,1,1,1,1,1,1,1,1,1},
                {1,1,1,1,0,1,1,1,1,1},
                {1,1,1,1,0,1,1,1,1,1},
                {1,1,1,1,0,1,1,1,1,1},
                {1,1,1,1,0,1,1,1,1,1},
                {1,1,1,1,0,1,1,1,1,1}  
        };  
        AStar aStar=new AStar(map, 6, 10);  
        int flag=aStar.search(4, 0, 3, 8);  
        if(flag==-1){  
            System.out.println("传输数据有误!");  
        }else if(flag==0){  
            System.out.println("没找到!");  
        }else{  
            for(int x=0;x<6;x++){  
                for(int y=0;y<10;y++){
                    if(map[x][y]==1){
                        System.out.print(" ");
                    }else if(map[x][y]==0){
                        System.out.print("〓");
                    }else if(map[x][y]==-1){
                        System.out.print("※");  
                    }  
                }  
                System.out.println();  
            }  
        }  
    }} 
 
 
分享到:
评论

相关推荐

    A星算法MFC实现和操作步骤

    A星算法MFC实现和操作步骤.rar A算法程序设计 本程序用于实现例3.3中的10 x 10个方格中从指定起点到指定终点的最短路径,其中 可以在任意方格中放置障碍。对于10 x 10个方格使用二维数组m_a[10] [10]表示,每个 ...

    A算法具体步骤

    A星算法的具体的指导步骤,便于编写程序,初始化两个链表open和closed,将初始状态放入open表中等等

    Astar.rar a星算法

    a星算法 步骤: 1 把起始格添加到开启列表。 2 重复如下的工作: (1) 寻找开启列表中F值最低的格子。我们称它为当前格。 (2) 把它切换到关闭列表。 (3) 对相邻的8格中的每一个? a 如果它不可通过或者已经...

    A星寻路插件

    A星的工具包,还有教学实例,以及使用步骤。

    Unity 算法 之 A星(A Star/A*)寻路算法实现和封装,并带动态演示Demo

    Unity 算法 之 A星(A Star/A*)寻路算法实现和封装,并带动态演示Demo Demo 使用操作说明 1、按空格可以刷线地图,更新地图的障碍物位置(动态随机设置) 2、鼠标左键设置开始点位置 3、鼠标右键设置目标点位置...

    人工智能(A星算法).doc

    A*算法基本步骤 1)生成一个只包含开始节点n0的搜索图G,把n0放在一个叫OPEN的列表上。 2)生成一个列表CLOSED,它的初始值为空。 3)如果OPEN表为空,则失败退出。 4)选择OPEN上的第一个节点,把它从OPEN中移入...

    A*算法源码游戏地图A*算法的原型

    这个A星算法的源码基本实现了地图的基本寻路功能。灰色的点代表障碍物,绿色点代表人物起点, 用鼠标点击白色空可以实现寻路步骤。并实现了穿越拐角。 源码属于测试码写的比较粗燥。但是原理思路比较清楚。其中包括...

    路径规划基于matlab A-star算法机器人静态避障路径规划【含Matlab源码 495期】.zip

    CSDN海神之光上传的全部代码均可运行,亲测可用,直接替换数据即可,适合小白; 1、代码压缩包内容 主函数:main.m; 调用函数:其他m文件;无需运行 ...4.4.5 萤火虫算法FA/差分算法DE避障路径规划

    人工智能实验A*算法例子

    利用A星算法解决Robot问题(下面有介绍)。 Robot问题:从起点到终点需要的最短步骤,其中包括障碍物,移动方向(东西南北),每次只能转向90度或者向前走一步

    【路径规划】A星算法结合floyd和动态窗口法机器人栅格地图路径规划【含Matlab源码 2721期】1.mp4

    步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主或扫描视频QQ名片; 4.1 博客或资源的完整代码...

    算法导论(part2)

    书中的算法以英语加伪代码的形式给出,只要有一点程序设计经验的人都能读懂,并可以用任何计算机语言(如C/C++和Java等)方便地实现。在书中,作者将算法的讨论集中在一些比较现代的例子上,它们来自分子生物学(如...

    算法导论(part1)

    书中的算法以英语加伪代码的形式给出,只要有一点程序设计经验的人都能读懂,并可以用任何计算机语言(如C/C++和Java等)方便地实现。在书中,作者将算法的讨论集中在一些比较现代的例子上,它们来自分子生物学(如...

    A*自动寻路算法Unity3D

    A*自动寻路的算法,基于unity,通过点击屏幕可以知道运行的详细步骤,通过颜色,对当前点,路障,目标点,以及路径进行了标注

    dijkstra 算法说明和基础应用介绍.zip

    Dijkstra 算法,又称为迪杰斯特拉算法,是一种用于解决单源最短 路径问题的经典算法。它的核心思想是通过逐步确定起点到其他顶 点的最短路径来求解。该算法被广泛应用于图论和网络路由等领域。 Dijkstra 算法的...

    vc++ 应用源码包_1

    To Create A COOL Desktop Lyrics Demo 歌词显示,效果非常好。对话框实现。 TopMost 自绘CListCtrl的实现。 Trace程序 演示了输出信息。 TransparentStatic 自绘CStatic控件。 TreeView控件 自绘CTreeView控件...

    vc++ 应用源码包_2

    To Create A COOL Desktop Lyrics Demo 歌词显示,效果非常好。对话框实现。 TopMost 自绘CListCtrl的实现。 Trace程序 演示了输出信息。 TransparentStatic 自绘CStatic控件。 TreeView控件 自绘CTreeView控件...

    vc++ 应用源码包_6

    To Create A COOL Desktop Lyrics Demo 歌词显示,效果非常好。对话框实现。 TopMost 自绘CListCtrl的实现。 Trace程序 演示了输出信息。 TransparentStatic 自绘CStatic控件。 TreeView控件 自绘CTreeView控件...

    vc++ 应用源码包_5

    To Create A COOL Desktop Lyrics Demo 歌词显示,效果非常好。对话框实现。 TopMost 自绘CListCtrl的实现。 Trace程序 演示了输出信息。 TransparentStatic 自绘CStatic控件。 TreeView控件 自绘CTreeView控件...

    vc++ 应用源码包_3

    To Create A COOL Desktop Lyrics Demo 歌词显示,效果非常好。对话框实现。 TopMost 自绘CListCtrl的实现。 Trace程序 演示了输出信息。 TransparentStatic 自绘CStatic控件。 TreeView控件 自绘CTreeView控件...

    vc++ 开发实例源码包

    ----------VC应用开发 [Visual.C..编程技巧精选500例]源代码. 内含各种例子(vc下各种控件的使用方法、标题栏...To Create A COOL Desktop Lyrics Demo 歌词显示,效果非常好。对话框实现。 TopMost 自绘CListCtrl的...

Global site tag (gtag.js) - Google Analytics