私は100,100タイルのブランクグリッドを持っています。開始点は(0,0)、目標は(99,99)です。タイルは4方向の接続です。私の実装はfloodfillよりも遅いのはなぜですか?
私のfloodfillアルゴリズムは30msで最短のパスを見つけますが、私の実装は約10倍遅くなります。
注:A *は、どんな種類のグリッドまたはレイアウトのサイズであっても、フロッドフィルよりも一貫して低速です(3〜10倍)。 floodfillはシンプルなので、私はA *で何らかの最適化が行えないと思う。
ここに機能があります。私はPythonのheapqを使ってfソートされたリストを維持しています。 「グラフ」は、すべてのノード、ゴール、ネイバー、および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
'remove_from_heap'を表示できますか?それはあなたのボトルネックかもしれません。 – templatetypedef
@templatetypedefこれは 'heap.remove((f_value、tile))'ですが、削除されていないときでさえ、はるかに速く実行されるわけではありません。 – cyrus
ヒープ除去操作は線形時間で実行されるため、インテリジェントなA *検索で得られるすべての効率を完全に犠牲にする可能性があります。これはあなたの問題ではないと確信していますか? – templatetypedef