Genişlik Öncelikli Arama (BFS)
Grafı başlangıçtan uzaklığa göre katman katman gezen ve ağırlıksız grafta en kısa yolu bulan algoritma.
Önce bunlara göz at
#Nasıl çalışır?
Genişlik öncelikli arama (Breadth-First Search, BFS), bir graftaki düğümleri başlangıç noktasına olan uzaklıklarına göre, katman katman gezer: önce tüm komşular, sonra komşuların komşuları, ve böyle devam eder.
Bu sırayı bir kuyruk (queue) sağlar: keşfedilen düğüm kuyruğun sonuna eklenir, sıradaki düğüm önden alınır. Bir düğümün iki kez eklenmemesi için "ziyaret edildi" kümesi tutulur.
Ağırlıksız bir grafta BFS'in bir düğümü ilk keşfettiği yol, o düğüme giden en kısa yoldur. Her düğümün nereden keşfedildiği (prev) kaydedilirse, yol hedeften geriye doğru izlenerek bulunur.
#Kendin dene
Komşuluk listesi
- 1: 2, 3
- 2: 1, 4, 5
- 3: 1, 5, 6
- 4: 2, 7
- 5: 2, 3, 7
- 6: 3, 7
- 7: 4, 5, 6
Bir başlangıç düğümü seç ve BFS'in grafı katman katman nasıl gezdiğini izle. İki düğüm vererek en kısa yolu da bulabilirsin.
#Adım adım
- 01Başlangıç düğümünü kuyruğa koy ve ziyaret edildi olarak işaretle.
- 02Kuyruk boşalana kadar önden bir düğüm (u) al.
- 03u'nun her komşusuna (v) bak; daha önce görülmediyse işaretle, prev[v] = u yaz ve kuyruğun sonuna ekle.
- 04En kısa yol için: hedef kuyruktan çıktığında dur ve prev[] zincirini hedeften başlangıca doğru izle.
#Örnek kod
Aynı algoritma 8 dilde. Her program derlenip çalıştırılarak test edildi ve hepsi aynı çıktıyı veriyor.
from collections import deque
# Undirected graph as adjacency lists (neighbours in increasing order).
EDGES = [(1, 2), (1, 3), (2, 4), (2, 5), (3, 5), (3, 6), (4, 7), (5, 7), (6, 7)]
graph = {v: [] for v in range(1, 8)}
for a, b in EDGES:
graph[a].append(b)
graph[b].append(a)
for v in graph:
graph[v].sort()
def bfs(start: int) -> list:
order, visited, queue = [], {start}, deque([start])
while queue:
u = queue.popleft()
order.append(u)
for v in graph[u]:
if v not in visited:
visited.add(v) # mark when queued, so nothing is queued twice
queue.append(v)
return order
def shortest_path(start: int, target: int) -> list:
prev, queue = {start: None}, deque([start])
while queue:
u = queue.popleft()
if u == target:
break
for v in graph[u]:
if v not in prev:
prev[v] = u
queue.append(v)
if target not in prev:
return []
path = [target]
while prev[path[-1]] is not None:
path.append(prev[path[-1]])
return path[::-1]
print(" ".join(map(str, bfs(1)))) # layer by layer
print(" ".join(map(str, shortest_path(1, 7)))) # fewest edges from 1 to 7#Karmaşıklık
| İşlem | Süre |
|---|---|
| Zaman (komşuluk listesi) | O(V + E) |
| Zaman (komşuluk matrisi) | O(V²) |
| Bellek (kuyruk + ziyaret) | O(V) |
| En kısa yol (ağırlıksız) | O(V + E) |
V düğüm, E kenar sayısıdır. Her düğüm kuyruğa en fazla bir kez girer ve her kenara iki uçtan birer kez bakılır. Kenarların ağırlıkları farklıysa BFS en kısa yolu bulamaz; o zaman Dijkstra gerekir.
#Ne zaman kullanılır?
Ağırlıksız grafta en kısa yol (labirent, oyun haritası, "kaç adımda" soruları), sosyal ağda arkadaşın arkadaşı önerileri, web tarayıcılarının sayfaları katman katman gezmesi, bir ağdaki yayılma (broadcast) ve iki parçalı (bipartite) graf kontrolü BFS ile yapılır.
#Alıştırma
Soruları cevaplamak ve ilerlemeni kaydetmek için giriş yap.
Kolay
BFS sıradaki düğümü tutmak için hangi veri yapısını kullanır?
- 1Kuyruk (queue)
- 2Yığın (stack)
- 3Heap
- 4Hash tablosu
Komşuluk listesiyle BFS'in zaman karmaşıklığı nedir?
- 1O(V + E)
- 2O(V · E)
- 3O(V²)
- 4O(E log V)
BFS hangi grafta en kısa yolu garanti eder?
- 1Ağırlıksız (ya da tüm ağırlıkları eşit) graflarda
- 2Negatif ağırlıklı graflarda
- 3Her ağırlıklı grafta
- 4Hiçbirinde
Orta
1'den başlayan BFS'te 1–2, 1–3, 2–4, 3–4 kenarlı grafta düğümler hangi sırayla ziyaret edilir (komşular küçükten büyüğe)?
- 11, 2, 3, 4
- 21, 2, 4, 3
- 31, 3, 4, 2
- 41, 4, 2, 3
Zor
Bir düğüm neden kuyruğa eklenirken (çıkarken değil) ziyaret edildi olarak işaretlenir?
- 1Aynı düğümün kuyruğa birden fazla kez girmesini önlemek için
- 2Aksi halde BFS yanlış mesafeler verir
- 3Daha az kenara bakmak için
- 4Kuyruğu sıralı tutmak için
#Bundan sonra
Bu dersi bildiğini varsayan dersler: