zoukankan      html  css  js  c++  java
  • 启发式搜索A-Star算法 【寻找 最短路径 算法】【地理几何位置 可利用的情况】

    在处理最短路径问题时,有一种启发式算法是我们应该了解的,由于其有着优秀的探索效率在各自现实项目中多有应用,它就是 A-star 算法,或  A*  算法。

     个人观点:

    A*  算法并不保证找到的路径一定是最短路径,但该方法由于运算效率高所以使用较广。如果出发点和终点之间存在可到达路径,则使用A*算法必然会得到一条可达路径,但是不一定是最短路径,可以这么说  启发式算法 A* 在存在可达路径的问题中会以较高效率必然找到一条 较短路径。

    由于 下文中提到的  h(n)  是用来评价节点n 到终点距离的一个估计,而这个估计往往在二维空间中是有效可行的,也就是常见的游戏中的地图中给定两点寻找最短路径的问题。   而在很多其他问题中我们无法有效评估节点n与终点的距离(估计值无法获得),因而不能使用,也就是说A*算法适用于 地理位置信息可利用的 情况下(利用地理几何位置)。

     启发式算法:个人观点就是在基本的数据结构的算法基础上加入一定的规则所构成的新算法,即策略算法

     这里之所以说A*只有在可利用地理几何位置信息时才可以用呢,是因为这里所采用的启发规则,即策略,采用的就是两点间的几何位置距离。

    个人感觉A*最大的优点是效率高,实时性强,能够快速的得出近似最优路径。

    没有弄懂的地方?   

    网上的博客说的都是使用A*算法可以得到最短路径,而我却总感觉这个说法站不住,总感觉它是在寻找近似 最短路径, 但是又没有什么法子可以证明,因此在这里这个问题成了一个悬念了。

     

    图来自:   http://ju.outofmemory.cn/entry/273479

    在上图中使用  A* 算法  搜寻效率并没有提高太多, 因为在搜索路径过程中有较大一部分的搜索处在远离终点的过程中,根据启发规则中的规定我们对远离终点的路径赋予的距离值较大,所以会导致偏离终点较远距离后重新返回起始点附件重新探索一条新的路径。

    ==================================================

    以下内容转自:

    http://www.cnblogs.com/gansaishi2008/articles/1254603.html

    初识A*算法

    写这篇文章的初衷是应一个网友的要求,当然我也发现现在有关人工智能的中文站点实在太少,我在这里抛砖引玉,希望大家都来热心的参与。还是说正题,我 先拿A*算法开刀,是因为A*在游戏中有它很典型的用法,是人工智能在游戏中的代表。A*算法在人工智能中是一种典型的启发式搜索算法,为了说清楚A*算 法,我看还是先说说何谓启发式算法。

    1、何谓启发式搜索算法
    在说它之前先提提状态空间搜索。状态空间搜索,如果按专业点的说法就是将问题求解过程表现为从初始状态到目标状态寻找这个路径的过程。通俗点说,就是 在解一个问题时,找到一条解题的过程可以从求解的开始到问题的结果(好象并不通俗哦)。由于求解问题的过程中分枝有很多,主要是求解过程中求解条件的不确 定性,不完备性造成的,使得求解的路径很多这就构成了一个图,我们说这个图就是状态空间。问题的求解实际上就是在这个图中找到一条路径可以从开始到结果。 这个寻找的过程就是状态空间搜索。
    常用的状态空间搜索有深度优先和广度优先。广度优先是从初始状态一层一层向下找,直到找到目标为止。深度优先是按照一定的顺序前查找完一个分支,再查找另一个分支,以至找到目标为止。这两种算法在数据结构书中都有描述,可以参看这些书得到更详细的解释。
    前面说的广度和深度优先搜索有一个很大的缺陷就是他们都是在一个给定的状态空间中穷举。这在状态空间不大的情况下是很合适的算法,可是当状态空间十分大,且不预测的情况下就不可取了。他的效率实在太低,甚至不可完成。在这里就要用到启发式搜索了。
    启发式搜索就是在状态空间中的搜索对每一个搜索的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无畏的搜索路径,提 到了效率。在启发式搜索中对位置的估价是十分重要的采用了不同的估价可以有不同的效果。我们先看看估价是如何表示的。
    启发中的估价是用估价函数表示的,如:

    f(n) = g(n) + h(n)

    其中f(n) 是节点n的估价函数,g(n)实在状态空间中从初始节点到n节点实际代价h(n)是从n到目标节点最佳路径的估计代价。在这里主要是h(n)体现了搜 索的启发信息,因为g(n)是已知的。如果说详细点,g(n)代表了搜索的广度的优先趋势但是当h(n) >> g(n)时,可以省略g(n),而提高效率。这些就深了,不懂也不影响啦!我们继续看看何谓A*算法。

    2、初识A*算法
    启发式搜索其实有很多的算法,比如:局部择优搜索法、最好优先搜索法等等。当然A*也是。这些算法都使用了启发函数,但在具体的选取最佳搜索节点时的 策略不同。象局部择优搜索法,就是在搜索的过程中选取“最佳节点”后舍弃其他的兄弟节点,父亲节点,而一直得搜索下去。这种搜索的结果很明显,由于舍弃了 其他的节点,可能也把最好的节点都舍弃了,因为求解的最佳节点只是在该阶段的最佳并不一定是全局的最佳。最好优先就聪明多了,他在搜索时,便没有舍弃节点 (除非该节点是死节点),在每一步的估价中都把当前的节点和以前的节点的估价值比较得到一个“最佳的节点”。这样可以有效的防止“最佳节点”的丢失。那么 A*算法又是一种什么样的算法呢?其实A*算法也是一种最好优先的算法只不过要加上一些约束条件罢了由于在一些问题求解时,我们希望能够求解出状态空 间搜索的最短路径,也就是用最快的方法求解问题,A*就是干这种事情的!我们先下个定义,如果一个估价函数可以找出最短的路径,我们称之为可采纳性。A* 算法是一个可采纳的最好优先算法。A*算法的估价函数可表示为:

    f'(n) = g'(n) + h'(n)

    这里,f'(n)是估价函数,g'(n)是起点到节点n的最短路径值,h'(n)是n到目标的最短路经值。由于这个f'(n)其实是无法预先知道 的,所以我们用前面的估价函数f(n)做近似。g(n)代替g'(n),但 g(n)>=g'(n)才可(大多数情况下都是满足的,可以不用考虑),h(n)代替h'(n),但h(n)<=h'(n)才可(这一点特别 的重要)。可以证明应用这样的估价函数是可以找到最短路径的,(近似最短路径),也就是可采纳的。我们说应用这种估价函数的最好优先算法就是A*算法。哈。你懂了吗?肯定没 懂。接着看。
    举一个例子,其实广度优先算法就是A*算法的特例。其中g(n)是节点所在的层数,h(n)=0,这种h(n)肯定小于h'(n),所以由前述可知广度优先算法是一种可采纳的。实际也是。当然它是一种最臭的A*算法。

     ==================================================

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

    起源

    名字创意来源于第一届百度之星比赛决赛中有题目是一道经典的8数码题目,解这道题,冠军ACRush使用了A*算法(Astar)。Astar又包含了“百度之星”的含义。
     
     
     
     
     

    算法的描述

    f(n) = g(n) + h(n)
    其中
    f(n) 是从初始点经由节点n到目标点的移动耗费。
            g(n) 是在状态空间中从起点到n节点的实际耗费。
            h(n) 从网格上那个方格移动到终点的预估移动耗费。这经常被称为启发式的,这样叫的原因是因为它只是个猜测。我们没办法事先知道路径的长度,因为路上可能存在各种障碍(墙,水,等等)。

    该算法的伪代码描述如下:

    创建两个表,OPEN表保存所有已生成而未考察的节点,CLOSED表中记录已访问过的节点; 
    算起点的估价值;
    将起点放入OPEN表;
    while(OPEN!=NULL) 
    { 
        从OPEN表中取估价值f最小的节点n; 
        if(n节点==目标节点)
        { 
            break; 
        }
         
        for(当前节点n 的每个子节点X) 
        {
            算X的估价值; 
            if(X in OPEN)
            { 
                if( X的估价值小于OPEN表的估价值 )
                { 
                    把n设置为X的父亲; 
                    更新OPEN表中的估价值; /*取最小路径的估价值*/
                }
            }
        
            if(X in CLOSE)
            {
                continue;
            }
        
            if(X not in both)
            {
                把n设置为X的父亲;
                求X的估价值; 
                并将X插入OPEN表中; 
            }
        }/* end for */
     
    将n节点插入CLOSE表中; 

    按照估价值将OPEN表中的节点排序;
    /*实际上是比较OPEN表内节点f的大小,从最小路径的节点向下进行。*/
    }/* end while(OPEN!=NULL) */


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

    估算函数的选择

    在静态网格中,距离的计算一般有如下几种:欧氏距离,曼哈顿距离,切比雪夫距离等。
    以下是 “欧氏距离”,“曼哈顿距离”,“切比雪夫距离”的几何定义: (也可参考:[转载]机器学习中的相似性度量 (多种几何距离定义)),距离估算函数的选择需要按实际情况而定。

    欧氏距离:

    欧氏距离是最易于理解的一种距离计算方法,源自欧氏空间中两点间的距离公式。
    (1)  二维平面上两点a(x1,y1)与b(x2,y2)间的欧氏距离:
     
     
    (2) 三维空间两点a(x1,y1,z1)与b(x2,y2,z2)间的欧氏距离:

     

    (3) 两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的欧氏距离:

     

    也可以用表示成向量运算的形式:

     

     
     

    曼哈顿距离
    从名字就可以猜出这种距离的计算方法了。想象你在曼哈顿要从一个十字路口开车到另外一个十字路口,驾驶距离是两点间的直线距离吗?显然不是,除非你能穿越大楼。实际驾驶距离就是这个“曼哈顿距离”。而这也是曼哈顿距离名称的来源, 曼哈顿距离也称为城市街区距离(City Block distance)。
                   

    (1) 二维平面两点a(x1,y1)与b(x2,y2)间的曼哈顿距离

    (2) 两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的曼哈顿距离

     

     
     

    切比雪夫距离
    国际象棋玩过么?国王走一步能够移动到相邻的8个方格中的任意一个。那么国王从格子(x1,y1)走到格子(x2,y2)最少需要多少步?自己走走试试。你会发现最少步数总是max( | x2-x1 | , | y2-y1 | ) 步。有一种类似的一种距离度量方法叫切比雪夫距离。

                   
    (1) 二维平面两点a(x1,y1)与b(x2,y2)间的切比雪夫距离

     

    (2) 两个n维向量a(x11,x12,…,x1n)与 b(x21,x22,…,x2n)间的切比雪夫距离

     

    这个公式的另一种等价形式是

     

     
    以上内容取自博客:
    作者:xlhdsj 
    来源:CSDN 
     
     注:   算法描述中的估价值指的是   f(x)  。
     
     
    =======================================================
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
  • 相关阅读:
    [05] EL表达式
    [03-01] JSP自定义标签
    [04] JSP标准动作
    [03] JSP指令
    Fiddler抓包调试前端脚本代码
    《互联网协议入门》思维导图笔记
    Nodejs学习笔记(十)—与MongoDB的交互(mongodb/node-mongodb-native)、MongoDB入门
    Nodejs学习笔记(九)—与Redis的交互(mranney/node_redis)入门
    Nodejs学习笔记(八)—Node.js + Express 实现上传文件功能(felixge/node-formidable)
    Nodejs学习笔记(七)—Node.js + Express 构建网站简单示例
  • 原文地址:https://www.cnblogs.com/devilmaycry812839668/p/10515462.html
Copyright © 2011-2022 走看看