Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

深さ優先探索(depth-first search: DFS)

  • 根ノードから子ノードへとどんどん深く探索していき、行き着いたらバックトラック(一歩逆戻り)して別のノードを探索する

  • 深さ優先探索 - Wikipedia

実装例

グラフのDFS(再帰あり)

計算量はノード数NNとエッジ数EEに対し O(N+E)O(N + E) 。各ノードを高々1回訪問し、各エッジを高々1~2回訪問するため

到達したnode: 0, visited={0}
到達したnode: 1, visited={0, 1}
到達したnode: 3, visited={0, 1, 3}
到達したnode: 4, visited={0, 1, 3, 4}
到達したnode: 2, visited={0, 1, 2, 3, 4}

グラフのDFS(再帰なし)

stackを使うことで再帰関数を使わない実装もできる

到達したnode: 0, visited={0}
到達したnode: 2, visited={0, 2}
到達したnode: 1, visited={0, 1, 2}
到達したnode: 4, visited={0, 1, 2, 4}
到達したnode: 3, visited={0, 1, 2, 3, 4}
searching a node '0'
1 is found and enqueued to todo
2 is found and enqueued to todo
searching a node '2'
searching a node '1'
3 is found and enqueued to todo
searching a node '3'

2次元グリッドでのDFS

縦HH、横WWのグリッドで、各マスを高々1回訪問するなら計算量はO(HW)O(HW)

0 0
1 0
2 0
2 1
2 2
1 2
0 2
0 1

2次元グリッドでのDFS + バックトラックあり

通常のDFSでは一度探索した経路は再訪問しない(探索を目的とするので)

しかし、様々な経路をたどって最大の利得を得る問題などでは「一旦戻って別の経路を見る」という形で再訪問を許容することもある。その場合はバックトラックを入れる。

例

目的:

  • 合計スコアが最大になる経路と最大スコアを求める

制約条件:

  • grid[i][j] がそのマスのスコア

  • 開始地点のスコアも加算する

  • 上下左右に移動可能

  • 最大 max_steps 回まで移動可能

  • 同じ経路内では同じマスを再訪問しない

この場合、計算量は最大ステップ数をKKとすると、4方向とステップ数でO(4K)O(4^K)ほどになる

best_score=29
best_path=[(0, 0), (0, 1), (1, 1), (1, 2), (2, 2)]