A*算法

**

原理

**

A*(A-Star)算法是一种静态路网中求解最短路最有效的方法。

A算法的公式表示为: f(n)=g(n)+h(n), 其中 f(n) 是从初始点经由节点n到目标点的估价函数,g(n) 是在状态空间中从初始节点到n节点的实际代价,h(n) 是从n到目标节点最佳路径的估计代价。

如果对A算法(全局择优)中的g(n)和h(n)分别提出如下限制:①g(n)是对最小代价g(n)的估计,且g(n)>0;②h(n)是最小代价h(n)的下界,即对任意结点n均有h(n)≤h(n)。**则称满足上述两条限制的A算法为A算法。

保证找到最短路径(最优解的)条件,关键在于估价函数h(n)的选取:

我们以d(n)表达状态n到目标状态的距离,那么h(n)的选取大致有如下三种情况:

  1. 如果h(n)< d(n)到目标状态的实际距离,这种情况下,搜索的点数多,搜索范围大,效率低。但能得到最优解。
  2. 如果h(n)=d(n),即距离估计h(n)等于最短距离,那么搜索将严格沿着最短路径进行, 此时的搜索效率是最高的。
  3. 如果 h(n)>d(n),搜索的点数少,搜索范围小,效率高,但不能保证得到最优解

算法分类

该算法在最短路径搜索算法中分类为:

  • 直接搜索算法:直接在实际地图上进行搜索,不经过任何预处理;
  • 启发式算法:通过启发函数引导算法的搜索方向;
  • 静态图搜索算法:被搜索的图的权值不随时间变化(后被证明同样可以适用于动态图的搜索)。

方法

估价值与实际值越接近,估价函数取得就越好。

例如对于几何路网来说,可以取两节点间欧几理德距离(直线距离)做为估价值,即f=g(n)+sqrt((dx-nx)(dx-nx)+(dy-ny)(dy-ny));这样估价函数f在g值一定的情况下,会或多或少的受估价值h的制约,节点距目标点近,h值小,f值相对就小,能保证最短路的搜索向终点的方向进行。明显优于Dijkstra算法的毫无方向的向四周搜索。

算法实现(路径搜索)

1. 创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点。
2. 算起点的h(s);
3. 将起点放入OPEN表;

while(OPEN!=NULL)
{
   
    从OPEN表中取f(n)最小的节点n;
    if(n节点==目标节点)
        break;
    for(当前节点n的每个子节点X)
    {
   
        计算f(X);
        if(XinOPEN)
            if(新的f(X)<OPEN中的f(X))
            {
   
                把n设置为X的父亲;
                更新OPEN表中的f(n);
            }
        if(XinCLOSE)
            continue;
        if(Xnotinboth)
        {
   
            把n设置为X的父亲;f(X);
            并将X插入OPEN表中;//还没有排序
        }
    }//endfor
    将n节点插入CLOSE表中;
    按照f(n)将OPEN表中的节点排序;//实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。
}//endwhile(OPEN!=NULL)

4.保存路径,即从终点开始,每个节点沿着父节点移动直至起点,这就是你的路径;

用C语言实现A*最短路径搜索算法

#include <stdio.h>
#include <math.h>
  
#define MaxLength 100    //用于优先队列(Open表)的数组
#define Height     15    //地图高度
#define Width      20    //地图宽度
  
#define Reachable   0    //可以到达的结点
#define Bar         1    //障碍物
#define Pass        2    //需要走的步数
#define Source      3    //起点
#define Destination 4    //终点
  
#define Sequential  0    //顺序遍历
#define NoSolution  2    //无解决方案
#define Infinity    0xfffffff
  
#define East       (1 << 0)
#define South_East (1 << 1)
#define South      (1 << 2)
#define South_West (1 << 3)
#define West       (1 << 4)
#define North_West (1 << 5)
#define North      (1 << 6)
#define North_East (1 << 7)
  
typedef struct
{
   
    signed char x, y;
} Point;
  
const Point dir[8] =
{
   
    {
   0, 1},   // East
    {
   1, 1},   // South_East
    {
   1, 0},   // South
    {
   1, -1},  // South_West
    {
   0, -1},  // West
    {
   -1, -1}, // North_West
    {
   -1, 0},  // North
    {
   -1, 1}   // North_East
};
  
unsigned char within(int x, int y)
{
   
    return (x >= 0 && y >= 0
        && x < Height && y < Width);
}
  
typedef struct
{
   
    int x, y;
    unsigned char reachable, sur, value;
} MapNode;
  
typedef struct Close
{
   
    MapNode *cur;
    char vis;
    struct Close *from;
    float F, G;
    int H;
} Close;
  
typedef struct //优先队列(Open表)
{
   
    int length;        //当前队列的长度
    Close* Array[MaxLength];    //评价结点的指针
} Open;
  
static MapNode graph[Height][Width];
static int srcX, srcY, dstX, dstY;    //起始点、终点
static Close close[Height][Width];
  
// 优先队列基本操作
void initOpen(Open *q)    //优先队列初始化
{
   
    q->length = 0;        // 队内元素数初始为0
}
  
void push(Open *q, Close cls[Height][Width], int x, int y, float g)
{
       //向优先队列(Open表)中添加元素
    Close *t;
    int i, mintag;
    cls[x][y].G = g;    //所添加节点的坐标
    cls[x][y].F = cls[x][y].G + cls[x][y].H;
    q->Array[q->length++] = &(cls[x][y]);
    mintag = q->length - 1;
    for (i = 0; i < q->length - 1; i++)
    {
   
        if (q->Array[i]->F < q->Array[mintag]->F)
        {
   
            mintag = i;
        }
    }
    t = q->Array[q->length - 1];
    q->Array[q->length - 1] = q->Array[mintag];
    q->Array[mintag] = t;    //将评价函数值最小节点置于队头
}
  
Close* shift(Open *q)
{
   
    return q->Array[--q->length];
}
  
// 地图初始化操作
void in
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值