基于A的矢量寻路算法
合集下载
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
Point GetPoint(Set s1, Set s2) //从集合 s1 中取出 f(n)值最小的结点,删除,并放入集合 s2
void Sort(Set s)
//把集合 s 中的元素按照 f(n)值排序
下面是矢量寻路的算法描述:
bool FindPath(Point start, Point end, VectorGraph graph)//参数为起点、终点和二维矢量图
传统的 A*算法中一个结点有 8 邻结点,而二维矢量图中一个顶点的邻结点数量是不固 定的。只要两个结点构成的线段没有穿过任何障碍,则它们互为邻结点。这样,二维矢量图 的寻路问题就转化为——从所有多边形的顶点中选择一些顶点连接起来,构成一条最短路 径。这个问题本质上就是 A*算法解决的问题。
3.1 矢量寻路算法描述
http://www.paper.edu.cn
基于 A*的矢量寻路算法
谌显,杨克俭
武汉理工大学计算机科学与技术系,武汉 (430063)
E-mail:iron1982@yeah.net
摘 要:最短路径搜索是路径分析中的热点问题,也是物流运输系统中的关键技术之一。 A*算法是一种经典的最短路径搜索算法。本文在分析和研究了 A*算法的基础上,提出了一 种矢量寻路算法。该方法是在二维矢量图中搜索最短路径。此外,本文对矢量寻路算法的改 进做了进一步探讨。 关键词:A*算法;矢量寻路;Dijkstra 算法;最佳优先搜索 中图分类号:TP391
图 4 矢量寻路算法结果
从上面对矢量寻路算法的描述中可以发现,选定一个 f 值最小的结点作为当前结点之 后,需要寻找当前结点的邻结点,即遍历二维矢量图中所有的结点,检查当前结点与邻结点
-4-
http://www.paper.edu.cn
构成的线段是否与障碍物相交。显然,当二维矢量图中的结点数量非常庞大时,算法是非常 低效的。现在假设选定当前结点之后,在考察邻结点时,只考虑离距离当前结点最近的障碍 物(即从当前结点发射一条射线到目标结点,射线最先碰到的障碍物)的结点,而不必考虑 其他障碍物的结点。这样就大大减少了搜索邻结点的计算量。但是这种假设算法可能找不到 一条路径,或者找到的路径不是最短路径。该假设的正确性和有效性需要进一步的论证。
2. A*算法简述
2.1 Dijkstra 算法与最佳优先搜索
Dijkstra 算法[1][2]从物体所在的初始点开始,访问图中的结点。它迭代检查待检查结点集 内的结点,并把和该结点最靠近的尚未检查的结点加入待检查结点集。该结点集从初始结点 向外扩展,直到到达目标结点。Dijkstra 算法保证能找到一条从初始点到目标点的最短路径, 只要所有的边都有一个非负的代价值。
为了描述矢量寻路算法,先约定几个数据结构和函数(用 C++描述)。
Байду номын сангаас
DataType Point
//结点,包含父结点指针、f(n)、g(n)等信息
DataType LineSegment
//由 2 个结点构成一条线段
DataType Set
//用来存储结点的集合
DataType VectorGraph
4. 总结
本文简要的描述了 A*算法,并在 A*算法基础上提出了一种矢量寻路算法,将 A*算法 的应用范围从二维网格拓展到了二维矢量图,更加贴近实际应用。此外,本文分析了这种矢 量寻路算法的性能瓶颈,并提出了一种假设,有待进一步的论证。
本文描述的矢量寻路算法能够应用到交通、导航系统、城市规划、计算机游戏等领域。
if(LineCrossLine(LineSegment(ptCurrent, pt), lineseg)) { bCross = true; break; } } //如果结点 ptCurrent 和 pt 构成的线段和矢量图 graph 中所有的线段都没有相交, 则结点 ptCurrent 和 pt 是邻结点
A*算法正好结合了 Dijkstra 算法和最佳优先搜索(BFS)算法的优点,成为二维网格中 求解最短路最有效的方法。接下来描述 A*算法。
2.2 A*算法
A*算法在人工智能中是一种典型的启发式搜索算法。如果将问题求解过程表现为从初 始状态到目标状态寻找最优路径的过程,启发式搜索就是在状态空间中的搜索对每一个搜索 的位置进行评估,得到最好的位置,再从这个位置进行搜索直到目标。这样可以省略大量无 谓的搜索路径,提高了效率。
一格的 f(n), g(n)和 h(n)值。 1. 如果它已经在 Open 集合中,用 g(n)值为参考检查新的路径是否更好。更低的 g(n)
值意味着更好的路径。如果是这样,就把这一格的父结点改成当前格,并且重新计 算这一格的 g(n)和 f(n)值。如果你保持你的 Open 集合按 f(n)值排序,改变之后需要 重新对 Open 集合排序。 D. 当目标格添加进了 Open 集合,这时候路径被找到,或者没有找到目标格,Open 集合 已经空了,表示路径不存在。这时程序停止。 (3)保存路径。从目标格开始,沿着每一格的父节点移动直到回到起始格。这就是找到的 路径。 采用 A*算法对图 1 所示的求最短路径问题求解,得到图 2 所示的结果(红色圆点构成 的序列为找到的路径)。从上面的描述可以发现,A*算法成功的秘决在于,它把 Dijkstra 算法(靠近初始点的结点)和 BFS 算法(靠近目标点的结点)的信息块结合起来。但是 A* 算法只适合二维网格中的寻路,本文提出了矢量寻路算法,能够在二维矢量图中寻找最短路 径。
{
Set Open, Close, Temp; //定义集合,其中 Temp 是临时集合
Open.add(start);
//将起点放入 Open 集合
While(Open != NULL) { //Open 集合不为空
Temp = {}; //清空 Temp 集合
//从集合 Open 中取出 f(n)值最小的结点(当前结点),并把该结点从 Open 集合中删
transitive closure and all-pairs shortest paths[J]. Journal of Algorithms, 2007, 62(2): 74~92.
Vector Path Searching Algorithm Based on A*
//二维矢量图,其中存放多边形
float Distance(Point pt1, Point pt2) //两个结点的距离
bool LineCrossLine(LineSegment lineseg1, LineSegMent lineseg2) //判断线段 lineseg1
和 lineseg2 是否有交点
A. 寻找 Open 集合中 f(n)值最低的结点,称它为当前结点。 B. 把它从 Open 集合中删除,放入 Close 集合。 C. 对于相邻的 8 格中的每一个结点:
a) 如果它不可通过或者已经在 Close 集合中,略过它。否则如下: b) 如果它不在 Open 集合中,把它添加进去。把当前格作为这一格的父节点。记录这
参考文献
[1] 王开义,赵春江,胥桂仙等.GIS 领域最短路径搜索问题的一种高效实现[J].中国图象图形学报,2003, 8(8):951~956.
[2] 张林广,方金云,申排伟.基于配对堆改进的 Dijkstra 算法[J].2007,12(5):922~926. [3] Surender Baswana, Ramesh Hariharan, Sandeep Sen. Improved decremental algorithms for maintaining
-3-
http://www.paper.edu.cn
if(!bCross) { if(pt 在 Close 集合中) continue; else{ if(pt 不在 Open 集合中){ pt.parent = ptCurrent; if(pt == end) { //已经找到目标结点 end 从 end 追溯其祖先,输出找到的路径 return true; } pt.g(n) = ptCurrent.g(n) + Distance(ptCurrent, pt); pt.f(n) = pt.g(n) + Distance(pt, end); Temp.add(pt); //将 pt 加入到 Temp 集合中,以后再加入到 Open 集合中 } else{ //pt 已经在 Open 集合中 if(pt.g(n) > ptCurrent.g(n) + Distance(pt, ptCurrent)){ pt.parent = ptCurrent; pt.g(n) = ptCurrent.g(n) + Distance(pt, ptCurrent); pt.f(n) = pt.g(n) + Distance(pt, end); } } }
最佳优先搜索(BFS)算法[3]按照类似的流程运行,不同的是它能够评估(称为启发式 的)任意结点到目标点的代价。与选择离初始结点最近的结点不同的是,它选择离目标最近 的结点。BFS 是基于贪心策略的,它试图向目标移动(即使不是正确的路径)。由于它仅仅 考虑到达目标的代价,而忽略了当前已花费的代价,于是尽管路径变得很长,它仍然继续走 下去。因此,BFS 不能保证找到一条最短路径。然而,它比 Dijkstra 算法快的多,因为它用 了一个启发式函数(heuristic function)快速地导向目标结点。例如,如果目标位于出发点的 南方,BFS 将趋向于导向南方的路径。
3. 基于 A*的矢量寻路算法
如图 3 所示,灰色的的区域(多边形)表示障碍物(不可通过的区域)。在图 3 描述的 矢量图中寻找最短路径。可以发现,如果起点和终点之间没有障碍物,则最短路径是一条线 段。路径中的转折点均为多边形的顶点。
-2-
http://www.paper.edu.cn
图 3 二维矢量图中的寻路
1. 引言
A*算法是一种典型的启发式搜索算法,是静态二维网格中求解最短路最有效的方法。 A*算法被广泛应用于游戏、计算机仿真、交通等领域。本文先简述各种经典的寻路算法, 然后着重描述 A*寻路算法,并在 A*算法的基础上提出了二维平面上的矢量寻路算法,将 A*算法的应用范围从二维网格拓展到二维的矢量图。
} } 将 Temp 集合中的结点加入到 Open 集合中; Sort(Open); //对 Open 集合按 f(n)值排序 }//end for while return false; //没有找到路径 }
3.2 实验结果分析及改进
图 4 显示了在不同的障碍物条件下得到的路径。图中找到的路径是最短路径。算法的效 率受 2 个因素影响:障碍物结点的数量 n 和结点的分布情况。随着 n 值的增大,算法执行的 效率会急剧下降。此外,在 n 值一定的条件下,不同的结点分布情况的寻路效率也会不同。
-1-
http://www.paper.edu.cn
图 1 A*算法中的网格
图 2 A*算法找到的路径
A*算法的估价函数为:f(n) = g(n) + h(n)。g(n)表示从初始结点到任意结点 n 的代价,h(n)表 示从结点 n 到目标点的启发式评估代价(heuristic estimated cost)。如图 1 所示,绿色的是 起点 A,红色是终点 B,蓝色方块是中间的墙。假设沿水平、垂直方向移动一格的距离为 10,沿对角线移动一格的距离为 14。考察起点 A 右边的点 n,从起点 A 移动到点 n 的距离 为 10,即 g(n)为 10。从点 n 到终点 B 的距离为 40,即 h(n)为 40。则点 n 的 f(n)为 50。A* 算法的工作流程如下: (1)把起始格添加到 Open 集合。 (2)重复如下的工作:
除,放入 Close 集合
Point ptCurrent = GetPoint(Open, Close);
for each pt in graph(包括终点 end) {
//Point pt
bool bCross = false; for each lineseg in graph{ //LineSegment lineseg