上篇博客中介绍了一些基本的图搜索算法,其中也重点介绍了基于势场来实现的Dijkstra算法。本篇博客将介绍关于Heuristic Function的图搜索算法
开源了一个结合Dijkstra,Greedy,以及Astar算法的代码,更新在了博主的github主页上,链接见文末
1. Greedy Best First Search Algorithm(贪心算法)
如上篇博客所介绍,BFS与Dijstra算法在搜索目标时是向所有方向进行节点拓展的。如果任务中是需要向多个目标点进行搜索,那么此类方法显然是合适的。但是如果仅仅只是需要向一个目标点进行搜索,那么这样的搜索会增加很多不必要的耗时。
那么此时我们可以尝试,将Dijkstra中的计算距离起点的cost修改为距离终点的cost。将节点的扩展导向终点。这种方法就可以称为贪心算法。
在贪心算法中,首先我们需要定义一个heuristic function来表述当前点距离终点的远近,通常我们会采用曼哈顿距离或者欧拉距离来实现此需求
1.1 算法伪代码
frontier = PriorityQueue()
frontier.put(start, 0)
came_from = dict()
came_from[start] = None
while not frontier.empty():
current = frontier.get()
if current == goal:
break
for next in graph.neighbors(current):
if next not in came_from:
priority = heuristic(goal, next)
frontier.put(next, priority)
came_from[next] = current
1.2 效果对比
上图对比了Dijkstra与Greedy算法之间的效果区别,可以看出,
- 当地图中没有障碍物遮挡时,Greedy算法的搜索范围以及效率是高于Dijkstra的,因为它让搜索更加具有目的性
- 当地图中存在障碍物特别是凹形障碍物遮挡时,由于Greedy算法仅考虑与终点的距离,常常会造成"短视"的现象即距离障碍物特别近时才会改变方向重新搜索路径去往终点
2. Astar Algorithm(A* 算法)
上部分Greedy算法展示了引入终点因素后对于搜索算法的影响,其优点与缺点通过效果对比图可以清楚的看出。为了解决单纯考虑终点因素而导致的"短视"问题,我们引入了一个更加均衡的算法&