ウィキペディアには、深さ優先トラバーサルのための非常に優れた疑似コードがあります。これらのトラバーサル アルゴリズムは、トラバーサルに表示される順序でグラフ内のすべてのノードにラベルを付けます。代わりに、ゴールが見つかったらすぐにパスをゴールに戻す必要があります。
それでは、ウィキペディアのアルゴリズムを変更しましょう。
( INCORRECT ALGORITHM DELETED WHICH THE OP COMMENTED ON CORRECTLY BELOW )
Python の実装は次のとおりです。
g = {
'A': ['B', 'C', 'D'],
'B': ['C', 'E', 'F'],
'C': ['A'],
'D': ['B', 'F', 'G', 'H'],
'E': ['G'],
'F': ['A', 'F'],
'G': ['H', 'I'],
'H': [],
'I': []
}
def DFS(g, v, goal, explored, path_so_far):
""" Returns path from v to goal in g as a string (Hack) """
explored.add(v)
if v == goal:
return path_so_far + v
for w in g[v]:
if w not in explored:
p = DFS(g, w, goal, explored, path_so_far + v)
if p:
return p
return ""
# Hack unit test
assert DFS(g, 'A', 'I', set(), "") == "ABEGI"
assert DFS(g, 'A', 'E', set(), "") == "ABE"
assert DFS(g, 'B', 'B', set(), "") == "B"
assert DFS(g, 'B', 'B', set(), "") == "B"
assert DFS(g, 'A', 'M', set(), "") == ""
assert DFS(g, 'B', 'A', set(), "") == "BCA"
assert DFS(g, 'E', 'A', set(), "") == ""
ここでの考え方は、 からへg
の経路をグラフ で見つけたいということです。 実際には の直前に終了する必要があります。v
goal
path_so_far
path_so_far
v
v
が目標である場合は、v
これまでのパスに追加できます。それだけです。
v
それ以外の場合は、エッジの反対側のノードをまだ探索していない、そこから発するすべてのエッジを探索する必要があります。これらのエッジのそれぞれについて、これまでのパスと現在のノードを使用して (再帰的に) 検索できます。ゴールへのパスがない場合はv
、空のパスが返されます。
良い点は、再帰呼び出しに拡張パスを渡すため、再帰を使用して「自動的にバックトラック」することです。