每日学习一算法【2】A*算法

来源:互联网 发布:java程序的开始 编辑:程序博客网 时间:2024/05/21 23:33

    用了一天来学习这个算法,好歹是写出程序来了。

        我是从某个前辈的博客学习的A*算法,想看原文可以点击这里。不过这篇译文有些问题,比如一些数字没有显示出来,这算比较次要的,主要的是后面循环寻路说的有些模糊,我和舍友推了一下午,后来才算明白过来。

下面我来在上文基础上,简化成二维矩阵的A*寻路问题来讲一些心得体会。

首先,A*的关键寻路函数:f = g + h。g是 从起点到该节点 按照所选路径走 所需要的花费。h是该节点到终点的曼哈顿距离*常数。按我理解,这个常数是为了保持g和h在一个数量级上,以免让g或h单独做大。

另外,本文所采用代码用到了优先队列,不了解可以看这个博客——优先队列的使用

我们从开启列表中选择F值最低的节点。然后,对选中的节点做如下处理:

1.把它从开启队列删除,然后添加到关闭列表中。

//先把起始节点赋给当前节点,并放入关闭队列    current = _start;    close.push(current);

2.检查所有相邻格子。跳过那些已经在关闭列表中的或者不可通过的(有墙,水的地形,或者其他无法通过的地形),把他们添加进开启列表,如果他们还不在里面的话。 把选中的方格作为新的方格的父节点。

 //开始寻路    while (true) {        int x = 0,y = 0;        for (int i = 0; i < 4; i++) {//向四个方向寻路            x = current.position.x + des[i].x;            y = current.position.y + des[i].y;                        if (map[x][y]!=2&&(!findInClose(x,y))) {//判断是否是墙,或者是否存在于关闭队列                node q;                q.father = new node;                *(q.father) = current;                q.position.x = x;                q.position.y = y;                q.fx = f(q);                q.gx = g(q);                q.hx = h(q);                                open.push(q);//把寻到的节点放入开启队列            }                        if (map[x][y]==3) {//如果找到终点就停止                break;            }        }                current = open.top();//当前节点 等于 开启队列中的最优节点        open.pop();//从开启队列中删除放入关闭队列        close.push(current);        if (map[x][y]==3) {            break;        }            }        //寻路完毕,所有最优节点都已放入关闭队列


3.*如果某个相邻格已经在开启列表里了,检查现在的这条路径是否更好。换句话说,检查如果我们用新的路径到达它的话,G值是否会更低一些。如果不是,那就什么都不做。另一方面,如果新的G值更低,那就把相邻方格的父节点改为目前选中的方格(在上面的图表中,把箭头的方向改为指向这个方格)。最后,重新计算F和G的值。(这一段话在本文中没有用处,因为本文中节点前进只有4个方向,不存在对角线方向,也不存在G值更低的点)(此处存疑,未发现问题,也不知道对不对)。

源代码下载地址

0 0
原创粉丝点击