Python A*寻路-欧几里德距离启发式行为比对角线距离更差

Python A*寻路-欧几里德距离启发式行为比对角线距离更差,python,path-finding,a-star,heuristics,Python,Path Finding,A Star,Heuristics,我根据以下内容实现了A*寻路算法: 我的网格有很多障碍(超过一万个),而且非常大。我知道,为了得到一条最短路径,我需要实现一个可接受的启发式,这样它就不会高估当前点和目标之间的距离。理论上,欧几里德距离必须总是小于或等于。然而,使用它,我根本没有得到最短路径,因为使用对角线(切比雪夫或八进制)距离,我得到的路径更短。为什么呢?我错过什么了吗? 代码如下: graph.cost始终返回1 graph.neighbors返回8个径向位置(如果有障碍物,则会减少) def a_star_搜索(图形、开

我根据以下内容实现了A*寻路算法:

我的网格有很多障碍(超过一万个),而且非常大。我知道,为了得到一条最短路径,我需要实现一个可接受的启发式,这样它就不会高估当前点和目标之间的距离。理论上,欧几里德距离必须总是小于或等于。然而,使用它,我根本没有得到最短路径,因为使用对角线(切比雪夫或八进制)距离,我得到的路径更短。为什么呢?我错过什么了吗? 代码如下:

graph.cost始终返回1

graph.neighbors返回8个径向位置(如果有障碍物,则会减少)

def a_star_搜索(图形、开始、目标):
frontier=优先队列()
边界。放置(开始,0)
来自={}
成本迄今为止={}
从[开始]=无
成本迄今为止[开始]=0
而不是边疆。空()
current=frontier.get()
如果当前==目标:
打破
对于图中的下一个。邻居(当前):
新成本=迄今为止的成本[当前]+图表成本(当前,下一个)
如果下一个不在成本中或新成本
问题在于,由于邻域都是8个相邻的网格点,并且它们之间的代价都是1,因此欧几里德距离高估了对角线点之间的代价

对角线点之间的实际距离:1

估计距离:sqrt(2)=1.41421356237

所以欧几里德距离对于你的图是不允许的

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)