我根据以下内容实现了A*寻路算法:
https://www.redblobgames.com/pathfinding/a-star/introduction.html
我的网格有很多障碍(超过一万个),而且非常大。我知道,为了获得一条最短路径,我需要实现一个可接受的启发式,这样就不会高估当前点与目标之间的距离。理论上,欧几里德距离必须始终小于或等于。然而,使用它,我根本得不到最短路径,因为使用对角线(切比雪夫或八进制)距离,我得到的路径更短。为什么会这样?我错过什么了吗?
代码如下:
图表成本始终返回1
图表邻居返回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)