A* 寻路 - 欧几里德距离启发式表现比对角线距离差
A* pathfinding - Euclidean distance heuristic behaving worse than Diagonal distance
我按照这个实现了A*寻路算法:https://www.redblobgames.com/pathfinding/a-star/introduction.html
我的格子障碍物很多(一万多),很大。我明白,为了获得最短路径之一,我需要实施一种可接受的启发式算法,因此它不会高估当前点与目标之间的距离。理论上,欧氏距离必须始终小于或等于。但是,使用它,我根本没有得到最短路径,因为使用对角线(切比雪夫或八分之一)距离我得到了更短的路径。这是为什么?我错过了什么吗?
这是代码:
graph.cost 总是 returns 1
graph.neighbors returns相邻的8个位置(有障碍物少)
def a_star_search(graph, start, goal):
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
priority = new_cost + heuristic(goal, next)
frontier.put(next, priority)
came_from[next] = current
return get_path(came_from, start, goal)
def heuristic(a, b):
dx = abs(b[0] - a[0])
dy = abs(b[1] - a[1])
D = 1
#with D2 = 1 it's even slower but more accurate
D2 = math.sqrt(2)
#Diagonal distance - this is more accurate
#return D*(dx + dy) + (D2 - 2*D)*min(dx, dy)
#Euclidean distance - this is faster and less accurate
return math.sqrt(dx*dx + dy*dy)
问题是因为邻居都是8个相邻的网格点,并且它们之间的成本都是1,所以欧氏距离高估了对角点之间的成本。
对角点之间的实际距离:1
估计距离:sqrt(2) = 1.41421356237
所以欧几里德距离对于您的图表来说不可接受!
我按照这个实现了A*寻路算法:https://www.redblobgames.com/pathfinding/a-star/introduction.html
我的格子障碍物很多(一万多),很大。我明白,为了获得最短路径之一,我需要实施一种可接受的启发式算法,因此它不会高估当前点与目标之间的距离。理论上,欧氏距离必须始终小于或等于。但是,使用它,我根本没有得到最短路径,因为使用对角线(切比雪夫或八分之一)距离我得到了更短的路径。这是为什么?我错过了什么吗? 这是代码:
graph.cost 总是 returns 1
graph.neighbors returns相邻的8个位置(有障碍物少)
def a_star_search(graph, start, goal):
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
priority = new_cost + heuristic(goal, next)
frontier.put(next, priority)
came_from[next] = current
return get_path(came_from, start, goal)
def heuristic(a, b):
dx = abs(b[0] - a[0])
dy = abs(b[1] - a[1])
D = 1
#with D2 = 1 it's even slower but more accurate
D2 = math.sqrt(2)
#Diagonal distance - this is more accurate
#return D*(dx + dy) + (D2 - 2*D)*min(dx, dy)
#Euclidean distance - this is faster and less accurate
return math.sqrt(dx*dx + dy*dy)
问题是因为邻居都是8个相邻的网格点,并且它们之间的成本都是1,所以欧氏距离高估了对角点之间的成本。
对角点之间的实际距离:1
估计距离:sqrt(2) = 1.41421356237
所以欧几里德距离对于您的图表来说不可接受!