幅優先探索
幅優先探索とは
幅優先探索(BFS : Breadth First Search)とはグラフや木構造を探索するためのアルゴリズムであり、探索を開始する位置から近いものから探索していく探索手法。
アルゴリズム
流れ
次の図のような木構造があったとする。
頂点1
を始点として、幅優先探索を行うと次のような流れになる。
- 始点は探索済みとして記録する。
頂点1
と繋がっている頂点2,4
を次の探索点に追加する。
-
頂点
2
探索済みとして記録する。 頂点2
と繋がっている頂点3
を次の探索点に追加する -
頂点
4
探索済みとして記録する。 頂点4
と繋がっている頂点7,6
を次の探索点に追加する -
頂点
3
探索済みとして記録する。 頂点3
と繋がっている頂点5
を次の探索点に追加する -
頂点
7
探索済みとして記録する。 頂点7
と繋がっている頂点は存在しないので何も追加しない -
頂点
6
探索済みとして記録する。 頂点6
と繋がっている頂点8
を次の探索点に追加する -
頂点
5
探索済みとして記録する。 頂点5
と繋がっている頂点は存在しないので何も追加しない -
頂点
8
探索済みとして記録する。 頂点8
と繋がっている頂点は存在しないので何も追加しない
使用するデータ構造
流れの次の探索点の配列の順番を見ると配列の一番左端、要素番号0
の要素が順に取り出され、新たに要素を追加する際には一番右側、要素番号の一番後ろに追加されている。
つまり、FIFO の動作が行われている。この FIFO を表すのに適したデータ構造が**Queue**である。
- 次の探索点の配列から一番前の要素を取り出し、探索を行う
- 探索した際に新たな未探索要素が見つかったら、次の探索点の配列の後ろに要素の追加する
以上の 2 つの処理を行えれば幅優先探索を行うことができる。 そのため、それぞれ Queue を用いると
- 次の探索点の配列から一番前の要素を
dequeue
し(取り出し)、探索を行う - 探索した際に新たな未探索要素が見つかったら、次の探索点の配列の後ろに
enqueue
(要素の追加)する
と言えるので Queue を用いてることができることがわかる。
プログラム
- Python
- C++
- C#
breadth-first-search.py
from collections import deque
box = [[1,2],[1,4],[2,3],[3,5],[4,7],[4,6],[6,8]]
graph = [[] for _ in range(8)]
# 有向グラ フを作成
for i in range(len(box)):
graph[box[i][0]-1].append(box[i][1]-1)
# queueを作成
q = deque()
# 頂点1番を追加
q.append(0)
# 頂点1からの距離を記録する配列
dist = [-1] * 8
dist[0] = 0
while (len(q) > 0):
# dequeue
pos = q.popleft()
for to in graph[pos]:
# 未探索チェック
if dist[to] == -1:
dist[to] = dist[pos] + 1
# enqueue
q.append(to)