Kurs
Bir labirentte en hızlı rotayı çıkarmaya, bir sosyal ağda insanlar arasındaki bağlantıları belirlemeye ya da internet üzerinde veriyi en verimli şekilde iletmeye çalıştığınızı hayal edin. Bu zorluklar ortak bir hedefe sahiptir: farklı noktalar arasındaki ilişkileri sistematik olarak keşfetmek. Genişlik-öncelikli arama, tam da bunu yapmanıza yardımcı olabilecek bir algoritmadır.
Genişlik-öncelikli arama, graf geçişinden yol bulmaya kadar veri biliminde çok çeşitli problemlere uygulanır. Özellikle ağırlıksız grafiklerde en kısa yolu bulmada kullanışlıdır. Okumaya devam edin; genişlik-öncelikli aramayı ayrıntılı olarak ele alacak ve Python ile bir uygulamasını göstereceğim. Başlarken Python konusunda daha fazla desteğe ihtiyaç duyarsanız, çok kapsamlı Python'a Giriş kursumuza kaydolun.
Genişlik-Öncelikli Arama (BFS) Nedir?
Genişlik-öncelikli arama (BFS), bir grafı veya ağacı seviye seviye keşfeden bir geçiş algoritmasıdır. Belirli bir kaynak düğümden başlayarak, BFS önce tüm doğrudan komşuları ziyaret eder, ardından bir sonraki seviye düğümlere geçer. Bu sayede aynı derinlikteki düğümler, daha derine inmeden önce işlenmiş olur. Bu özelliği nedeniyle BFS, tüm olası yolların yapılandırılmış ve sistematik bir biçimde incelenmesini gerektiren problemler için kullanışlıdır.
BFS, düğümler arasındaki en kısa yolu bulmada etkilidir; çünkü bir düğüme ilk kez ulaştığında en kısa rotayı kullanmış olur. Bu da BFS'yi, iki nokta arasındaki en verimli güzergâhın bulunmasının amaçlandığı ağ yönlendirme gibi problemler için uygun kılar. Aşağıdaki diyagram, BFS'nin bir ağacı nasıl keşfettiğine dair basitleştirilmiş bir açıklama gösterir.

Genişlik-Öncelikli Arama Algoritmasının Temel Özellikleri
Genişlik-öncelikli arama, bir düğümün tüm komşularını ziyaret ettikten sonra bir sonraki katmana ilerleyerek bir grafı veya ağacı keşfetmek üzere tasarlanmıştır. Bu yapılandırılmış geçiş, belirli bir derinlikteki tüm düğümlerin, yapının daha derinine inmeden önce araştırılmasını sağlar. Bu seviye seviye yaklaşım, BFS'yi karmaşık ağlarda gezinmek için sistematik ve güvenilir bir yöntem hâline getirir.
Geçiş yöntemi
BFS, bir sonraki seviyeye geçmeden önce mevcut derinlik seviyesindeki her düğümü keşfeder. Bu, başlangıç noktasından belirli bir uzaklıktaki tüm düğümlerin daha derine inmeden önce işleneceği anlamına gelir.
Kuyruk tabanlı uygulama
BFS, ziyaret edilmesi gereken düğümleri yönetmek için bir kuyruk kullanır. Algoritma bir düğümü işler, ziyaret edilmemiş komşularını kuyruğa ekler ve bu düzeni sürdürür. Kuyruk ilk giren ilk çıkar mantığıyla çalışır; bu da düğümlerin keşfedildikleri sırayla incelenmesini sağlar.
Ağırlıksız grafiklerde en kısa yolu garanti eder
Ağırlıksız grafiklerde, yani her bağlantının aynı uzunlukta olduğu durumlarda, BFS düğümler arasındaki en kısa yolu bulmayı garanti eder. BFS komşuları seviye seviye keşfettiği için bir düğüme ilk ulaştığında bunu mümkün olan en kısa yoldan yapar. Bu, tüm kenarların eşit ağırlığa sahip olduğu kısa yol problemlerinde BFS'yi özellikle etkili kılar.
Graf ve ağaçlar için uygulanabilir
BFS hem grafiklerde hem de ağaçlarda çalışır. Graf, bir sosyal ağ gibi döngüler içerebilen bağlı düğümlerden oluşan bir ağ iken, ağaç, bir köke sahip ve döngüsü olmayan bir hiyerarşidir; soy ağacı gibi. BFS her ikisi için de kullanışlıdır ve bu da onu çok geniş bir görev yelpazesinde uygulanabilir kılar.
Python ile Genişlik-Öncelikli Arama Uygulaması
BFS algoritmasını Python'da bir ağaç üzerinde gösterelim. Python becerilerinizi tazelemeniz gerekiyorsa, DataCamp'teki Python Programming yetkinlik yoluna göz atın. Farklı veri yapıları ve algoritmalar hakkında daha fazla bilgi için Data Structures and Algorithms in Python kursumuzu alın ve Data Structures: A Comprehensive Guide With Python Examples eğitim yazımızı okuyun.
Başlayalım. Önce, BFS'nin arama yapacağı basit bir karar ağacı kurmamız gerekiyor.
Sırada bu basit karar ağacını bir Python sözlüğü kullanarak tanımlayacağız; burada her anahtar bir düğümdür ve değeri, düğümün çocuklarının listesidir.
# Define the decision tree as a dictionary
tree = {
'A': ['B', 'C'], # Node A connects to B and C
'B': ['D', 'E'], # Node B connects to D and E
'C': ['F', 'G'], # Node C connects to F and G
'D': ['H', 'I'], # Node D connects to H and I
'E': ['J', 'K'], # Node E connects to J and K
'F': ['L', 'M'], # Node F connects to L and M
'G': ['N', 'O'], # Node G connects to N and O
'H': [], 'I': [], 'J': [], 'K': [], # Leaf nodes have no children
'L': [], 'M': [], 'N': [], 'O': [] # Leaf nodes have no children
}
Şimdi BFS algoritmasını Python'da uygulayalım. BFS, bir sonraki seviyeye geçmeden önce mevcut seviyedeki tüm düğümleri ziyaret ederek çalışır. Hangi düğümlerin sırada ziyaret edileceğini yönetmek için bir kuyruk kullanacağız.
from collections import deque # Import deque for efficient queue operations
# Define the BFS function
def bfs(tree, start):
visited = [] # List to keep track of visited nodes
queue = deque([start]) # Initialize the queue with the starting node
while queue: # While there are still nodes to process
node = queue.popleft() # Dequeue a node from the front of the queue
if node not in visited: # Check if the node has been visited
visited.append(node) # Mark the node as visited
print(node, end=" ") # Output the visited node
# Enqueue all unvisited neighbors (children) of the current node
for neighbor in tree[node]:
if neighbor not in visited:
queue.append(neighbor) # Add unvisited neighbors to the queue
Artık BFS fonksiyonumuzu oluşturduğumuza göre, kök düğüm A'dan başlayarak ağaç üzerinde çalıştırabiliriz.
# Execute BFS starting from node 'A'
bfs(tree, 'A')
Bunu çalıştırdığımızda, her düğümü ziyaret edildiği sırayla çıktılar.
A B C D E F G H I J K L M N O
Ağaçlarda ve Grafiklerde BFS
Ağaçlar doğaları gereği döngüsüz olduğundan, BFS'nin geçiş deseni ağaçlarda düzgündür. Algoritma kökten başlar ve bir sonraki seviyeye geçmeden önce tüm çocukları ziyaret eder. Bu seviye sıralı geçiş, ağaçlardaki hiyerarşik ilişkileri yansıtır: her düğümün bir ebeveyni ve birden fazla çocuğu vardır; bu da öngörülebilir bir desen oluşturur.
Buna karşılık, grafikler döngüler içerebilir. Düğümler arasındaki birden fazla yol, daha önce ziyaret edilen düğümlere geri dönebilir. Bu durum BFS için sorun yaratabilir ve tekrar ziyaretlerin dikkatle yönetilmesini gerektirir. Hangi düğümlerin ziyaret edildiğinin takibini yapmak, gereksiz yeniden işlemeyi önler ve döngülerin sonsuz çevrimlere yol açmasını engeller. Önceki BFS uygulamamızda, her düğümün yalnızca bir kez işlenmesini sağlamak için bir visited listesi kullandık. Ziyaret edilmiş bir düğümle karşılaşıldığında, atlandı ve BFS sorunsuzca devam etti.
Zaman ve Bellek Karmaşıklığı
Genişlik-öncelikli arama ne kadar verimlidir? BFS'nin verimliliğinin, graf boyutunun bir fonksiyonu olarak nasıl değiştiğini değerlendirmek için Big O gösterimini kullanabiliriz.
Zaman karmaşıklığı
BFS'nin zaman karmaşıklığı O(V+E)'dir; burada V, tepe (düğüm) sayısını ve E, grafdaki kenar sayısını ifade eder. Bu, BFS'nin performansının hem düğüm sayısına hem de aralarındaki bağlantılara bağlı olduğu anlamına gelir.
Bellek karmaşıklığı
BFS'nin bellek karmaşıklığı, kuyruğa alınan düğümleri saklamak için gereken bellek nedeniyle O(V)'dir. Daha geniş grafiklerde bu, aynı anda birçok düğümün saklanması anlamına gelebilir. En kötü durumda, tüm düğümlerin aynı anda tutulmasını gerektirebilir.
Genişlik-Öncelikli Aramanın Gerçek Hayat Uygulamaları
Genişlik-öncelikli aramanın bilgisayar bilimi, ağ teknolojileri ve yapay zekâ gibi alanlarda sayısız pratik uygulaması vardır. Düzgün, seviye seviye keşfi; arama ve yol bulma problemleri için onu ideal kılar.
Kullanım örnekleri
BFS'nin bir uygulaması, ağ yönlendirme algoritmalarındadır. Veri paketleri bir ağda ilerlerken, yönlendiriciler en kısa yolu bulmak için BFS kullanır. Daha derine inmeden önce tüm komşu düğümleri keşfederek, BFS gecikmeyi azaltan ve performansı artıran verimli rotaları hızla belirler.
BFS, labirentler veya kaydırmalı bulmacalar gibi bulmaca çözme için de kullanışlıdır. Her konum bir düğümdür ve bağlantılar kenarlardır. BFS, başlangıçtan çıkışa en kısa yolu verimli bir şekilde bulabilir.
Bir diğer güçlü kullanım alanı sosyal ağ analizidir. BFS, kullanıcılar arasındaki ilişkileri keşfetmeye ve etkili düğümleri belirlemeye yardımcı olur. Sosyal bağlantıları tarayarak ilişkili kullanıcı kümelerini ortaya çıkarabilir ve ağ yapıları hakkında içgörüler sunar.
YZ uygulamaları
BFS, yapay zekâ eğitiminde de kullanışlıdır. Örneğin, satranç gibi oyunlardaki oyun durumlarını aramak için kullanılabilir. YZ algoritmaları, olası hamleleri seviye seviye keşfetmek, gelecekteki durumları değerlendirmek ve en iyi eylemi belirlemek için BFS'den yararlanabilir; böylece zafere giden en kısa yolu bulur.
BFS, robotikte yol planlama için de uygulanır. Robotların çevrelerini haritalandırarak ve engellerden kaçınırken yolları bulmalarını sağlayarak karmaşık ortamlarda gezinmelerine imkân verir.
Genişlik-Öncelikli Arama ve Diğer Arama Algoritmaları Karşılaştırması
BFS'yi derinlik-öncelikli arama ve Dijkstra algoritması gibi diğer yaygın arama algoritmalarıyla karşılaştıralım.
Derinlik-öncelikli aramayla karşılaştırma
Genişlik-öncelikli arama ve derinlik-öncelikli arama (DFS) her ikisi de graf geçiş algoritmalarıdır; ancak grafı farklı şekilde keşfederler. BFS, daha derine inmeden önce mevcut derinlikteki tüm komşuları ziyaret ederken, DFS bir yolda olabildiğince derine iner ve sonra geri izler.
BFS, ağırlıksız grafiklerde en kısa yolu bulmada harikadır. Bu avantaj, onu labirentte gezinme ve ağ oluşturma gibi problemler için iyi bir seçim yapar. Buna karşılık, DFS her zaman en kısa yolu bulamayabilir; ancak derin ve geniş grafiklerde daha bellek verimli olabilir. Bu da onu, aşırı bellek kullanımı olmaksızın tam bir geçişin gerektiği topolojik sıralama veya planlama problemleri gibi görevler için tercih edilir kılar.
Dijkstra algoritmasıyla karşılaştırma
Dijkstra algoritması, kenarların farklı maliyetlere sahip olduğu ağırlıklı grafikler için tasarlanmış bir graf geçiş algoritmasıdır. Tüm kenarları eşit kabul eden BFS'nin aksine, Dijkstra en kısa yolu kenar ağırlıklarına göre hesaplar. Seyahat süresi gibi maliyetin önemli olduğu uygulamalarda en uygunudur.
Dijkstra, ağırlıklı grafikler için güçlü olsa da daha karmaşık ve hesaplama açısından daha yoğundur. Öncelik kuyruğu kullanıldığında Dijkstra'nın zaman karmaşıklığı O((V+E)logV) olup, BFS'nin O(V+E) zaman karmaşıklığından belirgin şekilde yüksektir. Dijkstra Algoritması hakkında daha fazla bilgiyi Python'da Dijkstra Algoritmasının Uygulanması: Adım Adım Rehber yazımızda bulabilirsiniz.
Olası Sorunlar
BFS kullanırken karşılaşabileceğiniz sorunlardan biri, bir döngüye yakalanmaktır. Bir yol, daha önce ziyaret edilen bir düğüme geri döndüğünde bir döngü oluşur ve geçişte bir çevrim yaratır. BFS, ziyaret edilen düğümleri düzgün biçimde takip etmezse bu, sonsuz döngüye yol açabilir. İşlendikten sonra her düğümü ziyaret edildi olarak işaretlemek ya da bir ziyaret listesi tutmak önemlidir. Bu basit yaklaşım, BFS'nizin grafı verimli bir şekilde keşfetmesini ve düzgün biçimde sonlanmasını sağlamalıdır.
Bir diğer yaygın hata ise kuyruğun yanlış kullanımıdır. BFS, keşfedilmesi gereken düğümlerin takibini yapmak için bir kuyruğa dayanır. Kuyruk doğru yönetilmezse, geçişte düğümlerin atlanmasına ya da yanlış yolların izlenmesine neden olabilir. Bunu önlemek için, düğümleri keşfedilecekleri sırayla kuyruğa ekleyip sonra çıkarın. Bu, BFS'nin tasarlandığı gibi düğümleri seviye seviye keşfetmesine yardımcı olur. Python'da collections.deque gibi güvenilir bir veri yapısı kullanmak bu konuda yardımcıdır.
BFS'nin uygun olmadığı durumlar
Çok yönlülüğüne rağmen, BFS her durumda en iyi seçenek olmayabilir. Örneğin, BFS çok büyük veya çok derin grafikler için her zaman uygun değildir; bu gibi durumlarda derinlik-öncelikli arama daha pratik olabilir. Ayrıca, BFS ağırlıklı grafikler için uygun değildir; çünkü tüm kenarları eşit kabul eder. A* veya Dijkstra gibi algoritmalar, en kısa yolu hesaplarken değişen maliyetleri dikkate aldıkları için bu durumlara daha uygundur.
Sonuç
BFS, özellikle ağırlıksız grafiklerde en kısa yolu bulmada değerlidir. Seviye bazlı keşfi, her derinlik seviyesindeki düğümlerin kapsamlı biçimde incelenmesini gerektiren durumlar için onu mükemmel bir araç hâline getirir.
Arama algoritmalarıyla ilgileniyorsanız, bu serideki diğer yazılarıma da göz atın: Python'da İkili Arama: Verimli Arama için Eksiksiz Rehber. Ayrıca AVL Ağacı: Python Uygulamasıyla Eksiksiz Rehber ve Python'da Ağ Analizine Giriş ilginizi çekebilir.

Biyolojik araştırma ortamında verilerle çalışma konusunda 13 yıllık deneyime sahip bir doktora sahibiyim. Python, MATLAB ve R dahil olmak üzere birkaç programlama dilinde yazılım geliştiriyorum. Öğrenme sevgimi dünyayla paylaşma konusunda tutkuluyum.
BFS SSS
Genişlik-öncelikli arama nedir?
Genişlik-öncelikli arama, bir grafı veya ağacı seviye seviye sistematik olarak keşfeden bir graf geçiş algoritmasıdır.
BFS, DFS'den nasıl farklıdır?
BFS, daha derine inmeden önce mevcut derinlikteki tüm komşuları ziyaret ederek grafı seviye seviye keşfeder; DFS ise geri izleme yapmadan önce tek bir yolda olabildiğince derine iner.
BFS'nin bazı avantajları nelerdir?
Ağırlıksız grafiklerde en kısa yolu bulur ve grafikler ile ağaçlarda iyi çalışır.
BFS'nin bazı dezavantajları nelerdir?
Graf ağırlıklarını dikkate almaz ve derinlik-öncelikli arama kadar bellek verimli değildir.
BFS'nin bazı gerçek dünya uygulamaları nelerdir?
BFS, ağ yönlendirme, sosyal ağ analizi ve bulmaca çözmede kullanılır.