COMPUTER ENGINEER

← BlogDATA STRUCTURES / ALGORITHMSPython örnek paketi ↓

Graf temelleri ve yollar · 29 / 53

Bellman–Ford, Floyd–Warshall ve Johnson

Anla → iz sür → uygula → gerekçelendir

2 dk okuma · uygulama için ayrıca zaman ayır

Bellman–Ford bütün kenarları V−1 tur relax eder. k tur sonrası en fazla k kenarlı en iyi yürüyüş distance'ı yakalanır. Kaynaktan erişilen negatif cycle varsa minimum maliyet sınırsız aşağı iner; V'inci turdaki iyileşme bunu saptar. Erişilemeyen negative cycle kaynak sonuçlarını etkilemez.

Floyd–Warshall all-pairs DP'dir: dist[i][j]=min(dist[i][j],dist[i][k]+dist[k][j]); k dış döngüdedir çünkü ara düğümleri aşamalı izin verme invariant'ını korur. Başlangıçta diagonal0 ve edge maliyetleri kullanılır. Paralel kenarlarda minimum maliyeti al. Negatif diagonal cycle göstergesidir; böyle cycle'a erişip çıkabilen çiftler için sonlu minimum yoktur.

Johnson seyrek all-pairs probleminde Bellman–Ford ile potential h bulur, w'=w+h[u]−h[v] sayesinde nonnegative yeniden ağırlıklandırır ve her kaynaktan Dijkstra çalıştırır. Yeniden ağırlıklandırma yollar arasında sıralamayı korur; orijinal distance'a dönüşümü unutma. Negative cycle varsa yöntem durmalıdır.

Adım adım iz sürme

A→B4, A→C5, B→C−2: iki kenarlı yol maliyeti2. Bellman–Ford negatif kenarı destekler; negative cycle ayrı durumdur.

Maliyet ve varsayımlar

Bellman–Ford O(VE), Floyd O(V³) zaman O(V²) alan. Johnson seyrek graflarda avantajlıdır.

Çalıştırılabilir örnek

Python 3 ile çalıştır. Assert küçük bir örneği denetler; genel doğruluk ispatı değildir. Bazı ileri örnekler özellikle küçük model veya referans oracle'dır; tam üretim uygulaması değildir.

Python 3
def bellman_ford(vertices, edges, source):
    d = {v: float("inf") for v in vertices}; d[source] = 0
    for _ in range(len(vertices)-1):
        changed = False
        for u,v,w in edges:
            if d[u] != float("inf") and d[u]+w < d[v]:
                d[v] = d[u]+w; changed = True
        if not changed: break
    if any(d[u] != float("inf") and d[u]+w < d[v] for u,v,w in edges):
        raise ValueError("reachable negative cycle")
    return d
assert bellman_ford("ABC",[("A","B",4),("A","C",5),("B","C",-2)],"A")["C"] == 2

KAVRADIĞINI KONTROL ET

Sıra sende

“Negatif edge varsa en kısa yol yok” doğru mu?

Çözümün mantığını göster

Hayır. Uygun reachable negative cycle olmadıkça minimum sonlu olabilir. Negatif edge ve negatif cycle ayrı kavramlardır.

Bir adım ileri

  1. Örneği değiştirmeden önce girdi sözleşmesini ve invariantı yaz.
  2. Uygun olan boş, sınır, tekrar ve adversarial girdileri ekle. Basit bir oracle ile karşılaştır.
  3. Belirtilen modelde maliyeti çıkar; farklı girdi büyüklüklerini ölç ve farkları gerekçelendir.

Temel kaynaklar ve ders notları

Bu eğitimde özgün anlatım kullanıldı; aşağıdaki kaynaklar ispatlar ve ileri okumalar sunar. Bağlantılar daha geniş ders modülünü kapsayabilir.

MIT 6.006 · Introduction to Algorithms ↗
İlerlemeden önce alıştırmayı çöz.