为什么我的A*实施比洪水填充慢?

cyr*_*rus 10 python a-star path-finding flood-fill

我有一个100,100个瓷砖的空白网格.起点是(0,0),目标是(99,99).瓷砖是4路连接.

我的Floodfill算法在30ms内找到最短路径,但我的A*实现速度慢了大约10倍.

注意:无论网格或布局的大小如何,A*始终比我的填充更慢(3 - 10x).因为洪水填充很简单,所以我怀疑我在A*中缺少某种优化.

这是功能.我使用Python的heapq来维护一个f排序列表.'graph'包含所有节点,目标,邻居和g/f值.

import heapq

def solve_astar(graph):

    open_q = []

    heapq.heappush(open_q, (0, graph.start_point))

    while open_q:

        current = heapq.heappop(open_q)[1]

        current.seen = True # Equivalent of being in a closed queue

        for n in current.neighbours:
            if n is graph.end_point:
                n.parent = current
                open_q = [] # Clearing the queue stops the process

            # Ignore if previously seen (ie, in the closed queue)
            if n.seen:
                continue

            # Ignore If n already has a parent and the parent is closer
            if n.parent and n.parent.g <= current.g:
                continue

            # Set the parent, or switch parents if it already has one
            if not n.parent:
                n.parent = current
            elif n.parent.g > current.g:
                remove_from_heap(n, n.f, open_q)
                n.parent = current

            # Set the F score (simple, uses Manhattan)
            set_f(n, n.parent, graph.end_point)

            # Push it to queue, prioritised by F score
            heapq.heappush(open_q, (n.f, n))

def set_f(point, parent, goal):
    point.g += parent.g
    h = get_manhattan(point, goal)
    point.f = point.g + h
Run Code Online (Sandbox Code Playgroud)

cyr*_*rus 4

这是一个决胜局的问题。在空网格上,从 (0,0) 开始到 (99,99) 会产生许多具有相同 f 分数的图块。

通过在启发式中添加微小的推动,将首先选择稍微接近目的地的图块,这意味着可以更快地达到目标并且需要检查的图块更少。

def set_f(point, parent, goal):
    point.g += parent.g
    h = get_manhattan(point, goal) * 1.001
    point.f = point.g + h
Run Code Online (Sandbox Code Playgroud)

这导致了约 100 倍的改进,使其比洪水填充快得多。