您的位置:首页 > 其它

A*算法

2015-11-15 21:33 232 查看
http://www.redblobgames.com/pathfinding/a-star/introduction.html

Breadth First search

frontier

1. pick and reomove a location from the frontier

2. mark the location as visited so that we know not to process it again

3. Expand it by looking at its neighbors,any neighbors we haven’t seen yet we add to the frontier

frontier = queue()
frontier.put(start)
visited = {}
visited[start] = true
while nor frontier.empty():
current = frontier.get()
for next in graph.neighbors(current):
if next not in visited:
frontier.put(next)
visited[next] = true


this article, show how it’s used for tower defence,

用来寻路,在循环中,记录足迹, 把 visited 改为 came_from

frontier = queue()
frontier.put(start)
came_from= {}
came_from[start] = None
while nor frontier.empty():
current = frontier.get()
for next in graph.neighbors(current):
if next not in came_from:
frontier.put(next)
came_from[next] = current


这样 came_from 指向前面一步的足迹,可以根据这点重建路劲

current = goal
path = [current]
while current != start
current = came_from[current]
path.append(current)
path.reverse()


现实中,我们并不需要所有的方向路径,只要记住某个方向的路劲即可。

只要找到了goal,即可停止

frontier = Queue()
frontier.put(start)
came_from = {}
came_form[start] = None
while not frontier.empty():
current = frontier.get()
if current == goal
break
for next in graph.neghbors(current):
if next not in came_from
frontier.put(next)
came_from[next] = current


Movements costs

Dijkstra 算法, cost’_so_far, 记录开始以来的cost, 放进frontier,消耗较少的路劲

frontier = priorityQueue()
frontier.put(start, 0)
came_from = {}
cost_so_far = {}
came_from[start] = None
cost_so_far[start] = 0

while not frontier.empty():
current = frontier.get()

if current == goal
break;
for next in graph.neighbors(current)
new_cost  = cost_so_far[current] + graph.cost(current, next)
if next not in cost_so_far or new_cost<cost_so_far[next]>
cost_so_far[next] =  new_cost
prioity  = new_cost
frontier.put(next, priority)
came_from[next] = current


启发式搜索 Heuristic search

frontier 向目标地方扩展,首先需要定义个启发函数告诉我们离目标有多近

def heuristic(a,b)

# Manhattan distance on a square grid

return abs(a.x – b.x) + abs(a.y – b.y)

在Dijkstra中,我们使用实际的距离来作为priority队列的顺序。此时,在Greedy best first search

我们使用估算的离目标距离作为顺序。离目标最近的地方会首先被访问。

frontier = priorityQueue()
frontier.put(start, 0)
came_from = {}
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


A* 算法

Dijkstra 算法在计算最短路径是个好算法,可是花费太多时间在不需要的方向搜索上面。

Greedy First Search 搜索了希望的方向,可是可能并不是找到的是最短的路径。A*算法即是使用

两种距离,一个是当前距离出发点的距离,一个是当前距离目标的距离。

Dijsktra算法从中心向目标climb,需要周围360 角度搜索 ; 而 Greedy Best First Search 算法,我们

从目标出发。





A*算法,综合了两种方法,如下图中所示,内部的部分拥有最短的路径。A*从内部区域开始搜索,

frontier = PriorityQueue()
frontier.put(start, 0 )
came_from = {}
cost_so_far = {}
came_from[start] = None
cost_so_far[start] = 0

while nor frontier.empty()
current = frontier.get()

if current == goal
break
for next in graph. neighbors(current)
new_cost = cost_so_far[current] + graph.cost(current, next)
if next not in cost_so_far  or new_cost <cost_s0_far[next];
cost_so_far[next] = new_cost
priority = new_cost + heuristic(goal, next)
frontier.put(next, priority)
came_from[next] = current


You can see that A* tries to stay within the same estimated path length (which we use as the priority for the queue) as much as possible. Why does it run faster than Dijkstra’s Algorithm? Both algorithms explore the same set of locations. However, the heuristic
function lets us visit the locations in a different order that makes it more likely that the goal node will be encountered sooner.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: