リリース・改善中
Algorithm
グラフ探索は BFS や DFS で到達可能な頂点をすべて訪問する手法で、重みなし最短経路、連結成分、閉路検出、トポロジカルソートの基礎です。
グラフ探索とは、頂点と辺からなるグラフで、開始頂点から辺をたどって到達できるすべての頂点をちょうど一度ずつ訪問する処理です。キューを使って近い頂点から一層ずつ広げていく幅優先探索(BFS)と、スタックや再帰で一つの道を行き止まりまでたどってから戻る深さ優先探索(DFS)が基本になります。グラフは通常、隣接リストか隣接行列で表現し、迷路のような二次元グリッドも各マスを頂点とみなせば同じ方法で扱えます。
道路網、SNS の人間関係、タスクの依存関係、Web のリンクはどれもグラフです。BFS はすべての辺のコストが等しいグラフで最短経路を求め、DFS は連結成分の判定、閉路検出、トポロジカルソートの土台になります。ビルドツールのタスク順序決定、ガベージコレクタの到達可能性判定、画像編集ソフトの塗りつぶしもグラフ探索で動いており、コーディング面接でも特によく出題される分野です。
まずは小さなグラフを紙に描き、BFS のキューと DFS の呼び出しスタックがどう変化するかを手で追ってみるのがおすすめです。次に、訪問済みの印をいつ付けるか、距離と親をどう記録するかに注意しながら自分で実装し、グリッドの最短距離、連結成分の数え上げ、Kahn のアルゴリズムによるトポロジカルソートへと進みましょう。
隣接リストは O(V + E) のメモリで疎なグラフに向き、隣接行列は辺の有無を O(1) で調べられる代わりに O(V^2) のメモリを使います。
キューで近い頂点から訪問するため、重みなしグラフでは最初に付いた距離がそのまま最短距離になります。
再帰やスタックで深く進んでから戻る探索で、連結成分、閉路検出、バックトラッキングの土台です。
閉路のない有向グラフで、Kahn のアルゴリズムか DFS の終了順の逆順により依存関係を守る順序を求めます。
6 頂点の無向グラフを辞書ベースの隣接リストで作り、deque を使った BFS で A から各頂点までの最少辺数を、再帰 DFS で訪問順を出力します。どちらの関数も訪問済みの記録を持ち、同じ頂点を二度処理しません。
graph_traversal.py
from collections import deque
graph = {
"A": ["B", "C"],
"B": ["A", "D"],
"C": ["A", "D", "E"],
"D": ["B", "C", "F"],
"E": ["C", "F"],
"F": ["D", "E"],
}
def bfs(start):
"""Shortest number of edges from start to every reachable vertex."""
dist = {start: 0}
queue = deque([start])
while queue:
node = queue.popleft()
for nxt in graph[node]:
if nxt not in dist:
dist[nxt] = dist[node] + 1
queue.append(nxt)
return dist
def dfs(start):
"""Vertices in depth-first visiting order."""
order, seen = [], set()
def visit(node):
seen.add(node)
order.append(node)
for nxt in graph[node]:
if nxt not in seen:
visit(nxt)
visit(start)
return order
print(bfs("A")) # {'A': 0, 'B': 1, 'C': 1, 'D': 2, 'E': 2, 'F': 3}
print(dfs("A")) # ['A', 'B', 'D', 'C', 'E', 'F']
python graph_traversal.pyインストールから グラフ探索 の中心となる考え方まで、6 章で順を追って学びます。
グラフ探索 について質問し、経験を共有し、意見を交わす場所です。
まだディスカッションはありません。最初の話題を始めましょう。
コメント 0件
ログイン · ログインするとコメントできます。
最初のコメントを書いてみましょう。