T: tema · Z: kodu büyüt · S: konuşmacı notları · F: tam ekran · Esc: genel bakış · ⌂ ders haritası
OYUNLARDA YAPAY ZEKÂ · GRAFLAR
En Kısa Yollar
Gevşetme, Dijkstra, DAG’ler, Bellman–Ford — oyunlarda yol bulmanın kapısı
PRESS ▶ TO START

Bu derste oyunun haritası 🗺️

  1. Temeller — en kısa yollar ağacı, gevşetme relaxation
  2. Dijkstra — negatif olmayan ağırlıklar için klasik
  3. Oyunda yol bulma — arazi maliyeti, Dijkstra haritaları, A*’a köprü
  4. DAG’ler — doğrusal zaman; en uzun yol = kritik yol
  5. Negatif ağırlıklar — Bellman–Ford ve “sonsuz altın” açığı
🎮 Bu dersin sonunda…

…bir birimin bataklıktan değil yoldan dolaşmasını sağlayan yol bulmayı, yüzlerce düşmanı tek bir hesapla yönlendiren “Dijkstra haritası”nı ve oyun ekonomisindeki ticaret açıklarını bulan algoritmayı anlayacaksınız.

🤔 ISINMA: KISA MI, UCUZ MU?

Bir RTS biriminiz haritanın öbür ucuna gidecek. Düz gitse 20 kare ama 12’si bataklık (her biri 6 kat yavaş). Yoldan dolaşsa 30 kare, hepsi hızlı.

  • BFS (Yönsüz Graflar sunumu) adım sayar → bataklıktan geçer: 8 + 12×6 = 80 birim süre
  • Yoldan: 30 × 1 = 30 birim süre
  • Kenarların ağırlığı (süre, yakıt, tehlike) varsa “en kısa” = toplam ağırlığı en küçük yol. Bunun için yeni algoritmalar gerekiyor.

Mini sözlük

edge-weighted digraphkenar ağırlıklı yönlü grafHer yönlü kenarın bir maliyeti var
shortest-path tree (SPT)en kısa yollar ağacıKaynaktan herkese en kısa yolların birleşimi
distTo[] · edgeTo[]uzaklık · son kenarŞimdiye kadarki en iyi uzaklık · o yolun son kenarı
relaxationgevşetme“Bu kenarı kullanınca daha kısa olur mu?” kontrolü ve güncellemesi
negative cyclenegatif döngüAğırlıkları toplamı negatif olan döngü
critical pathkritik yolBir iş planındaki en uzun bağımlılık zinciri
heuristicsezgisel tahmin“Hedefe aşağı yukarı ne kadar kaldı?” (A*’ın sırrı)
LEVEL 0
Temeller ve gevşetme
bütün en kısa yol algoritmalarının ortak hamlesi
  • temeller ve gevşetme
  • Dijkstra
  • oyunda yol bulma
  • DAG’ler ve kritik yol
  • negatif ağırlıklar

Problemin çeşitleri

  • Tek kaynak: s’den herkese (bu derste)
  • Kaynak–hedef: s’den t’ye (oyunda en sık; aynı algoritma, t bulununca dur)
  • Tüm çiftler: herkesten herkese (küçük haritalarda önceden hesaplanıp tabloda tutulur)
ağırlıklar…algoritma
hepsi eşit (1)BFS
negatif değilDijkstra
herhangi, graf DAGtopolojik sırayla gevşet
negatif olabilir, negatif döngü yokBellman–Ford
Gösterim: en kısa yollar ağacıFikir: s’den herkese en kısa yolların birleşimi bir ağaçtır. Onu iki dizi ile tutarız: distTo[v] (s’den v’ye en kısa uzaklık) ve edgeTo[v] (o yoldaki son kenar). Yol = edgeTo zincirini geriye izlemek (DFS/BFS’teki gibi!).

Gevşetme relaxation — kendiniz deneyin

Soru: “s’den w’ye, v üzerinden (v→w kenarıyla) gitmek şimdiki en iyi yoldan daha mı kısa?” Evetse güncelle. Kaydırıcılarla oynayın. Bütün algoritmalar sadece bu hamleyi farklı sıralarda yapar.

Gevşetme — kod

Önerme (en iyilik koşulu)distTo[] değerleri ancak ve ancak hiçbir kenar gevşetilemiyorsa (her v→w için distTo[w] ≤ distTo[v] + ağırlık) en kısa uzaklıklardır.

Genel algoritma: “Gevşetilebilen bir kenar kaldıkça gevşet.” Doğru ama yavaş olabilir. Dijkstra, DAG ve Bellman–Ford bu genel algoritmanın akıllı sıralamalarıdır.

🎒 Sonsuz (∞) neden işe yarar? ∞ + 5 = ∞ ve her sayı ∞’dan küçük → ilk bulunan yol her zaman kabul edilir. Tam sayı dizilerde ∞ yoksa çok büyük bir sayı (ör. int.MaxValue / 2 — taşmasın diye yarısı!) kullanılır.

🎒 Kodu okuyalım

ifadene demekneden böyle
distTo[v] + weight < distTo[w]v’ye kadar + v→w kenarı, w’nin bilinen en iyisinden kısa mı?“daha kısa bir yol buldum mu?” sorusunun tamamı bu satır
distTo[w] = …w’nin en iyi bilinen uzaklığını güncellebu değer yalnızca küçülebilir; büyümez
edgeTo[w] = vw’ye artık v’den geliniyoryolu geri izlemek için; eski kayıt silinir
başlangıç değerleridistTo[s] = 0, ötekiler InfinityInfinity + ağırlık hâlâ Infinity: henüz ulaşılmamış düğüm hiçbir şeyi gevşetemez
return truebir şey değiştiDijkstra bu cevaba göre öncelik kuyruğunu günceller

🔗 Başka gözle: etkileşimli anlatımlar ve yazılar

Aynı konuyu başka bir anlatımla, kendi elinizle oynayarak görmek çok işe yarar. Kartlar yeni sekmede açılır; çoğu İngilizce ama görsel ve etkileşimli.

Quiz 1 · temeller
distTo[v] = 7, distTo[w] = 12, v→w kenarının ağırlığı 4. v→w gevşetilince ne olur?
7 + 4 = 11 < 12 → v üzerinden gitmek daha kısa: distTo[w] = 11, edgeTo[w] = v. Gevşetme sadece kenarın ucundaki (w) değerleri değiştirir.
LEVEL 1
Dijkstra
en yakın kesinleşmemiş düğümü al, oklarını gevşet
  • temeller ve gevşetme
  • Dijkstra
  • oyunda yol bulma
  • DAG’ler ve kritik yol
  • negatif ağırlıklar

Saf yaklaşım: bütün yolları dene

4121538SABCT

Köy S’den kale T’ye; sayılar yol süresi (dakika). Yeşil = en kısa yol; kırmızı kesikli = en az adımlı yolun son kenarı.

Saf yol 1: bütün yolları yaz, toplamlarını karşılaştır
yoladımsüre
S → A → C → T34 + 1 + 3 = 8
S → B → A → C → T41 + 2 + 1 + 3 = 7 ✔
S → B → C → T31 + 5 + 3 = 9
S → B → T21 + 8 = 9

Bu grafta 4 yol var. Bir k × k ızgarada yalnızca sağa ve aşağı giden yollar bile: 10 × 10 → 48 620; 20 × 20 → 35 milyar; 50 × 50 → 2,5 × 1028.

Saf yol 2: BFS (en az adım)BFS S → B → T’yi seçer: 2 adım ama 9 dakika. Ağırlıklar eşit değilse “az adım” ≠ “kısa yol”.
DijkstraYolları değil düğümleri sayar: her düğüm bir kez kesinleşir, her kenar bir kez gevşetilir → E log V.

Dijkstra’nın fikri

  1. distTo[s] = 0, diğerleri ∞
  2. Henüz kesinleşmemiş düğümler arasından distTo’su en küçük olanı (v) seç → v artık kesin
  3. v’nin bütün oklarını gevşet
  4. Herkes kesinleşene kadar tekrarla
BFS + öncelik kuyruğuBFS’te kuyruk (FIFO) “en az adımlı”yı öne alıyordu. Dijkstra’da öncelik kuyruğu “en az maliyetli”yi öne alır. Tüm ağırlıklar 1 ise Dijkstra = BFS!

Prim ile kardeş: Prim “ağaca en yakın”ı, Dijkstra “kaynağa en yakın”ı seçer.

Dijkstra — iz tablosu

Mor kesikli = PQ’da, yeşil = kesinleşti, mavi kenar = az önce gevşedi. Sonuç (0’dan): 2: .26, 4: .38, 7: .60, 5: .73, 3: .99, 1: 1.05, 6: 1.51. Başka bir kaynak için düğüme tıklayın.

Elle izleme: Dijkstra, adım adım

4121538S0A3B1C4T7

Rozet = kesinleşen uzaklık. Yeşil = en kısa yollar ağacı (edgeTo): T ← C ← A ← B ← S.

Neden A için 4 değil 3?S → A doğrudan 4 dakika; ama B’ye 1 dakikada gidip oradan 2 dakikada A’ya varmak 3 eder. Dijkstra A’yı, kendisinden daha yakın olan B kesinleşmeden “kesin” saymaz.
#PQ’dan çıkangevşetmelerPQ (sonra)
0—dist[S] = 0(S, 0)
1(S, 0)S → A: 0 + 4 = 4 · S → B: 0 + 1 = 1(B, 1) (A, 4)
2(B, 1)B → A: 1 + 2 = 3 < 4 · B → C: 6 · B → T: 9(A, 3) (A, 4) (C, 6) (T, 9)
3(A, 3)A → C: 3 + 1 = 4 < 6(C, 4) (A, 4) (C, 6) (T, 9)
4(C, 4)C → T: 4 + 3 = 7 < 9(A, 4) (C, 6) (T, 7) (T, 9)
5(A, 4)bayat: A zaten 3 ile kesin, at(C, 6) (T, 7) (T, 9)
6(C, 6)bayat, at(T, 7) (T, 9)
7(T, 7)T kesin: hedef!(T, 9)

Sonuç: S 0, B 1, A 3, C 4, T 7. Yol: S → B → A → C → T.

“Bayat kayıt” hilesi: uzaklık azalınca eski kaydı silmek yerine yenisini ekleriz; eski kayıt çıkınca “bu düğüm zaten kesin” deyip atarız. Tek hedef aranıyorsa 7. adımda durulur.

Dijkstra — kod (ikili yığınla)

🎒 “Bayat kayıt” hilesi ve indeksli PQ

Bir düğümün uzaklığı iyileşince PQ’daki eski kaydını güncellemek gerekir. İki yol:

  1. İndeksli öncelik kuyruğu (iz tablosundaki demo): PQ her düğümün nerede olduğunu bilir, önceliğini düşürür (decreaseKey). PQ’da en fazla V kayıt.
  2. Tembel silme (koddaki): yeni bir kayıt ekle, eskisini bırak. Eski kayıt çıkınca d > dist[v] ile tanı ve atla. Python heapq, C# PriorityQueue decreaseKey desteklemediği için pratikte bu kullanılır.
ÖnermeDijkstra, ağırlıklar negatif değilse en kısa yollar ağacını bulur. İkili yığınla süre E log V.

Neden negatif olmamalı? Bir düğüm kesinleştiğinde “daha kısa bir yol bulunamaz” varsayıyoruz: geri kalan bütün yollar daha uzun bir yerden başlıyor ve kenar eklemek yolu kısaltamaz. Negatif kenar bu varsayımı yıkar.

🎬 Ara: Dijkstra, kâğıt üzerinde

Dijkstra’s Algorithm
Computerphile (Mike Pound) · 10 dk 43 sn · YouTube’da aç

Az önceki gevşetme ve öncelik kuyruğu adımlarının küçük bir graf üzerinde elle, sırayla yapılışı. Hangi düğümün neden önce alındığını izleyin.

🤔 İzlerkenVideoda bir düğüm kuyruktan çıktıktan sonra mesafesi bir daha değişiyor mu? Neden? Negatif ağırlıklı bir kenar olsaydı bu güven nasıl bozulurdu?
📜 Yirmi dakikalık algoritma

1956’da Amsterdam’da genç Edsger Dijkstra, yeni bir bilgisayarın gücünü halka göstermek için bir problem arıyordu: “Rotterdam’dan Groningen’e en kısa yol”.

Kendi anlatımına göre nişanlısıyla alışverişteyken bir kafede oturdu ve algoritmayı kâğıt kalem olmadan, yaklaşık yirmi dakikada tasarladı. “Kâğıt kalemsiz tasarlamanın bir avantajı, kaçınılabilecek bütün karmaşıklıklardan kaçınmak zorunda kalmanızdır” dedi.

Makalesini 1959’da yayımladı — 3 sayfa. Bugün telefonunuzdaki harita uygulamasından oyunlardaki A*’a kadar her yerde onun izi var.

Quiz 2 · Dijkstra
Bu grafta kaynak s: s→a (2), s→b (5), b→a (−4). Dijkstra a’nın uzaklığını kaç bulur, doğrusu kaç?
Dijkstra önce a’yı (2) kesinleştirir — b’den (5) küçük. Sonra b’yi işler ve b→a ile 5 − 4 = 1 bulur ama a çoktan “kesin” ilan edilmişti. Negatif kenar yüzünden yanlış! (Tembel sürüm bu küçük örnekte a’yı yeniden güncelleyebilir ama genelde garantisi yoktur.) Negatif ağırlıklar için Bellman–Ford.
LEVEL 2
Oyunda yol bulma
arazi maliyeti, Dijkstra haritaları ve A*’a köprü
  • temeller ve gevşetme
  • Dijkstra
  • oyunda yol bulma
  • DAG’ler ve kritik yol
  • negatif ağırlıklar

🎮 Arazili harita: BFS vs Dijkstra

Koyu yeşil = bataklık (6), sarı = orman (3), gri = yol (0,5). Karenin maliyeti = oraya girmenin maliyeti. Algoritmayı BFS yapın: adım sayısı azalır ama maliyet artar. Fırçayla bataklık/yol çizip tekrar arayın.

🔗 Ayrıntısı: Y8 · A* (sezgiyle hızlandırılmış Dijkstra, oyun haritalarında) sunumunda.

🎮 Dijkstra haritası: bir hesap, yüz düşman

Kaynak olarak hedefi (oyuncuyu) al, Dijkstra’yı bütün haritaya yay. Her karede “oyuncuya maliyet” yazar.

  • Her düşman sadece: “komşularımdan sayısı en küçük olana git” → yol bulma bitti! 200 düşman = 1 Dijkstra.
  • Birden çok hedef (bütün can paketleri) = çok kaynaklı Dijkstra → “en yakın can paketine” harita.
  • Kaçış haritası: değerleri −1,2 ile çarp, bir kez daha yay → korkan düşmanlar köşeye değil, açık alana kaçar (Brogue’un ünlü hilesi).

RTS’lerde aynı fikrin vektör hâli: akış alanı flow field — Supreme Commander 2 gibi oyunlarda binlerce birim böyle yönlendirilir.

DeneyinÖnceki slayttaki demoda algoritmayı “Dijkstra haritası” yapın: her karede hedefe olan maliyet yazacak. Herhangi bir kareden sayıların azaldığı yönü takip edin: hep hedefe varırsınız.

🔗 Ayrıntısı: Y7 · Yönlendirme (akış alanlarıyla kalabalık hareket) sunumunda.

🔮 Köprü: Dijkstra’dan A*’a

  • Dijkstra hedefin nerede olduğunu bilmez: kaynak etrafında bir daire gibi her yöne yayılır.
  • A*: PQ önceliği = distTo[v] + h(v), h = “hedefe kalan tahmini mesafe” (ör. kuş uçuşu). Arama hedefe doğru eğilir, çok daha az kare açar.
  • h hiçbir zaman gerçeği aşmazsa A* yine en kısa yolu bulur. h = 0 ise A* = Dijkstra.
Sonraki bölüm: Oyun Yapay ZekâsıA*, navigasyon ağları (navmesh), yol düzeltme, hiyerarşik yol bulma, sürü davranışları, karar ağaçları… hepsi bu bölümde öğrendiğiniz graflar, öncelik kuyrukları ve hash tablolarının üstüne kurulu.

Red Blob Games’in A* rehberi (kaynaklarda) ileriye bakmak için mükemmel.

Quiz 3 · oyunda
Bir zombi oyununda 300 zombi aynı oyuncuyu kovalıyor. En verimli yol bulma yaklaşımı hangisi?
Hedef ortak olduğu için tek bir Dijkstra (oyuncu = kaynak) bütün zombilere yeter: 300 arama yerine 1. Oyuncu hareket ettikçe harita birkaç karede bir güncellenir. Roguelike’larda “Dijkstra map”, RTS’lerde “flow field” adıyla bilinir.
LEVEL 3
DAG’ler ve kritik yol
döngü yoksa topolojik sırayla tek geçiş
  • temeller ve gevşetme
  • Dijkstra
  • oyunda yol bulma
  • DAG’ler ve kritik yol
  • negatif ağırlıklar

DAG’de en kısa yol: topolojik sırayla gevşet

  • Düğümleri topolojik sırayla (Yönlü Graflar sunumu) ele al, her birinin oklarını gevşet
  • Bir düğüme sıra gelince ona gelen bütün oklar zaten gevşetilmiş → değeri kesin
  • E + V süre (Dijkstra’dan hızlı, PQ yok!)
  • Negatif ağırlıklarla da çalışır
  • En uzun yol: ağırlıkları eksi yap (ya da < yerine >). Genel graflarda imkânsız derecede zor olan problem, DAG’de kolay!

Elle izleme: nehirde sal yolculuğu

2637182Pınar0Değirmen2Orman5Köprü6Liman8

Sal yalnızca akıntı yönünde gider: geri dönüş yok, graf bir DAG. Sayılar saat. Topolojik sıra: Pınar, Değirmen, Orman, Köprü, Liman. Rozet = sonuçtaki uzaklık.

#sıradakioklarını gevşetdist[] (Pınar … Liman)
0——0, ∞, ∞, ∞, ∞
1Pınar→ Değirmen: 0 + 2 = 2 · → Orman: 0 + 6 = 60, 2, 6, ∞, ∞
2Değirmen→ Orman: 2 + 3 = 5 < 6 · → Köprü: 2 + 7 = 90, 2, 5, 9, ∞
3Orman→ Köprü: 5 + 1 = 6 < 9 · → Liman: 5 + 8 = 130, 2, 5, 6, 13
4Köprü→ Liman: 6 + 2 = 8 < 130, 2, 5, 6, 8
5Limanoku yok0, 2, 5, 6, 8

En kısa yol: Pınar → Değirmen → Orman → Köprü → Liman, 8 saat. Orman’dan Liman’a doğrudan ok 8 saat; Köprü üzerinden 1 + 2 = 3 saat.

Öncelik kuyruğu yok, bayat kayıt yok: her düğüme sıra geldiğinde ona gelen bütün oklar zaten gevşetilmiş. 7 ok, her biri bir kez. Ağırlıklardan biri eksi olsaydı da (ör. yolda hazine) yöntem aynen çalışırdı.

🎮 Kritik yol: boss savaşına en hızlı hazırlık

Her iş bir süre alıyor, bazıları başkalarını bekliyor; işçi sınırsız (paralel). En erken bitiş = başlangıçtan bitişe en uzun yol. “Paralel iş zamanlama” problemi; oyun stüdyolarında proje planlarında (ve RTS yapı sıralarında) aynısı.

Quiz 4 · DAG
Kritik yoldaki bir iş 2 saniye gecikirse ne olur? Kritik yolda olmayan bir iş 2 saniye gecikirse?
Toplam süre = en uzun zincir. Kritik yoldaki her iş bu zincirin parçası → gecikmesi aynen yansır. Diğer işlerin bir “bolluk” payı vardır; gecikme bu payı aşmadıkça toplam değişmez. Proje yöneticilerinin dikkat ettiği yer tam bu kırmızı zincir.
LEVEL 4
Negatif ağırlıklar
Bellman–Ford ve negatif döngüler
  • temeller ve gevşetme
  • Dijkstra
  • oyunda yol bulma
  • DAG’ler ve kritik yol
  • negatif ağırlıklar

Problem: eksi ağırlık ne demek, Dijkstra neden yanılır?

🎮 Geçince kazandıran yollar
  • Şimdiye kadar her kenar bir bedeldi: süre, mesafe, yakıt. Hepsi artı.
  • Bazı kenarlar kazandırır: içinden geçince can dolduran şifalı pınar, yokuş aşağı inerken dolan batarya, ödül veren ara görev.
  • “Bedel” yerine “bedel − kazanç” yazınca ağırlık eksi olabilir.
  • Soru aynı: A’dan B’ye toplamı en küçük yol hangisi?

Bir de en önemli kullanım var: döngü boyunca toplam eksiyse, o döngüde her tur kâr edilir. Oyun ekonomisindeki açıkları bulmanın yolu budur (birazdan).

Dijkstra’nın varsayımı çöker

Dijkstra kuyruktan çıkan düğüme “uzaklığı kesinleşti” der; çünkü daha uzun bir yoldan dolaşmak onu kısaltamaz. Eksi kenar varsa kısaltabilir.

kenarağırlık
0 → 14
0 → 25
2 → 1−3
  • Dijkstra: kuyrukta 1 (uzaklık 4) ve 2 (uzaklık 5). En küçük 1 → “1’in uzaklığı 4, kesin.”
  • Sonra 2 çıkar; 2 → 1 kenarı: 5 − 3 = 2. Ama 1 çoktan “kesin” sayıldı.
  • Doğru cevap 2; Dijkstra 4 dedi.

“Bütün ağırlıklara 3 ekleyip eksiyi yok edeyim” işe yaramaz: çok kenarlı yollar daha çok cezalanır, en kısa yol değişir.

Bellman–Ford

  • V − 1 tur boyunca, her turda bütün kenarları gevşet
  • Neden V − 1? En kısa yol en fazla V − 1 kenarlı; k. turdan sonra k kenarlı bütün yollar doğru
  • Negatif kenarlarla çalışır; süre E · V (yavaş!). Pratikte: sadece bir önceki turda değişen düğümlerin kenarlarını gevşet (kuyruklu sürüm)
  • V. turda hâlâ bir şey değişiyorsa → negatif döngü var: en kısa yol tanımsız (döngüde sonsuza kadar dönüp maliyeti −∞’a indirebilirsin)

📜 Richard Bellman (1958), Lester Ford Jr. (1956). Bellman “dinamik programlama”nın da babası.

Elle izleme: Bellman–Ford tur tur

Aynı üç kenar; kenarlar listede yazıldığı sırayla gevşetiliyor: 0 → 1 (4), 2 → 1 (−3), 0 → 2 (5). Kaynak 0.

  • Fikir: hangi düğümün “kesin” olduğuna karar vermeye çalışma. Bütün kenarları gevşet; sonra bir daha; bir daha…
  • Her tur, doğru bilgiyi bir kenar daha uzağa taşır. En kısa yol en çok V − 1 kenarlıdır: V − 1 tur yeter.
  • Ek veri yapısı yok: yalnızca dist[] dizisi ve kenar listesi. (Dijkstra’da öncelik kuyruğu vardı.)
  • Son bir kontrol turu: hâlâ kısalan bir kenar varsa, sonsuza kadar kısaltan bir eksi döngü var demektir.
dist[0], dist[1], dist[2]
turgevşetilen kenarhesapdist[]
başlangıç——0, ∞, ∞
10 → 1 (4)0 + 4 = 4 < ∞0, 4, ∞
12 → 1 (−3)∞ − 3: 2’ye henüz ulaşılmadı0, 4, ∞
10 → 2 (5)0 + 5 = 5 < ∞0, 4, 5
20 → 1 (4)değişmez0, 4, 5
22 → 1 (−3)5 − 3 = 2 < 40, 2, 5
20 → 2 (5)değişmez0, 2, 5
kontrolüç kenar dahiçbiri kısalmıyoreksi döngü yok ✔

1. turda 2 → 1 kenarı işe yaramadı, çünkü 2’nin uzaklığı henüz bilinmiyordu. 2. turda bilindi ve 1’in uzaklığı düzeldi: turların tekrarlanmasının nedeni bu. Maliyet: tur sayısı × kenar sayısı = (V − 1) · E.

Kur, arbitraj ve “neden logaritma?”

  • Kur = takas oranı. Tüccar “1 Altın verene 10 Gümüş veririm” diyorsa Altın → Gümüş kuru 10’dur. Geri dönüş kuru ayrıdır: 1 Gümüş → 0,09 Altın.
  • Arbitraj: bir tur takas yapıp başladığınız paraya daha fazlasıyla dönmek. Oyunda bu bir hatadır: oyuncu aynı turu yüz kez atıp sınırsız zengin olur.
  • Bir turun sonucu, yol üstündeki kurların çarpımıdır. Çarpım 1’den büyükse kâr var.
  • Sorun: en kısa yol algoritmaları toplar, çarpmaz.
  • Logaritma çarpmayı toplamaya çevirir: ln(a · b) = ln a + ln b. (ln x: “2,718’in kaçıncı kuvveti x eder?” 1’den büyük sayılarda artı, küçüklerde eksi, ln 1 = 0.)
  • Kenar ağırlığı olarak −ln(kur) yazarsak: çarpım > 1 ⇔ ln’lerin toplamı > 0 ⇔ −ln’lerin toplamı < 0. Yani kârlı tur = eksi döngü; onu da Bellman–Ford’un kontrol turu bulur.
Elle hesap: Altın → Gümüş → Mücevher → Altın
takaskureldeln(kur)ağırlık = −ln(kur)
başlangıç—1 Altın——
Altın → Gümüş1010 Gümüş2,303−2,303
Gümüş → Mücevher0,252,5 Mücevher−1,386+1,386
Mücevher → Altın0,431,075 Altın−0,844+0,844
turçarpım 1,075%7,5 kârtoplam +0,073toplam −0,073

Kontrol: e0,073 = 1,075 ✓. Öbür turlar zararda: Altın → Gümüş → Altın = 10 · 0,09 = 0,90; Altın → Kürk → Altın = 2 · 0,48 = 0,96.

Aynı numara her “çarparak birleşen” ölçüde işe yarar: art arda isabet olasılıkları, hasar çarpanları, güvenilirlik. Çarpımı en büyük yol = −ln toplamı en küçük yol.

🧭 DEMOYU OKUMA KILAVUZU (bir sonraki slayt)
  • Düğümler dört para birimi; okların üstündeki sayı kur: “okun başındaki paradan 1 verirsen ucundakinden bu kadar alırsın”.
  • Algoritma kurlarla değil −ln(kur) ağırlıklarıyla çalışır; sağdaki tabloda distTo[] bu ağırlıkların toplamıdır (Altın’dan o paraya en “ucuz” takas zinciri). Mor rozetler aynı sayılar.
  • “İleri ▶|” ile adım adım: mavi kenar az önce gevşedi. Üç tur (V − 1 = 3) sonunda tablo oturmuş olmalıydı.
  • 4. tur kontrol turudur: bir kenar hâlâ gevşiyor → kırmızı döngü belirir: Altın → Gümüş → Mücevher → Altın, çarpım 1,075.
  • Soru: tüccarlardan birinin kurunu değiştirerek açığı kapatın. Mücevher → Altın kuru en çok kaç olabilir? (10 · 0,25 · k ≤ 1 → k ≤ 0,40.)

💰 Oyun ekonomisinde arbitraj = negatif döngü

  • Düğümler dört para birimi; okların üstündeki sayı kur: “okun başındaki paradan 1 verirsen ucundakinden bu kadar alırsın”.
  • Algoritma kurlarla değil −ln(kur) ağırlıklarıyla çalışır; sağdaki tabloda distTo[] bu ağırlıkların toplamıdır (Altın’dan o paraya en “ucuz” takas zinciri). Mor rozetler aynı sayılar.
  • “İleri ▶|” ile adım adım: mavi kenar az önce gevşedi. Üç tur (V − 1 = 3) sonunda tablo oturmuş olmalıydı.
  • 4. tur kontrol turudur: bir kenar hâlâ gevşiyor → kırmızı döngü belirir: Altın → Gümüş → Mücevher → Altın, çarpım 1,075.
  • Soru: tüccarlardan birinin kurunu değiştirerek açığı kapatın. Mücevher → Altın kuru en çok kaç olabilir? (10 · 0,25 · k ≤ 1 → k ≤ 0,40.)

NPC tüccarlarının takas oranları. Bir döngüde kurların çarpımı 1’den büyükse oyuncu o turu tekrar tekrar atıp bedava altın basar. Bellman–Ford’un kontrol turu bu döngüyü bulur; siz de yayımlamadan önce kurları düzeltirsiniz.

Quiz 5 · negatif
Bellman–Ford V − 1 tur sonunda bir tur daha yapıyor ve bir kenar hâlâ gevşiyor. Bu ne demektir?
Negatif döngü yoksa her en kısa yol en fazla V − 1 kenarlıdır ve V − 1 tur yeter. V. turda iyileşme olması, kenar sayısı arttıkça maliyetin azalmaya devam ettiğini, yani bir negatif döngü olduğunu gösterir. Oyun ekonomisinde: sonsuz para açığı!

🧪 Kod laboratuvarı: Dijkstra

TODO’yu doldurun (3 satır). Sonra if (d > dist[v]) continue; satırını silin: sonuç değişiyor mu? Hız? (Doğru kalır ama bayat kayıtlar boşuna işlenir.)

🐍 Kod laboratuvarı — Dijkstra (Python)

Bu kod gevşetmeyi unutmuş: her komşunun uzaklığını koşulsuz eziyor — döngülü graflarda PQ hiç boşalmaz! Gevşetme koşulunu ekleyin; sonra bayat kayıtları atlayan satırı da ekleyin.

Derin hikâye: Shakey ve A*’ın doğuşu (1968)

  • 1966–1972: Stanford Araştırma Enstitüsü’nde (SRI) geliştirilen Shakey, kendi eylemleri hakkında akıl yürüten ilk mobil robot olarak anılır: kamera ve mesafe sensörleriyle odaları algılıyor, kutuları itiyor, rampalardan geçiyordu.
  • Shakey’in odalar arasında yol bulması gerekiyordu. Dijkstra’nın algoritması (1959) doğruydu ama hedefin nerede olduğunu hiç kullanmadan her yöne eşit yayılıyordu.
  • Peter Hart, Nils Nilsson ve Bertram Raphael, 1968’de hedefe olan tahmini uzaklığı (sezgisel) aramaya ekleyen A*’ı yayımladı ve sezgisel “gerçek uzaklığı hiç aşmadığı” sürece en kısa yolu bulacağını ispatladı.
  • Shakey bugün Bilgisayar Tarihi Müzesi’nde sergileniyor; A* ise neredeyse her oyunun yol bulucusunun kalbinde (Y8).
DersEn kısa yol algoritmalarının en ünlü uygulaması bir robottu; oyunlar bu mirası devraldı. Dijkstra “herkese en kısa yol”, A* “tek bir hedefe en kısa yol, akıllıca”: doğru soruyu sormak doğru algoritmayı seçtirir.

Kaynak: Wikipedia: Shakey the robot · CACM: Dijkstra röportajı (2001)

🧰 Kütüphaneler ve araçlar

adplatformne yapar / sınırlarınasıl eklenir
NetworkXPythondijkstra_path, bellman_ford_path, astar_path, all_pairs…pip install networkx
scipy.sparse.csgraph.shortest_pathPythonDijkstra, Bellman–Ford, Johnson, Floyd–Warshall; seyrek matrislerde hızlı.pip install scipy
Unity NavMesh (AI Navigation)UnityNavmesh üzerinde A* + funnel; NavMesh.CalculatePath, NavMeshAgent (Y9).Package Manager: AI Navigation
A* Pathfinding ProjectUnityIzgara, navmesh ve nokta grafları; çok iş parçacıklı arama, etiketler ve cezalar (Y8, Y12).Asset Store
PathFinding.jsJavaScriptIzgara üzerinde A*, Dijkstra, JPS ve diğerleri; görsel demo.npm install pathfinding

🧩 Hangi algoritma, ne zaman?

  • Tek hedef, iyi bir sezgisel var → A* (oyunların %90’ı).
  • Bir noktadan herkese (ör. bir kuleden bütün hücrelere uzaklık, akış alanı) → Dijkstra / BFS.
  • Negatif ağırlık (ödül veren kenarlar, döviz kurları) → Bellman–Ford; negatif döngü = sonsuz kazanç (arbitraj).
  • Herkesten herkese, küçük graf (ör. 50 şehirlik dünya haritası) → Floyd–Warshall, bir kez hesaplanıp saklanır.
  • Hareketli engeller → yeniden arama ya da artımlı algoritmalar (D* Lite); çoğu oyunda kısa aralıklarla yeniden A* yeterli.
Sık hatalar
  • Negatif kenarla Dijkstra.
  • Düğümü kuyruğa eklerken kapatmak (Dijkstra’da yanlış; çıkarırken kapatın).
  • Gerçek maliyeti aşan (kabul edilemez) sezgisel.
  • Kuyrukta bayat kayıtları atlamamak.

🤖 Bu konuyu bir YZ kod asistanıyla yazarken

Sık yapılan hatalar — kontrol edin
  • Negatif kenarla Dijkstra
  • Düğümü eklerken kapatmak
  • Kabul edilemez sezgisel
  • Bayat kuyruk kayıtlarını işlemek
İyi bir istek (prompt) örneği

“Unity 6, C#. 8 yönlü ızgara A* yaz: düz adım 1, çapraz √2; köşe kesmeyi engelle; sezgisel octile; eşit f’de daha küçük h’yi tercih et; açık liste için kendi ikili yığının; kapalı küme bool[]; sonuç: yol + açılan düğüm sayısı. Ayrıca aynı API ile Dijkstra (sezgisel 0) ve BFS; üçünün aynı haritada aynı uzunlukta yol bulduğunu doğrulayan NUnit testleri.”

  • Kenar ağırlıklarının negatif olup olamayacağını yazın
  • Sezgiselin kabul edilebilirliğini açıklatın
  • Eşitlik bozma (tie-breaking) kuralı isteyin
  • Yolun yanında “açılan düğüm sayısı”nı da döndürsün

🚀 Proje ve araştırma önerileri

  1. [kolay] Metro haritası — Bir şehrin metro hatlarında en kısa ve en az aktarmalı rotalar.
  2. [orta] En güvenli yol — Kenar başına “güvenli geçme olasılığı” verin; −log(olasılık) ağırlıklarıyla en güvenli yolu Dijkstra ile bulun.
  3. [orta] Kule savunma uzaklık alanı — Hedeften bütün hücrelere Dijkstra ile uzaklık; düşmanlar alanın eğimini izlesin.
  4. [araştırma] Hızlandırma teknikleri — ALT (yer imli A*) ya da kontraksiyon hiyerarşilerini küçük bir yol ağında deneyin.

📄 Akademik okumalar ve kaynaklar

Dijkstra 1959 · A Note on Two Problems in Connexion with Graphs (Numerische Mathematik 1)
Dijkstra algoritması (ve Prim’in yeniden keşfi).
Hart, Nilsson & Raphael 1968 · A Formal Basis for the Heuristic Determination of Minimum Cost Paths (IEEE Trans. Systems Science and Cybernetics 4(2))
A*.
Bellman 1958 · On a Routing Problem (Quarterly of Applied Mathematics 16)
Bellman–Ford.

Neler öğrendik? 🎒

algoritmakısıttipik süreen kötü🎮 oyunda
BFSağırlıklar eşitE + VE + Vkaro haritada adım
Dijkstra (ikili yığın)ağırlıklar ≥ 0E log VE log Varazili yol bulma, Dijkstra haritası
topolojik sıraDAGE + VE + Vkritik yol, yapı sırası
Bellman–Ford (kuyruklu)negatif döngü yokE + VE · Vekonomi arbitraj kontrolü

Hepsi aynı hamleyi (gevşetme) farklı sıralarda yapıyor.

🏁 Algoritmalar bölümünün sonu

18 sunumda neler topladınız:

  • Analiz: büyüme hızları, ölçme, kare bütçesi
  • Temel yapılar: dizi, bağlı liste, yığın, kuyruk, Union–Find
  • Sıralama & arama: ikili arama, 7 sıralama algoritması
  • Sembol tabloları: BST, dengeli ağaçlar, kd-ağaçları, hash
  • Öncelik kuyrukları: ikili yığın
  • Graflar: DFS, BFS, topolojik sıra, MST, en kısa yollar
🎮 Sıradaki bölüm: Oyun Yapay ZekâsıA* ve navigasyon ağları, sonlu durum makineleri ve davranış ağaçları (Yönlü Graflar + Ağaçlar!), minimax ve oyun ağaçları, Monte Carlo arama, sürü davranışları, etki haritaları… Her biri bu bölümde öğrendiğiniz bir veri yapısının üstüne kurulu.

Alıştırmalar 🏋️

  1. Kâğıt-kalem: tinyEWD’de 0’dan Dijkstra iz tablosunu çıkarın; sonuçları demo ile karşılaştırın.
  2. Karo haritada 8 yönlü harekete izin verin; çapraz adımın maliyeti √2. Dijkstra’nın yolu nasıl değişir?
  3. p5.js’te bir Dijkstra haritası yapın: fare = hedef; 100 “zombi” her karede en küçük komşuya gitsin.
  4. “s’den t’ye en kısa yol” için Dijkstra’yı t kesinleşince durdurun. Ortalama kaç kare açılıyor? Sonra kuş uçuşu mesafeyi önceliğe ekleyin (ilk A*’ınız!) ve tekrar sayın.
  5. Kendi oyununuzdaki bir “üretim zinciri” için DAG çizip kritik yolu bulun.
  6. 🤖 Bir YZ asistanından “Unity’de ızgarada Dijkstra” isteyin. PQ olarak ne kullandı? List.Sort ise her adımda N log N — neden kötü?

🎮 Bu sunumdaki oyunlar

Adı geçen oyunu tanımıyorsanız: oyuncuların kullandığı wiki sayfası ve oyunu kısaca gösteren bir video. ▶ video slaydın üstünde açılır (Esc ile kapanır); 🎯 işaretli bağlantılar doğrudan bu sunumdaki konuya gider.

Supreme Commander 2 2010 · gerçek zamanlı strateji
Yüzlerce birimin aynı anda savaştığı büyük ölçekli strateji; birimleri akış alanlarıyla yürür.

Kaynaklar: videolar 🎬

Kaynaklar: okuma 📚

BÖLÜM TAMAMLANDI 🏆
Sırada: Oyun Yapay Zekâsı
A*, navmesh, davranış ağaçları, minimax… Bu bölümdeki her yapı orada iş başında.
DERS HARİTASI ▶