21  Problem Oturumu 6

Ders 16-19’un uygulaması: beş ağırlıklı en kısa yol problemi indirgemeyle Dijkstra/BFS’e iner — negatif kenarın kırdığı dondurma, Johnson ile ağırlıklı yarıçap, süpernode artı ikili arama, durum makinesi ile graf çoğaltma, darboğaz için modifiye gevşetme

NotOturum bilgisi

21.1 Bu Problem Oturumu Ne Hakkında?

Altıncı problem oturumu (Justin Solomon) ağırlıklı en kısa yollar üzerine beş problemi işler (Şekil 33.1): Dijkstra’yı elle çalıştırmak, tüm-çiftler en kısa yol (Johnson) ve birkaç “kılık değiştirmiş” en kısa yol problemi. Tema yine indirgeme: problem çoğu zaman doğrudan Dijkstra değil, ama süpernode, graf çoğaltma, ikili arama veya modifiye gevşetme ile Dijkstra/BFS’e iner.

“if there’s an obvious algorithm staring us in the phase to solve a given algorithms problem, we should try that first before we try something more clever.” — Solomon, 15:01

Her problem “İfade → Yaklaşım → Çözüm → Karmaşıklık” akışıyla işlenir.

flowchart TD
    R["Problem Oturumu 6<br/>(Ders 16-19 uygulaması)"] --> P1["Problem 1<br/>Dijkstra elle + negatif kenar<br/>(dondurma varsayımı kırılır)"]
    R --> P2["Problem 2<br/>Ağırlıklı yarıçap<br/>(Johnson + tanımı uygula)"]
    R --> P3["Problem 3<br/>Sensörlerden uzak dur<br/>(süpernode + ikili arama)"]
    R --> P4["Problem 4<br/>Küre kapasitesi<br/>(durum makinesi / çoğaltma)"]
    R --> P5["Problem 5<br/>Nakliye darboğazı<br/>(modifiye gevşetme)"]
    CORE["Ortak tema:<br/>zor görünen ağırlıklı problemi<br/>DOĞRU İNDİRGEMEYLE<br/>Dijkstra/BFS'e indir"]
    CORE -.-> P1
    CORE -.-> P2
    CORE -.-> P3
    CORE -.-> P4
    CORE -.-> P5

    classDef root fill:#fef3c7,stroke:#b45309,stroke-width:3px,color:#1f2937
    classDef prob fill:#f3f4f6,stroke:#374151,stroke-width:2px,color:#1f2937
    classDef core fill:#fcd34d,stroke:#b45309,stroke-width:2px,color:#1f2937
    class R root
    class P1,P2,P3,P4,P5 prob
    class CORE core
Şekil 21.1: Problem Oturumu 6’nın kavram haritası: kök (PS6) beş probleme dallanır ve ortadaki ortak tema düğümü beşini birden yönlendirir. Problem 1 Dijkstra’yı elle çalıştırır, sonra negatif bir kenarın dondurma varsayımını nasıl kırdığını gösterir; Problem 2 ağırlıklı yarıçabı Johnson algoritmasını kara kutu olarak çağırıp tanımı doğrudan koda dökerek çözer; Problem 3 sensör problemini bir süpernode artı cevap-üzerinde ikili aramaya indirir; Problem 4 küre kapasitesini durum makinesine çevirip çizgeyi kapasite katmanlarına çoğaltır; Problem 5 darboğaz yolunu toplama yerine min/maks ile gevşeten modifiye bir Dijkstra ile bulur. Ortak tema — zor görünen ağırlıklı problemi doğru indirgemeyle Dijkstra veya BFS’e çevir — Solomon’un her probleme aynı kapıdan girmesini sağlar.
İpucuYaklaşım — ortak strateji: önce bariz olanı dene, sonra indirgemeyi ara

Beş problemin tamamı aynı refleksle başlar: önce “asıl ne soruluyor” ve “hangi sabitler verildi” diye metni soy; eğer ortada bariz bir algoritma (doğrudan Dijkstra, tanımı uygula) varsa onu dene. Bariz değilse problemi bildiğin bir araca indirge: süpernode (çok hedef → tek kaynak), graf çoğaltma (konum + durum → katman), cevap-üzerinde ikili arama (log n bütçe → eşik ara) veya modifiye gevşetme (üçgen-eşitsizliği analoğu her güncelleme formülü Dijkstra iskeletine takılır). Bu oturum, ağırlıklı en kısa yol kasını bu beş indirgemeyle çalıştırır.

21.2 Problem 1: Dijkstra Elle ve Negatif Kenarın Kırdığı Varsayım

İfade. (a) Verilen pozitif-ağırlıklı çizgede \(s\)’den Dijkstra’yı çalıştır (mesafeler + işlem sırası). (b) Bir kenarın ağırlığını negatif yap; Dijkstra çalıştırılırsa ne kırılır?

İpucuYaklaşım — dondurma varsayımı: işlenen düğüme bir daha dokunma

Dijkstra her adımda en yakın işlenmemiş düğümü çeker, komşularını üçgen eşitsizliğiyle günceller. Kilit özellik: bir düğüm işlenince (kesinleştirilince) dondurulur — bir daha dokunulmaz. Bu açgözlü doğruluk, ağırlıkların negatif-olmamasına dayanır: ileride keşfedilen hiçbir yol, çoktan kesinleşmiş bir düğümü kısaltamaz. Negatif bir kenar bu garantiyi yok eder; çözümü görmek için tek negatif kenarlı çizgeyi elle adım adım çalıştırmak yeterlidir.

“once I visit a vertex, I never touch it again. It gets frozen in time.” — Solomon, 4:49

Çözüm.

(a) Pozitif ağırlıklarla Dijkstra. Kaynaktan başla, en yakın işlenmemiş düğümü çek, kenarlarını gevşet, dondur; sırayla tüm düğümler kesinleşir. Çıkarılma sırası mesafeye göre artar (Ders 19 Gözlem 1’in sonucu: ağırlık ≥ 0 → mesafe en kısa yol boyunca artar).

(b) Negatif kenar dondurmayı kırar. Çizgeye bir negatif kenar (örneğimizde \(b \to c\) ağırlık \(-8\)) eklenince, \(b\) işlendiğinde \(b \to c\) üzerinden \(9 + (-8) = 1 < 3\) bulunur — yani \(c\)’ye daha kısa bir yol keşfedilir, ama \(c\) çoktan dondurulmuştur. Dijkstra’nın “işlenen düğüme bir daha dokunma” varsayımı kırılır; \(c\)’yi kuyruğa geri eklemek gerekir ama Dijkstra buna izin vermez. (Bu örnekte ek olarak \(b \to c \to d \to b = -8 + 2 + 5 = -1\) negatif bir çevrim oluşur, bu yüzden çevrime erişilen her düğüm Bellman-Ford’da eksi sonsuz olur.)

def dijkstra_vs_bf(adj, weight, s):              # dondurma davranışını izle
    d = {v: INF for v in adj}; d[s] = 0
    Q = ChangeablePQ((v, d[v]) for v in adj)
    done = set(); violations = []
    while len(Q):
        u, _ = Q.delete_min()
        done.add(u)                              # DONDUR
        for v in adj[u]:
            cand = d[u] + weight[(u, v)]
            if v in done:                        # donmuş düğüme daha kısa yol!
                if cand < d[v]:
                    violations.append((u, v, cand, d[v]))
                continue                         # Dijkstra DOKUNMAZ (varsayım)
            if cand < d[v]:
                d[v] = cand; Q.decrease_key(v, d[v])
    return d, bellman_ford_classic(adj, weight, s), ..., violations

“that breaks our assumption, which is that as soon as I visit a vertex, I never have to touch it again.” — Solomon, 10:59

Şekil 21.2 bu çöküşü motordan gerçek verilerle gösterir: örnek çizgeye \(b \to c\,(-8)\) kenarı eklenir; donmuş davranışı taklit eden Dijkstra hâlâ \(\{s{:}0,\,a{:}7,\,b{:}9,\,c{:}3,\,d{:}5\}\) (negatif kenarı yok sayan, yanlış sonuç) verirken, ihlal listesi tam olarak \([(b, c, 1, 3)]\)’tür — \(b\) işlenince \(9 + (-8) = 1 < 3 = d[c]\) keşfedilir ama \(c\) donmuştur. Bellman-Ford ise negatif çevrimi yakalar: \(s\) hariç tüm düğümler eksi sonsuza düşer.

Karmaşıklık. (a) standart Dijkstra. (b) negatif kenar → Dijkstra geçersiz; Bellman-Ford gerekir (Ders 18).

Şekil 21.2: Negatif kenar dondurmayı KIRAR — Problem 1 İMZA. Örnek çizgeye b→c(−8) eklenir (motordan GERÇEK). SOL: çizge (D19 yerleşimi); b→c kenarı kalın amber kesikli; Dijkstra işleme sıra rozetleri #1..#5; c düğümü ‘d[c]=3’te DONDURULDU (#2)’ kilit ikonu; b işlenince (#5) b→c üzerinden 9+(−8)=1 < 3 keşfi → ihlal okunda YASAK işareti (donmuş düğüme dokunulamaz, Solomon 4:49); negatif çevrim notu b→c→d→b = −1. SAĞ: düğüm / Dijkstra / Bellman-Ford tablosu (motor değerleri BİREBİR) — Dijkstra {s:0,a:7,b:9,c:3,d:5} (negatif kenarı ihmal etti, YANLIŞ), Bellman-Ford s hariç hepsi ‘eksi sonsuz’ (negatif çevrim yakalandı); fark hücreleri amber. Alt not: tek negatif kenar hem dondurma ihlali hem negatif çevrim doğurur; çözüm Bellman-Ford (Ders 18).

21.3 Problem 2: Ağırlıklı Yarıçap ve Johnson

İfade. Ağırlıklı yönlü çizge (negatif ağırlık olabilir, negatif çevrim yok). Ağırlıklı eksantriklik \(\varepsilon(u) = \max_v \delta(u, v)\); ağırlıklı yarıçap \(= \min_u \varepsilon(u)\). Yarıçapı \(O(V^3)\)’te bul.

İpucuYaklaşım — akıllı olma, tanımı doğrudan algoritmaya çevir

Bu, Ders 17 (PS5)’teki yarıçap probleminin ağırlıklı versiyonudur. Burada hile aramaya gerek yok: tanımı doğrudan algoritmaya dök. Eksantriklik için tüm-çiftler mesafe gerekir; bunu Johnson algoritması verir (Ders 21’de açılacak; negatif çevrim olmadığından çalışır). Johnson’ı bir kara kutu olarak çağır, sonra iç içe döngüyle eksantriklikleri ve minimumlarını topla. Karmaşıklık bütçesi \(O(V^3)\) bu naif yaklaşımı zaten rahatça karşılar.

“that’s called Johnson’s algorithm.” — Solomon, 15:49

Çözüm. Üç adım, doğrudan tanımdan:

  1. Johnson ile tüm \(\delta(u, v)\) çiftlerini hesapla — \(O(V \cdot E + V^2 \log V) \le O(V^3)\) (basit çizgede \(E \le 2V^2\)).
  2. Her \(u\) için iç içe döngüyle \(\varepsilon(u) = \max_v \delta(u, v)\)\(O(V^2)\).
  3. \(\min_u \varepsilon(u)\)\(O(V)\).

İlk terim baskındır, dolayısıyla toplam \(O(V^3)\) olur ve problem bütçesiyle uyumludur.

def weighted_radius(adj, weight):                # O(V³) — tanımı uygula
    delta = johnson(adj, weight)                 # tüm-çiftler δ (kara kutu)
    if delta is None:
        return None, None                        # negatif çevrim → tanımsız
    best, center = None, None
    for u in adj:                                # her u: ε(u) = maks δ
        ecc = max(delta[u][v] for v in adj)
        if best is None or ecc < best:           # R = min_u ε(u)
            best, center = ecc, u
    return best, center

Johnson burada kara kutudur — içinde süpernode + Bellman-Ford potansiyeli ile kenarları negatif-olmayana yeniden ağırlıklandırıp \(V\) kez Dijkstra çalıştırır, ama bu problem için önemli olan tek şey çıktısının tüm-çiftler mesafe tablosu olduğudur. Motor üzerinde bir doğrulama: rastgele üretilen 30 negatif-çevrimsiz çizgede weighted_radius (Johnson tabanlı) ile her düğümden Bellman-Ford koşan bağımsız bir \(V \times \text{BF}\) tanığı birebir aynı yarıçapı verir — yani indirgemenin doğruluğu farklı bir mekanizmayla teyit edilir.

Karmaşıklık. \(O(V^3)\) — yalnızca “tanımı uygula” ile, hiçbir akıllı numara olmadan.

21.4 Problem 3: Atniss ve Sensörler — Süpernode ve İkili Arama

İfade. \(n\) kavşaklı boru ağı, her kavşak derecesi \(\le 4\) (pozitif uzunluklu borular), bazı kavşaklarda hareket sensörü. Atniss, \(s\)’den \(t\)’ye giderken herhangi sensöre olan minimum uzaklığı en büyük tutan yolu ister; \(O(n \log n)\)’de.

İpucuYaklaşım — kılık değiştirmiş erişilebilirlik: iki katman + cevap-üzerinde ikili arama

Bu doğrudan en kısa yol değil; kılık değiştirmiş bir erişilebilirlik problemidir. İki katmana ayır: (i) her kavşağın en yakın sensöre uzaklığını bul, (ii) “en az \(k\) uzakta kalarak \(s \to t\) gidilir mi?” sorusunu \(k\) üzerinde ikili arama ile çöz. İkinci katmanın ipucu sınıfta yalnız bir algoritmanın \(\log n\) sürede koştuğudur: ikili arama. Yanıt monoton (büyük \(k\) geçilebilir ise küçük \(k\) de geçilir) olduğundan, eşiği sıralı bir dizi indeksinde aramak güvenlidir.

“it’s sort of a readability problem in disguise.” — Solomon, 24:16

Çözüm. Üç adımda:

  1. Süpernode \(x\) ekle, tüm sensörlere 0-ağırlıklı kenarla bağla; \(x\)’ten Dijkstra → her kavşağın en yakın sensör mesafesi (\(O(n \log n)\)).

“add a new vertex… and make that vertex distance 0 to every one of my sensors.” — Solomon, 31:10

  1. \(G_k\) = sensör-mesafesi \(> k\) olan kavşakların alt-çizgesi; \(G_k\)’da BFS, “\(k\) yarıçapı dışında \(s \to t\) var mı?” sorusunu \(O(n)\)’de yanıtlar.
  2. En büyük \(k^\star\)’yı bul: kavşakları sensör-mesafesine göre sırala (\(O(n \log n)\)), dizi indeksi üzerinde ikili arama (\(\log n\) adım \(\times\ O(n)\) BFS).

“we only have one algorithm that runs in log n time in this class, which is binary search.” — Solomon, 41:44

def max_min_sensor_dist(adj, weight, sensors, s, t):    # O(n log n)
    sd = nearest_sensor_dist(adj, weight, sensors)      # 1. süpernode Dijkstra
    cands = sorted(set(sd.values()))                    # eşik adayları (sıralı)
    lo, hi, best = 0, len(cands) - 1, None
    while lo <= hi:                                      # 3. indeks üzerinde ikili arama
        mid = (lo + hi) // 2; k = cands[mid]
        if survives_threshold(adj, sd, s, t, k - 1):    # 2. G_k'da BFS
            best = k; lo = mid + 1
        else:
            hi = mid - 1
    return best

İndirgemenin doğruluğunu küçük bir çizgede bağımsız bir tanık teyit eder: tüm basit yolları DFS ile gezip her yolun minimum sensör-mesafesini alan, sonra bunların maksimumunu döndüren kaba-kuvvet, ikili aramanın bulduğu \(k^\star\) ile aynı değeri verir.

Karmaşıklık. Dijkstra \(O(n \log n)\) + ikili arama \(\log n \times O(n)\) = \(O(n \log n)\).

21.5 Problem 4: Ashley ve Critter’lar — Graf Çoğaltma ve Durum Makinesi

İfade. \(n\) açıklık, her açıklık derecesi \(\le 5\); her patika (uzunluk \(l_t\), üzerinde \(c_t\) critter). Yürüyen kişi her patikadaki tüm critter’ları toplamak zorunda; \(k\) küre kapasitesi var, mağazalarda boşaltır. Küre yetmezse “üzülür”. Üzülmeden en kısa yol; bütçe \(O(nk \log nk)\).

İpucuYaklaşım — durum makinesi: konuma ‘kalan kapasite’ durumunu ekle, çizgeyi katmanla

Klasik durum makinesi / graf çoğaltma: konuma ek olarak “kalan kapasite” durumunu izle. Her fiziksel açıklığı \(k+1\) kopyaya çoğalt — her kopya “kaç boş küre kaldı” bilgisini taşır. Bir critter patikası kapasiteyi tüketir; mağaza tam doldurur. Yeterli boş küre olmadan bir patikaya girilemez (o kenar yoktur), bu yüzden “üzülme” durumu otomatik olarak modelin dışında kalır. Bu çoğaltılmış çizgede Dijkstra, hem konumu hem kapasiteyi takip ederek doğru cevabı verir.

“it’s kind of like a state machine.” — Solomon, 56:42

Çözüm. Her açıklığın \(k+1\) kopyası: \(v_{c,i}\) = “açıklık \(c\), \(i\) boş küre”. Kenarlar (her \((a, b)\) patikası, \(c\) critter):

  • Mağaza yoksa: \(v_{a,i} \to v_{b,i-c}\) (\(i \ge c\) gereği — yoksa üzülür);
  • Mağaza varsa: \(v_{a,i} \to v_{b,k-c}\) (önce boşalt, sonra topla).

Burada \(V = O(kn)\) ve \(E = O(kn)\). Dijkstra’yı \(v_{s,k}\)’dan çalıştır; hedef herhangi \(v_{t,i}\). Sonuç \(\infty\) ise “üzüntü kaçınılmaz”. (Bu çizge DAG değil — iki mağaza arası ileri-geri bedava çevrim olabilir, bu yüzden DAG relaxation değil Dijkstra gerekir.)

def shortest_no_sadness(paths, stores, k, s, t):        # O(nk log nk)
    adj, weight = build_capacity_graph(paths, stores, k)  # k+1 kapasite katmanı
    d = dijkstra(adj, weight, (s, k))                   # tam küre ile başla
    return min(d[(t, i)] for i in range(k + 1))         # herhangi (t,i) min; ∞ = üzüntü

Şekil 21.3 bu çoğaltmayı motordan gerçek bir küçük örnekle gösterir: \(s \xrightarrow{l=2,\,c=2} m \xrightarrow{l=3,\,c=1} t\), mağaza \(m\), kapasite \(k=2\). Katmanlı çizgede tek geçerli yol \((s, 2) \to (m, 0) \to (t, 1)\) ağırlık \(2 + 3 = 5\)’tir; \(m\) mağazalı olduğu için çıkışta küre tam dolar (\(k - c = 2 - 1 = 1\)). Kapasite \(k=1\)’e düşürülünce \(s \to m\) patikası \(c = 2\) critter ister ama maksimum \(i = 1 < 2\) olduğundan o kenar hiç oluşmaz → sonuç \(\infty\) = üzüntü kaçınılmaz.

Karmaşıklık. Dijkstra, \(O(kn)\) boyutlu çizgede → \(O(nk \log nk)\).

Şekil 21.3: Durum makinesi — konum + kalan küre = düğüm; çizgeyi k+1 katmana çoğalt — Problem 4 İMZA. Üç panel (motordan GERÇEK: paths=[(s,m,2,2),(m,t,3,1)], stores={m}). ① FİZİKSEL HAT: s –[ℓ=2, 2 critter]– m(MAĞAZA ikonu) –[ℓ=3, 1 critter]– t. ② KATMANLI ÇİZGE (k=2): 3 sütun (s/m/t) × 3 satır (boş küre i=2/1/0); aktif en kısa yol amber (s,2)→(m,0) w=2 (2 critter toplandı), m MAĞAZALI çıkışta boşalt (m,0)→(t,1) w=3; geçersiz örnek (s,1)→m YOK (i=1 < c=2 → uyulur); yol toplam (s,2)→(m,0)→(t,1) = 2+3 = 5 rozeti. ③ k=1 PANEL: hiçbir s→m kenarı yok (patika 2 critter ister, maks i=1) → δ(s→t)=+∞ üzüntü kaçınılmaz. Alt not: Solomon 56:42, V=O(nk), Dijkstra O(nk log nk).

21.6 Problem 5: Nakliye ve Darboğaz — Modifiye Dijkstra

İfade. \(n\) kamyon rotası (kaynak, hedef, maks ağırlık \(w_i\), maliyet \(c_i\)); yönlü. (1) Gönderilebilen en ağır server \(w^\star\), (2) o ağırlığı en az maliyetle taşıma. (\(\le 3\sqrt{n}\) şehir.)

İpucuYaklaşım — darboğaz dünyasının üçgen eşitsizliği: modifiye gevşetme + iki aşama

Bir yolun darboğazı (bottleneck) = yoldaki minimum kenar ağırlığıdır; \(B(s, t)\) = tüm \(\pi\) yolları üzerinde darboğazın maksimumu (\(\max_\pi\)). Anahtar gözlem bir eşitsizliktir: \(B(s, t) \ge \min(B(s, v),\ w(v, t))\), bir \(v^\star\) için eşitlikle — bu, darboğaz dünyasının üçgen eşitsizliğidir. Üçgen-eşitsizliği analoğu olan her güncelleme formülü Dijkstra iskeletine takılabilir: toplama yerine min, en küçüğü kesinleştirme yerine en büyüğü kesinleştirme. Sonra \(w^\star\) bilinince problem ikinci aşamada sıradan bir maliyet-Dijkstra’ya iner.

“the bottleneck of pi is going to be the minimum edge weight of any edge in pi.” — Solomon, 1:12:24

Çözüm.

(1) En ağır \(w^\star\). Darboğaz eşitsizliği, Dijkstra’nın güncelleme formülünün analoğudur: toplama yerine min/maks ile gevşet — gelen komşular arasında en büyük darboğazı seç. Modifiye Dijkstra \(w^\star\)’ı verir.

“rather than updating by summing edge lengths, we update by using this formula.” — Solomon, 1:26:05

(2) En az maliyet. \(w^\star\) bilinince, yalnız \(w^\star\) taşıyabilen rotaları tut; kenar ağırlığı = maliyet olan bir çizgede Dijkstra → en az maliyet. \(V = 3\sqrt{n}\) olduğundan array-PQ Dijkstra \(O(V^2)\) = \(O(n)\).

def widest_path(adj, capacity, s):               # (1) darboğaz-maks
    B = {v: 0 for v in adj}; B[s] = INF          # kaynağın darboğazı sonsuz
    Q = ChangeablePQ((v, -B[v]) for v in adj)    # max-PQ: anahtarları negatif tut
    done = set()
    while len(Q):
        u, _ = Q.delete_min()
        done.add(u)
        for v in adj[u]:
            if v in done:
                continue
            cand = min(B[u], capacity[(u, v)])   # TOPLA değil MIN (darboğaz-üçgeni)
            if cand > B[v]:                      # KÜÇÜLT değil BÜYÜT
                B[v] = cand; Q.decrease_key(v, -cand)
    return B

Şekil 21.4 bu iki aşamayı motordan gerçek verilerle gösterir: \(s \to t\) doğrudan (kapasite 10, maliyet 5) ile \(s \to t_2 \to t\) alternatifi (kapasiteler \(4, 4\); maliyetler \(1, 1\)). Aşama 1’de darboğaz gevşetmesi doğrudan rota için \(\min(\infty, 10) = 10\), alternatif için \(\min(4, 4) = 4\) bulur; \(\max(10, 4) = 10\)\(w^\star = 10\). Aşama 2’de yalnız kapasitesi \(\ge 10\) olan kenarlar kalır (alternatif rota \(4 < 10\) ile elenir), kalan çizgede maliyet-Dijkstra en ucuz taşımayı 5 olarak verir.

Karmaşıklık. (1) modifiye Dijkstra; (2) array-PQ Dijkstra \(O(V^2) = O((\sqrt{n})^2) = O(n)\).

Şekil 21.4: Darboğaz = modifiye Dijkstra: gevşetmeyi değiştir, iskeleti koru — Problem 5. İki aşama (motordan GERÇEK). SOL: iki rota s⟶t — doğrudan (kapasite 10, maliyet 5) vs t₂ üzerinden (kapasiteler 4,4; maliyetler 1,1). AŞAMA ①: darboğaz gevşetme formül kutusu B(v)=maks(min(B(u),kap)) — toplama→MIN, küçültme→BÜYÜTME (klasik d(v)=min(d(u)+w) ile kıyas); rota darboğazları doğrudan min(∞,10)=10 amber-kazanan vs alternatif min(4,4)=4; w=maks(10,4)=10 rozeti. AŞAMA ②: w≥10 süz → alternatif rota (kap 4 < 10) elenir soluk, doğrudan kazanır; kalan çizgede maliyet-Dijkstra → en ucuz=5. Alt not: üçgen-eşitsizliği-analogu her güncelleme formülü Dijkstra iskeletine takılır; V=3√n → array-PQ O(V²)=O(n) (Solomon 1:26:05).

21.7 Ne Öğrendik?

ÖnemliAltı Taşınabilir Araç

Bu oturum, Ders 16-19’un ağırlıklı en kısa yol teorisini beş somut problemde uyguladı ve altı taşınabilir araç kazandırdı:

  1. Dijkstra’nın dondurma varsayımı: negatif kenar bu varsayımı kırar (düğüm geri eklenmeli) — bu yüzden Dijkstra yalnız negatif-olmayan ağırlıkta çalışır; negatif kenarda Bellman-Ford gerekir.
  2. “Önce bariz olanı dene”: yarıçap gibi problemler, akıllı numara yerine tanımı doğrudan kodlamayla (Johnson + iç içe döngü) \(O(V^3)\)’te çözülür.
  3. Süpernode: birçok hedefe (sensör) tek 0-ağırlıklı kaynakla bağlanıp tek Dijkstra ile “en yakın hedef” mesafesini bul.
  4. Cevap-üzerinde ikili arama:\(\log n\) bütçe” → ikili arama ipucu; monoton evet/hayır eşiğini (\(k^\star\)) sıralı dizi indeksinde ara.
  5. Graf çoğaltma / durum makinesi: konum + durum (kalan kapasite) → \(k+1\) katman; \(O(kn)\) çizgede Dijkstra.
  6. Modifiye gevşetme: üçgen-eşitsizliği analoğu olan her güncelleme formülü (darboğaz) Dijkstra iskeletine takılabilir — toplama yerine min/maks.

21.8 Sonraki

UyarıDers 21 (L14) — Tüm-Çiftler En Kısa Yollar (APSP) ve Johnson

Sırada Ders 21 (L14): Tüm-Çiftler En Kısa Yollar (APSP) var — Jason Ku ile, bu oturumda kara kutu olarak kullandığımız Johnson algoritmasını açıyoruz: negatif ağırlıklı bir çizgede tüm düğüm çiftleri arası en kısa yol. Püf nokta, bir potansiyel fonksiyonla kenarları negatif-olmayana “yeniden ağırlıklandırıp” Dijkstra’yı \(V\) kez çalıştırmaktır.