还没仔细看,比学的要深,特意留存学习

A*算法是到目前为止最快的一种计算最短路径的算法,但它一种‘较优’算法,即它一般只能找到较优解,而非最优解,但由于其高效性,使其在实时系统、人工智能等方面应用极其广泛。

A*算法结合了启发式方法(这种方法通过充分利用图给出的信息来动态地作出决定而使搜索次数大大降低)和形式化方法(这种方法不利用图给出的信息,而仅通过数学的形式分析,如Dijkstra算法)。它通过一个估价函数(Heuristic Function)f(h)来估计图中的当前点p到终点的距离(带权值),并由此决定它的搜索方向,当这条路径失败时,它会尝试其它路径。

因而我们可以发现,A*算法成功与否的关键在于估价函数的正确选择,从理论上说,一个完全正确的估价函数是可以非常迅速地得到问题的正确解答,但一般完全正确的估价函数是得不到的,因而A*算法不能保证它每次都得到正确解答。一个不理想的估价函数可能会使它工作得很慢,甚至会给出错误的解答。

为了提高解答的正确性,我们可以适当地降低估价函数的值,从而使之进行更多的搜索,但这是以降低它的速度为代价的,因而我们可以根据实际对解答的速度和正确性的要求而设计出不同的方案,使之更具弹性。

众所周知,对图的表示可以采用数组或链表,而且这些表示法也各也优缺点,数组可以方便地实现对其中某个元素的存取,但插入和删除操作却很困难,而链表则利于插入和删除,但对某个特定元素的定位却需借助于搜索。而A*算法则需要快速插入和删除所求得的最优值以及可以对当前结点以下结点的操作,因而数组或链表都显得太通用了,用来实现A*算法会使速度有所降低。要实现这些,可以通过二分树、跳转表等数据结构来实现,我采用的是简单而高效的带优先权的堆栈,经实验表明,一个1000个结点的图,插入而且移动一个排序的链表平均需500次比较和2次移动;未排序的链表平均需1000次比较和2次移动;而堆仅需10次比较和10次移动。需要指出的是,当结点数n大于10,000时,堆将不再是正确的选择,但这足已满足我们一般的要求。

还有一种更好的方法是Hot Queues,而且这种方法还可应用于Dijkstra算法以降低其复杂度。当我们移动估价函数值为f的结点时,我们插入值为f+δ(δ<=C)(若δ>=0将意味着估价函数是有效的,反之亦然),常量C为从一个结点到相邻结点的权的最大改变。同时我们用一些“容器”来保存估价函数值的子集(这正如o(n)的排序算法的思想),例如,当有10个“容器”时,堆将平均只包含1/10的估价值。因而这将比用堆更为有效。

     估价函数(Heuristic Function)

估价函数的正确选取将直接关系到A*算法的成功与否,而函数的确定却与实际情形有着密切的关系。在本文中,仅对网格状地图的估价函数作部分讨论,而在其它情形中,需要作不同的分析,但至少估价函数应为连续函数。

a.      Manhattan Distance

这是一种标准的估价函数,

h(A) = 10 * (abs(A.x-goal.x) + abs(A.y-goal.y))

b.      Diagonal Distance

如果在地图上允许作斜线方向的运动,则Mahattan Distance修正为Diagonal Distance

h(A) = max(abs(A.x-goal.x), abs(A.y-goal.y))

     估价函数的判优

一般情形下,我们只需对估价函数的值进行比较而取其大者即可,但在几个结点的估价函数值相同的情形下,我们需要采取一定的策略来决定这几者谁更优,从而避免对多个点的搜索。从而如下代码可实现之:

double dx1 = currentX - goalX;

double dy1 = currentY - goalY;

double dx2 = startX - goalX;

double dy2 = startY - goalY;

cross = dx1*dy2 - dx2*dy1;

if( cross<0 ) cross = -cross;

... add cross*0.001 to the heuristic ...

这段代码计算始点、当前点和终点的矢量积,从而可以判断这三点是否共线(或近似共线),这样不同点间即使有微小的差别也会被放大,从而更利于判断。

     改进的A*算法

a.      Beam Search

在A*算法中需要保留所有的结点,这将使得时间和空间的消耗都很大,而Beam Search方法对结点数作出限期,当结点数过多时,它会将一些不(大)可能为最优的点排除,从而降低时间和空间的要求,但需要说明的是,由于在排除结点后需对结点排序,当排序的工作量大于排除点后所节省的工作量,则该方法无意义。

b.      Iterative deepening

这是一种在人工智能中常使用的方法,它首先产生一近似值,然后对它进行修正而逐步接近最优解。这其实在一种博奕算法的变形。

c.      Dynamic weighting

这种算法是基于这样的考虑,即在搜索初期以速度优先,在搜索后期以准确度优先(这可通过对搜索初、后期赋予不同的权值来实现)。即:

f(p) = g(p) + w(p) * h(p)

d.      Bidirectional search

这种算法从起点和终点同时应用A*算法,直到有结点相遇。其缺点在于复杂度太大,一般仅用于复杂的图形。

e.      Hierarchical A*

这种算法思想是将搜索过程化,对每个简单过程求解从而得全局较优解。正如当我们到另一城市时,可分解为从家里“搜索”一条路径至车站,再从车站“搜索”一条路径到另一城市,当我们从家里出发时,需要考虑的是怎样尽快地到达车站,而不是怎样尽快地到另一城市。

f.      Dynamic A*(D*)

这种算法主要用于人工智能和机器人技术。由于A*算法一开始要求获得全部信息,而这在实际中有时是不可能的,而D*算法就是在假定信息不完整的前提下应用A*算法,但它会随着得到信息的增多而不断改进结果,这就决定了它对空间的要求相当高,因为它需要保留以前的所有获得信息及运算情形。

计算最短路径的A* 算法简介相关推荐

  1. DL:神经网络算法简介之耗算力的简介、原因、经典模型耗算力计算、GPU使用之详细攻略

    DL:神经网络算法简介之耗算力的简介.原因.经典模型耗算力计算.GPU使用之详细攻略 目录 神经网络算法耗算力的简介 神经网络算法耗算力的原因 神经网络算法耗算力的经典模型耗算力计算 1.AlexNe ...

  2. 量子计算(二十):量子算法简介

    文章目录 量子算法简介 一.概述 二.量子经典混合算法 量子算法简介 一.概述 量子算法是在现实的量子计算模型上运行的算法,最常用的模型是计算的量子电路模型.经典(或非量子)算法是一种有限的指令序列, ...

  3. 计算完全最短路径的Floyd算法

    [计算完全最短路径的Floyd算法] (一).定义** Floyd–Warshall(简称Floyd算法)是一种著名的解决任意两点间的最短路径(All Paris Shortest Paths,APS ...

  4. python 计算最短路径算法

    在 Python 中,有许多算法可以用来计算最短路径.其中包括 Dijkstra 算法.A* 算法.Bellman-Ford 算法和 Floyd-Warshall 算法. Dijkstra 算法是一种 ...

  5. 数据结构与算法:算法简介

    数据结构与算法:算法简介 雪柯 大工生物信息 提笔为写给奋进之人 已关注 你说呢 . shenwei356 等 70 人赞同了该文章 引用自算法图解,作者[美] Aditya Bhargava 译袁国 ...

  6. JAVA编程求单源最短路径_【算法】单源最短路径——dijkstra算法

    一,概念 单源最短路径 给定一个带权有向图G=(V,E),其中每条边的权是一个实数.另外,还给定V中的一个顶点,称为源.要计算从源到其他所有各顶点的最短路径长度.这里的长度就是指路上各边权之和.这个问 ...

  7. Dijkstra(迪杰斯特拉)算法简介

    目录 适用情形 思想 核心代码 设计实现更多功能 举例说明 适用情形 适用于权值为非负的图的单源最短路径 思想 在已知起点与终点的情况下.须有三个一维数组S,U,dis,S用于记录已经查找过的点,U则 ...

  8. hash算法_一致性hash算法简介

    一致性hash算法有什么用?我们为什么需要一致性hash算法?这两个问题的答案可以看这篇文章 分布式系统路由算法简介. 了解了一致性hash算法出现的背景,我们来看看什么是一致性hash算法.一致性h ...

  9. 推荐系统算法_机器学习和推荐系统(二)推荐算法简介

    推荐算法简介 一. 基于人口统计学的推荐算法 二.基于内容的推荐算法 三. 基于协同过滤的推荐算法 协同过滤(Collaborative Filtering , CF) 基于近邻的系统过滤 基于用户( ...

最新文章

  1. Oracle再发力,区块链平台多项更新
  2. 了解Master Pages库
  3. hdu-2955(01背包)Robberies
  4. C++实现顺序查找(附完整源码)
  5. IdentityServer4 指定角色授权(Authorize(Roles=amp;quot;adminamp;quot;))
  6. 获取异常信息_如何在 ASP.NET Core 中实现全局异常拦截
  7. 两个Liunx服务器之间的文件夹迁移
  8. spark学习-scala版写的SparkSQL程序读取Hbase表注册成表SQL查询
  9. mysql 8.0 ~ 安装
  10. 通过 Hibernate 调用存储过程
  11. 易科软件中国:维系客户关系是企业的根本
  12. python怎样定义font_无法在matplotlib中使用自定义字体
  13. c语言由天数求日期,C语言-由日期求天数由天数求日期
  14. 计算机开机键盘屏幕无反应,戴尔电脑开机键亮但为什么屏幕没有反应
  15. android 平板root,安卓平板电脑怎么root 安卓平板一键root方法
  16. 区域和检索 - 数组不可变(前缀和)
  17. Linux查看MegaSAS raid卡缓存策略
  18. ubuntu中/usr目录下无法直接复制粘贴文件或目录
  19. 什么是FEC/NACK/RTX
  20. mac电脑解压缩报错:错误22 无效的参数

热门文章

  1. jQuery Form 表单提交插件-----ajaxSubmit() 的应用
  2. 今天终于可以正常下班了
  3. vector数组的使用——机器翻译(洛谷 P1540)
  4. 触摸屏开发_Microchip推出新型电容触摸式控制器,加速汽车触摸屏EMI认证
  5. 高级考题_理论干货最最直观的词云分布,带你一次看清天大考题端倪!
  6. integer 最大值_JAVA源码之Integer
  7. 2021,国产数据库的躬行实践之年
  8. SimpleDateFormat类的线程安全问题和解决方案
  9. 专家解惑 | 关于华为云盘古大模型,你想问的都在这里~
  10. 想了解表格问答,我们先看看TA的前世