使用A*算法求最短路径

图论中最短路径的求解之A*算法实现

代码链接

利用A*算法找到从A城市到B城市的最短路径,以及代价,其中A *算法中的h也就是从当前点到目标点的距离已经给出。程序要有通用性,即其中城市A、B可以为下图中任意的两个城市
使用A*算法求最短路径_第1张图片

在做这个作业时我感觉数据给的不完整,说真的二维图论搜索基本是上按照两点之间的距离作为启发式函数,数据里只给了其他点到一个点直线距离,所以如果城市增多,那么我的这个启发式函数就可能不适用

A*算法简介

假设此时起始点是A,中间点是B,目的地点是C

有三个参数

  • h是启发式函数,在本题里面表示无视所有障碍,B到C的距离,一般是直线距离
  • g表示cost,也就是A到B走的距离,这个不能无视障碍
  • f总的路径长,对于B来说他的f就是 g + h g+h g+h

有两个容器

  • openList,经过中心点向四周辐射,将可到达的点放入到openList中,并且按照f,h的大小顺序进行排序,下一次选择中心点就选择f最小的,如果f一样小,就选择h最小的,因为h小的话代价就会小
  • closeList,上面我们每一次都选择f、h最小的f小优先作为新的中心点,那么这个点就可以从openList中删除了,然后加入到closeList中,这个容器类似于visit[]数组,就是用来做标记的。但是他的功能不仅于此,还可以通过closeList来回溯出从起始点到终点的路径

启发式函数设计

由于没有给出来所有点之间的直线距离,所以就将两城市到Bucharest的直线的距离的差的绝对值作为启发式函数

//采用起始点和终点到B城市的直线距离的差的绝对值用来做H
int getH(int start, int end) {
    return abs(strai_dist_B[start] - strai_dist_B[end]);
}

具体实现

数据结构:

  • 定义一个结构体Node表示每一个节点,id表示着城市的序号,father_id表示他之前点的序号
struct Node{
    int f;
    int g;
    int h;
    int id; //城市的序号
    int father_id;
    Node() {
        f = 0;
        g = 0;
        h = 0;
        id = -1;
        father_id = -1;
    }
    Node(int g, int h, int id, int father_id){
        this->h = h;
        this->g = g;
        this->id = id;
        this->f = g+h;
        this->father_id = father_id;
    }
};

一共有三个大步骤

首先我们要将起始点加入到openList中,这个不算三步里面。

  1. 对openList进行排序,排序的规则是最小原则,f优先于h。找出来最小的节点,并且将其设定为中心点,然后将改点从openLIst中删除,并且加入到clsoeList中。

    //这个是排序函数,肯定是先排f较小的
    //如果出现f相等了,那么就看他们的h,如果h越小,那么说明离的越近
    bool cmp(const Node& node1, const Node &node2) {
        if(node1.f < node2.f) return true;
        else if(node1.f > node2.f) return false;
        else {
            if(node1.h < node2.h) return true;
        }
        return false;
    }
    
    
    
  2. 从中心点开始遍历周围可以到达的点。在这一题里面就是找到临近的城市

    1. 临近城市、不在closeList中

    2. 如果不在openList中,就加入到openList,并且将father_id设置为中心节点的序号

    3. 如果在openList中,需要判断B点(假设这个点是B,中心点是A)是否需要进行更新。更新的原则就是:

      if(dist[A.id][B.id] + A.g < B.g):
      	B.g = dist[A.id][B.id] + A.g
        B.father.id = A.id
      

      此时整个openList需要进行从新排序

  1. 如果终点在了openList中,那么这个算法就可以停止了,如果最后openLIst空了,那么就搜索失败了

上述三步代码如下

使用A*算法求最短路径_第2张图片

运行截图

使用A*算法求最短路径_第3张图片

后记

这个是我的人工智能课的题目,之前一直在网上搜查资料,在求最短路径中,他们对于A * 算法的实现基本不对,主要还是没有更新openList,写下这篇博客最主要的原因还是,我的某个傻屌同学一直不承认他写的不是A * 算法,我理论不过,遂写下这篇博客。当然了如果存在问题,可以评论我

你可能感兴趣的:(A*算法,最短路径)