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

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

        我是从某个前辈的博客学习的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值更低的点)(此处存疑,未发现问题,也不知道对不对)。

源代码下载地址

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值