Bölüm 4.4: Ağ Akışı

Algoritmalar
Akış ağlarıArtık ağ ve artış yoluKesimlerMaks-akış min-kesim Ford-FulkersonEdmonds-KarpDinicİtme–yeniden etiketleme
Sercan KÜLCÜ · Giresun Üniversitesi · Bilgisayar Mühendisliği

Giriş

Öğrenme Çıktıları

Modelleme

Bir problemi kaynak, hedef ve kapasiteli kenarlardan oluşan bir akış ağı olarak kurmak; akışın kapasite ve korunum kısıtlarını yazmak.

Artık ağ ve kesim

Artık ağı, artış yolunu ve darboğazı hesaplamak; s–t kesiminin kapasitesini bulmak ve maks-akış min-kesim teoremini uygulamak.

Algoritmalar

Ford-Fulkerson, Edmonds-Karp, Dinic ve itme–yeniden etiketleme algoritmalarını bir örnek ağ üzerinde adım adım çalıştırmak.

Analiz

O(E·|f*|), O(V·E²) ve O(V²·E) sınırlarının nereden geldiğini açıklamak; algoritmaları karşılaştırıp uygun olanı seçmek.

Akış Ağları

Maksimum Akış (Maximum Flow) Problemi

  • Yönlü çizgede bir kaynak (source, s) ve bir hedef (sink, t) düğüm bulunur.
  • Her kenara bir kapasite (capacity) c(u, v) ≥ 0 atanır: o kenardan birim zamanda geçebilecek en fazla miktar.
  • Amaç: kapasiteleri aşmadan kaynaktan hedefe gönderilebilecek en büyük akış miktarını bulmak.
4343266SABCDT

Kenar etiketleri kapasitedir. Bu ağda en büyük akış 7'dir.

Sezgi: boru hattında su, yol ağında trafik, bilgisayar ağında veri paketleri. Her boru (kenar) en fazla kapasitesi kadar taşır; ara kavşaklarda (düğümlerde) madde birikmez.

Akış Ağları

Akış (Flow) ve Kısıtları

Akış, her kenara bir sayı f(u, v) atayan bir fonksiyondur:

  1. Kapasite kısıtı: 0 ≤ f(u, v) ≤ c(u, v).
  2. Akış korunumu: s ve t dışındaki her v için
    giren akış = çıkan akış.

Akışın değeri: |f| = Σ f(s, v) − Σ f(v, s)
(kaynaktan çıkan net akış = hedefe giren net akış).

4/43/34/42/32/25/65/6SABCDT

Etiket: akış/kapasite. C'ye 3 + 2 = 5 girer, 5 çıkar. |f| = 4 + 3 = 7.

Bir kenarda f = c ise kenar doymuştur (saturated): üzerinden daha fazla akış gönderilemez.

Akış Ağları

Birden Çok Kaynak ve Hedef

S∞s₁∞s₂∞sₙt₁∞t₂∞tₘ∞T⋮⋮ağ
  • Birden çok kaynak (s₁ … sₙ) ve hedef (t₁ … tₘ) varsa yeni bir süper kaynak S ve süper hedef T eklenir.
  • S → sᵢ ve tⱼ → T kenarlarına sınırsız (∞) kapasite verilir; problem tek kaynaklı, tek hedefli maksimum akışa dönüşür.

Artık Ağ ve Artış Yolu

Artık Ağ (Residual Network)

  • Artık ağ Gf, mevcut akış f altında hâlâ gönderilebilecek akışı gösterir.
  • İleri kenar: cf(u, v) = c(u, v) − f(u, v) — kapasiteden akış çıkarılır; akış kapasiteden azsa kalan kapasite pozitiftir.
  • Ters kenar: cf(v, u) = f(u, v) — gönderilmiş akış geri alınabilir (iptal edilebilir).
  • Yalnızca cf > 0 olan kenarlar Gf'ye girer; artış yolları bu ağda aranır.
Akış ağı: f/c = 3/5
3/5uv
Artık ağ: 5 − 3 = 2 ileri, 3 geri
23uv

Düz ok: ileri (kalan) kapasite · kesikli ok: ters kenar. Ters kenarlar olmadan algoritma ilk yanlış seçimini düzeltemez.

Artık Ağ ve Artış Yolu

Artış Yolu (Augmenting Path)

  • Artık ağda kaynaktan hedefe giden yönlü bir yoldur; kaynaktan hedefe ek akış sağlar.
  • Yoldaki her kenarın artık kapasitesi pozitiftir: kenarlar kapasitelerinden daha az akış taşır (ya da ters kenardır).
  • Darboğaz (bottleneck): cf(p) = min cf(u, v), (u, v) ∈ p. Yol boyunca bu kadar akış eklenir.
  • Genellikle DFS veya BFS ile bulunur; artış yolu kalmayınca akış maksimumdur.
4343266SABCDT

p = S → A → B → T: min(4, 4, 2) = 2.

Kesimler

Kesimler (Cuts)

  • s–t kesimi (S, T): düğümleri s ∈ S ve t ∈ T olacak biçimde ikiye bölen ayrımdır; kesilen kenarlar çizgenin bağlantısını keser.
  • Kesim kapasitesi: c(S, T) = Σ c(u, v), u ∈ S, v ∈ T — yalnızca S'den T'ye giden kenarlar sayılır.
  • Her akış için kesimden geçen net akış |f|'ye eşittir; bu yüzden |f| ≤ c(S, T).
  • Minimum kesim (min-cut): kapasitesi en küçük kesim (kenar sayısı değil, kapasite toplamı).
4343266kesimSTSABCDT

S = {S, A}: c(S, T) = 4 + 3 = 7 (minimum).

Kesimler

Maksimum Akış – Minimum Kesim Teoremi

Bir f akışı için aşağıdakiler denktir (Ford ve Fulkerson, 1956):

  1. f bir maksimum akıştır.
  2. Artık ağ Gf'de hiçbir artış yolu yoktur.
  3. Bir (S, T) kesimi için |f| = c(S, T).
Sonuç: en büyük akış değeri = en küçük kesim kapasitesi. Min kesim, son artık ağda s'ten ulaşılabilen düğümler S alınarak bulunur.
S tarafı (örnek ağ)c(S, T)
{S}7
{S, A}7
{S, A, B}8
{S, A, B, C, D}8
{S, C}10
{S, B, D}18

16 kesimin en küçüğü 7'dir; bulunan akışın değeri de 7 olduğu için bu akış maksimumdur.

Kesimler

Ağ Akış Algoritmaları (Network Flow)

Amaç: kısıtlar altında kaynaktan hedefe mümkün olan en fazla akışı sağlamak.

AlgoritmaYaklaşımSüreNot
Ford-Fulkerson (1956)herhangi bir artış yolu (çoğunlukla DFS)O(E · |f*|)basit; süre akış değerine bağlı
Edmonds-Karp (1972)en kısa artış yolu (BFS)O(V · E²)Ford-Fulkerson'ın polinom zamanlı hâli
Dinic (1970)seviye çizgesi + engelleyici akışO(V² · E)Edmonds-Karp'tan hızlı; birim kapasitede çok verimli
İtme–yeniden etiketleme (1988)ön akış + yükseklikler, yerel işlemlerO(V² · E)yol aramaz; FIFO sürümü O(V³)

|f*|: maksimum akışın değeri. Ford-Fulkerson'ın süresi tam sayı kapasiteler için geçerlidir.

Ford-Fulkerson

Ford-Fulkerson Yöntemi

  • L. R. Ford Jr. ve D. R. Fulkerson tarafından geliştirilmiştir (1956).
  • Ağırlıklı (kapasiteli) yönlü çizgede iki düğüm arasındaki maksimum akışı bulur: kaynaktan hedefe, belirli kapasiteli borularla gönderilebilecek en fazla suyu modelleyen bir çizge problemi.
  • İlkeler: ağ yönlü bir çizgedir; her kenarın bir kapasitesi vardır; başlangıçta tüm akışlar 0'dır; artış yolu bulma adımı tekrarlanarak maksimum akışa ulaşılır.
  • Artış yolunun nasıl bulunacağını belirtmediği için bir yöntemdir: Ford-Fulkerson genellikle DFS, Edmonds-Karp ise BFS kullanır.

Ford-Fulkerson

Ford-Fulkerson: Algoritma Adımları

0. Tüm kenarlarda f(u, v) = 0; artık ağ = özgün ağ.

Başlangıçta akış sıfırdır, her kenarın artık kapasitesi kendi kapasitesidir.

1. Artık ağda kaynaktan hedefe bir artış yolu p bul (cf > 0 olan kenarlar).

Yol DFS ile (Ford-Fulkerson) ya da BFS ile (Edmonds-Karp) aranır.

2. Darboğazı hesapla: δ = min cf(u, v), (u, v) ∈ p.

Yol boyunca gönderilebilecek en fazla akış, yolun en dar kenarıdır.

3. Yol boyunca δ kadar akış gönder: f(u, v) += δ, ters kenar için f(v, u) −= δ; |f| += δ.

Ters kenarlar güncellenir; yoldaki en az bir kenar doyar.

4. Artış yolu kalmayana kadar 1–3'ü tekrarla; |f| maksimumdur.

Döngü, hedefe ulaşılamadığında (artış yolu kalmadığında) biter; maks-akış min-kesim teoremi sonucun en iyi olduğunu garanti eder.

Ford-Fulkerson

Ford-Fulkerson Örneği 1

Artık ağ Gf
4343266SABCDT
Akış f (f/c)
0/40/30/40/30/20/60/6SABCDT|f| = 0

Başlangıç: tüm akışlar 0, artık ağ özgün ağın aynısı.

Artık ağ: yol p
4343266SABCDT
Akış: +2
2/40/32/40/32/20/60/6SABCDT|f| = 2

İlk artış yolu p = {S, A, B, T}: darboğaz 2 birim. |f| = 2.

Artık ağ: yol p
223223266SABCDT
Akış: +3
2/43/32/40/32/23/63/6SABCDT|f| = 5

İkinci artış yolu p = {S, C, D, T}: darboğaz 3 birim. |f| = 5.

Artık ağ: yol p
22322323333SABCDT
Akış: +2
4/43/34/42/32/25/65/6SABCDT|f| = 7

Üçüncü artış yolu p = {S, A, B, C, D, T}: darboğaz 2 birim. |f| = 7.

Son artık ağ
4341221515SABCDT
Maksimum akış
4/43/34/42/32/25/65/6SABCDT|f| = 7

S'den çıkan iki kenar da doydu: artık ağda S'den hiçbir yere gidilemez. Maksimum akış 7; min kesim ({S}, diğerleri) = 4 + 3.

Ford-Fulkerson

Ford-Fulkerson Örneği 2: Ters Kenar Kullanımı

Artık ağ Gf
1010428961010S1234T
Akış f (f/c)
0/100/100/40/20/80/90/60/100/10S1234T|f| = 0

Kaynak S, hedef T. Başlangıçta tüm akışlar 0.

Artık ağ: yol p (+8)
1010428961010S1234T
Akış f
8/100/100/40/28/80/90/60/108/10S1234T|f| = 8

p = S → 1 → 4 → T: darboğaz 1 → 4 (8). |f| = 8.

Artık ağ: yol p (+2)
2810428961028S1234T
Akış f
8/102/100/40/28/82/90/60/1010/10S1234T|f| = 10

p = S → 3 → 4 → T: 4 → T'de yalnızca 2 kaldı. |f| = 10.

Artık ağ: yol p (+4)
28824287261010S1234T
Akış f
8/106/104/40/24/86/90/64/1010/10S1234T|f| = 14

p = S → 3 → 4 → 1 → 2 → T: 4 → 1 ters kenarı kullanılır; 1 → 4 akışı 8'den 4'e düşer, 1'den çıkan 4 birim 1 → 2'ye yönlenir. |f| = 14.

Artık ağ: yol p (+2)
284642443666410S1234T
Akış f
10/106/104/40/26/86/92/66/1010/10S1234T|f| = 16

p = S → 1 → 4 → 2 → T: S → 1'de 2 birim kalmıştı. |f| = 16.

Artık ağ: yol p (+3)
1046422636424610S1234T
Akış f
10/109/104/40/26/89/95/69/1010/10S1234T|f| = 19

p = S → 3 → 4 → 2 → T: darboğaz 3 → 4 (9 − 6 = 3 kaldı). |f| = 19.

Son artık ağ
101942269151910S1234T
Maksimum akış
10/109/104/40/26/89/95/69/1010/10S1234T|f| = 19

Artık ağda S'den yalnızca 3'e ulaşılır → min kesim ({S, 3}, diğerleri) = 10 + 9 = 19 = |f*|.

Ford-Fulkerson

Ters Kenarlar Neden Gerekli?

Yalnızca ileri kenarlarla (açgözlü)
  1. S → 1 → 4 → T: 8
  2. S → 3 → 4 → T: 2
  3. S → 1 → 2 → T: 2
  4. S → 3 → 4 → 2 → T: 6

Toplam 18. S'den yalnızca 3 ve 4'e gidilebiliyor; 4'ün çıkışları dolu. Takıldı!

Artık ağ (ters kenarlı)

İlk seçim 1 → 4'e 8 birim gönderdi. 4 → 1 ters kenarı bu kararın bir kısmını geri almayı sağlar: 1'den gelen akış 2'ye, 3'ten gelen akış 4'e yönlenir.

Sonuç 19 = min kesim. Yol hangi sırayla seçilirse seçilsin artık ağ maksimuma ulaşır.

Ters kenar, gerçekte "geriye akış göndermek" değil, daha önce gönderilmiş akışı iptal etmek demektir: f(u, v) −= δ.

Ford-Fulkerson

Ford-Fulkerson: Sözde Kod

FORD_FULKERSON(G, kaynak, hedef):
  akış[u, v] = 0, her bir (u, v) için E içinde     // başlangıçta 0
  maksimumAkış = 0
  döngü artırıcı yol var iken:
    yol = DFS(G, kaynak, hedef, akış)            // c − akış > 0 kenarlarla
    delta = ∞                                    // yoldaki en küçük kalan kapasite
    v = hedef
    döngü v ≠ kaynak iken:
      u = yol.ata[v]
      delta = min(delta, kapasite[u, v] − akış[u, v])
      v = u
    v = hedef                                    // yoldaki akışları güncelle
    döngü v ≠ kaynak iken:
      u = yol.ata[v]
      akış[u, v] += delta
      akış[v, u] −= delta                        // ters kenar
      v = u
    maksimumAkış += delta
  döndür maksimumAkış, akış

Ford-Fulkerson

Java: DFS ile Artış Yolu

boolean dfs(int u, int hedef,
            boolean[] ziyaret, int[] ata) {
  ziyaret[u] = true;
  if (u == hedef) return true;
  for (int v = 0; v < V; v++) {
    if (!ziyaret[v] && artik[u][v] > 0) {
      ata[v] = u;
      if (dfs(v, hedef, ziyaret, ata))
        return true;
    }
  }
  return false;   // bu daldan hedefe yol yok
}
  • artik[u][v]: artık kapasite matrisi. Başlangıçta kapasiteler; ters kenarlar 0.
  • Hedefe ulaşılınca true döner; ata[] yolu tersten verir.
  • Akış eklenirken artik[u][v] −= d ve artik[v][u] += d yapılır: ters kenar kendiliğinden oluşur.
  • Komşu matrisinde bir DFS O(V²), komşu listesinde O(V + E) sürer.

Ford-Fulkerson

Ford-Fulkerson: Karmaşıklık Analizi

  • Çalışma süresi ağın yapısına ve kapasitelere bağlıdır.
  • Bir artış yolu bulmak (DFS/BFS) ve akışı güncellemek: O(E).
  • Kapasiteler tam sayı ise her artış yolu akışı en az 1 birim artırır → en fazla |f*| tekrar.
  • Toplam: O(E · |f*|); E kenar sayısı, |f*| maksimum akış değeri.
Tam sayılılık (integrality)Tüm kapasiteler tam sayı ise akış hep tam sayı kalır ve tam sayı değerli bir maksimum akış bulunur. Eşleme problemlerinde bu özellik kullanılır.
UyarıO(E · |f*|) polinom değildir: |f*| sayının büyüklüğüne bağlıdır. İrrasyonel kapasitelerde yöntem sonlanmayabilir bile.

Ford-Fulkerson

Kötü Yol Seçimi: 2000 Artış

10001000110001000sabt
  • Maksimum akış 2000 (s → a → t ve s → b → t).
  • Kötü bir yol seçimi her seferinde ortadaki kenarı kullanır: s → a → b → t, sonra ters kenarla s → b → a → t … Her yol yalnızca 1 birim ekler → 2000 artış.
  • Edmonds-Karp (BFS) en kısa yolları seçer: 2 artış yeter.
  • Kapasite 10⁹ olsaydı DFS'li sürüm milyarlarca adım atabilirdi; BFS bu bağımlılığı kaldırır.

Edmonds-Karp

Edmonds-Karp Algoritması

  • Ağırlıklı yönlü çizgede iki düğüm arasındaki maksimum akışı bulur; Ford-Fulkerson yönteminin bir türevidir.
  • Jack Edmonds ve Richard Karp tarafından geliştirilmiştir (1972; Dinic 1970'te bağımsız olarak).
  • Artış yollarını BFS (genişlik öncelikli arama) ile bulur: her seferinde kenar sayısı en az olan artış yolu seçilir.
  • Edmonds-Karp BFS'yi artış yolu bulmak için kullanır; Dinic ise BFS'yi daha fazla akış mümkün mü diye bakmak ve seviye çizgesi kurmak için kullanır.
Adımlar: (1) BFS ile kaynaktan hedefe en kısa artış yolunu bul. (2) Yol boyunca darboğaz kadar akış gönder, ters kenarları güncelle. (3) BFS hedefe ulaşamayana kadar tekrarla.

Edmonds-Karp

Edmonds-Karp: Karmaşıklık O(V · E²)

  • Her tur bir BFS ve bir yol güncellemesidir: O(E).
  • BFS en kısa yolu seçtiği için s'ten her düğüme olan artık ağ uzaklığı hiç azalmaz.
  • Her artışta en az bir kenar kritik olur (doyar). Aynı kenarın yeniden kritik olabilmesi için uzaklığı en az 2 artmalıdır; uzaklık ≤ V olduğundan her kenar en fazla ~V/2 kez kritik olur.
  • Artış sayısı O(V · E) → toplam O(V · E) · O(E) = O(V · E²); E kenar, V düğüm sayısı.
Süre artık |f*|'ye bağlı değildir: kapasiteler ne kadar büyük olursa olsun algoritma polinom zamanda biter.

Edmonds-Karp

Java: BFS ile Artış Yolu

boolean bfs(int kaynak, int hedef, int[] ata) {
  boolean[] ziyaret = new boolean[V];
  Queue<Integer> kuyruk = new LinkedList<>();
  kuyruk.add(kaynak);
  ziyaret[kaynak] = true;
  ata[kaynak] = -1;
  while (!kuyruk.isEmpty()) {
    int u = kuyruk.poll();
    for (int v = 0; v < V; v++)
      if (!ziyaret[v] && artik[u][v] > 0) {
        kuyruk.add(v);
        ata[v] = u;
        ziyaret[v] = true;
      }
  }
  return ziyaret[hedef];
}
  • Kuyruk kaynaktan başlar; artık kapasitesi pozitif ve ziyaret edilmemiş her komşu kuyruğa eklenir.
  • ata[v] = u ile BFS ağacı saklanır; hedef ziyaret edildiyse bulunan yol en az kenarlı yoldur.
  • Ford-Fulkerson'dan tek farkı bu fonksiyondur; ana döngü aynıdır.

Edmonds-Karp · Kodu adım adım çalıştır

edmondsKarp(s, t): Kodu Adım Adım İzle

1613104129147204s1324t

Başlangıç: artık ağ = kapasiteler, maksAkis = 0.

1613104129147204s1324t

bfs en kısa yolu buldu: s → 1 → 3 → t (3 kenar).

1613104129147204s1324t

Hedeften geriye: akis = min(16, 12, 20) = 12.

412131041291478124s1324t

Yoldaki ileri kenarlardan 12 çıkar, ters kenarlara 12 eklenir (kesikli oklar).

412131041291478124s1324t

maksAkis = 0 + 12 = 12.

412131041291478124s1324t

bfs en kısa yolu buldu: s → 2 → 4 → t (3 kenar).

412131041291478124s1324t

Hedeften geriye: akis = min(13, 14, 4) = 4.

4129410412910478124s1324t

Yoldaki ileri kenarlardan 4 çıkar, ters kenarlara 4 eklenir (kesikli oklar).

4129410412910478124s1324t

maksAkis = 12 + 4 = 16.

4129410412910478124s1324t

bfs en kısa yolu buldu: s → 2 → 4 → 3 → t (4 kenar).

4129410412910478124s1324t

Hedeften geriye: akis = min(9, 10, 7, 8) = 7.

41221110412931171194s1324t

Yoldaki ileri kenarlardan 7 çıkar, ters kenarlara 7 eklenir (kesikli oklar).

41221110412931171194s1324t

maksAkis = 16 + 7 = 23.

41221110412931171194s1324t

BFS t'ye ulaşamadı (s'ten yalnızca s, 1, 2, 4 ulaşılabilir). return 23.

int edmondsKarp(int s, int t) {
  int maksAkis = 0;
  int[] ata = new int[V];
  while (bfs(s, t, ata)) {
    int akis = Integer.MAX_VALUE;
    for (int v = t; v != s; v = ata[v])
      akis = Math.min(akis, artik[ata[v]][v]);
    for (int v = t; v != s; v = ata[v]) {
      int u = ata[v];
      artik[u][v] -= akis;  // ileri
      artik[v][u] += akis;  // ters
    }
    maksAkis += akis;
  }
  return maksAkis;
}

Edmonds-Karp

Edmonds-Karp Örneği

Artık ağ
1613104129147204s1324t
Akış f
0/160/130/100/40/120/90/140/70/200/4s1324t|f| = 0

Ağ verilsin. Üst sınır: |f*| ≤ 24 (s'den çıkan kapasite 16 + 13 = 29, t'ye giren 20 + 4 = 24; küçüğü).

Artık ağ: p1
1613104129147204s1324t
Akış f
12/160/130/100/412/120/90/140/712/200/4s1324t|f| = 12

Adım 1: c(1, 3) yüzünden cf(p1) = 12 olan p1 = ⟨s, 1, 3, t⟩ artış yolu seçilir. |f| = 12.

Artık ağ: p2
412131041291478124s1324t
Akış f
12/164/130/100/412/120/94/140/712/204/4s1324t|f| = 16

Adım 2: c(4, t) yüzünden cf(p2) = 4 olan p2 = ⟨s, 2, 4, t⟩ artış yolu seçilir. |f| = 16.

Artık ağ: p3
4129410412910478124s1324t
Akış f
12/1611/130/100/412/120/911/147/719/204/4s1324t|f| = 23

Adım 3: c(4, 3) yüzünden cf(p3) = 7 olan p3 = ⟨s, 2, 4, 3, t⟩ artış yolu seçilir. |f| = 23.

Son artık ağ
41221110412931171194s1324t
Son akış ve min kesim
12/1611/130/100/412/120/911/147/719/204/4s1324t|f| = 23

Son durum: artık ağda s'ten yalnızca 1, 2, 4'e ulaşılır. Kesim ({s, 1, 2, 4}, {3, t}) (kırmızı: T tarafı): 12 + 7 + 4 = 23 = |f*| (t'ye giren akış: 19 + 4).

Edmonds-Karp

Edmonds-Karp Örneği 2

Artık ağ
33431226119ABCDEFG
Akış f
0/30/30/40/30/10/20/20/60/10/10/9ABCDEFG|f| = 0

Kaynak A, hedef G. Başlangıçta tüm akışlar 0.

Artık ağ: yol (+1)
33431226119ABCDEFG
Akış f
0/31/30/40/30/10/21/20/60/11/10/9ABCDEFG|f| = 1

p = {A, D, E, G}: E → G (1) darboğaz. Akış = 1.

Artık ağ: yol (+2)
3214312116119ABCDEFG
Akış f
0/33/30/40/30/10/21/22/60/11/12/9ABCDEFG|f| = 3

p = {A, D, F, G}: A → D'de 2 kaldı. Akış = 1 + 2 = 3.

Artık ağ: yol (+1)
33431211421172ABCDEFG
Akış f
1/33/31/40/31/10/21/23/60/11/13/9ABCDEFG|f| = 4

p = {A, B, C, D, F, G}: A → D doydu, BFS 5 kenarlı yolu bulur; C → D (1) darboğaz. Akış = 4.

Artık ağ: yol (+1)
2133131211331163ABCDEFG
Akış f
2/33/32/40/31/11/20/24/60/11/14/9ABCDEFG|f| = 5

p = {A, B, C, E, D, F, G}: E → D ters kenarı D → E akışını 1'den 0'a indirir. Akış = 5.

Son artık ağ
1232231112241154ABCDEFG
Maksimum akış
2/33/32/40/31/11/20/24/60/11/14/9ABCDEFG|f| = 5

BFS G'ye ulaşamaz; A'dan A, B, C, E ulaşılabilir. Kesim kapasitesi A→D 3 + C→D 1 + E→G 1 = 5 = |f*|.

Edmonds-Karp

Edmonds-Karp Örneği 3: Artık Ağ Üzerinde

Ağ (kapasiteler)
424213113s1234t
Artık ağ
424213113s1234t

s'ten t'ye; başlangıçta artık ağ = kapasiteler. En kısa yolların hepsi 3 kenarlı: s→4→t, s→1→2→t, s→1→3→t.

Önce: yol
424213113s1234t
Sonra: +2
4242131112s1234t|f| = 2

s → 4 → t yolu: darboğaz s → 4 (2). 2 birim itilir; s → 4 kalanı 0, 4 → s ters kenarı 2.

Önce: yol
4242131112s1234t
Sonra: +3
132132131112s1234t|f| = 5

s → 1 → 2 → t yolu: darboğaz 2 → t (3). 3 birim itilir.

Önce: yol
132132131112s1234t
Sonra: +1
421311131112s1234t|f| = 6

s → 1 → 3 → t yolu: s → 1'de 1 kalmıştı. 1 birim itilir.

Son akış (f/c)
4/42/23/41/20/13/31/10/12/3s1234t|f| = 6
Son artık ağ
421311131112s1234t

s'ten çıkan kenarlar doydu → yol yok. |f*| = 2 + 3 + 1 = 6: 3 birim s→1→2→t, 1 birim s→1→3→t, 2 birim s→4→t.

Dinic

Dinic Algoritması

  • Bir çizgede maksimum akışı bulur (Y. Dinitz, 1970); kapasiteli (ağırlıklı) çizge üzerinde çalışır.
  • Seviye çizgesi (level graph): artık ağda BFS ile her düğümün seviyesi (kaynağa uzaklığı) bulunur; yalnızca seviye(v) = seviye(u) + 1 olan kenarlar tutulur.
  • Engelleyici akış (blocking flow): seviye çizgesinde her s–t yolunda en az bir doymuş kenar bırakan akış; DFS ile bulunur.
  • Akış ters kenarlarla güncellenir; hedef seviye çizgesinde ulaşılamaz olana kadar fazlar tekrarlanır.
Edmonds-Karp her BFS'den sonra tek yol kullanır; Dinic aynı seviye çizgesindeki tüm en kısa yolları tek fazda doyurur.

Dinic

Dinic: Algoritma Adımları

1. Başlangıçta tüm kenarların akışına 0 ata.

Artık ağ özgün ağla aynıdır.

2. Kaynaktan BFS ile her düğümün seviyesini (kaynağa uzaklık) belirle. Hedefin seviyesi yoksa dur.

BFS, artık kapasitesi pozitif kenarları kullanır; hedefe ulaşılamıyorsa akış maksimumdur.

3. DFS ile her adımda bir seviye ileri giden artış yolları bul.

Yalnızca seviye(v) = seviye(u) + 1 olan kenarlar izlenir; çıkmaz kenarlar bir daha denenmez.

4. Her yoldaki minimum kapasiteyi toplam akışa ekle; kenarların ve ters kenarların kapasitesini güncelle.

Yol kalmayınca bu fazın engelleyici akışı bulunmuştur.

5. 2. adıma dön ve işlemleri tekrarla.

Her fazda s–t uzaklığı en az 1 artar; bu yüzden en fazla V − 1 faz vardır.

Dinic

Dinic Örneği: Fazlar

0/100/100/40/20/80/90/60/100/10s1324t|f| = 0

Ağ (akış/kapasite). Başlangıçta tüm akışlar 0; artık ağ = kapasiteler.

1010428961010s1324t012123

Faz 1 – BFS: seviyeler s = 0; 1, 2 = 1; 3, 4 = 2; t = 3. Soluk kenarlar (1 → 2, 4 → 3) seviye atlamaz, kullanılmaz.

10/104/104/40/26/84/90/64/1010/10s1324t|f| = 14

Faz 1 – engelleyici akış (DFS): {s, 1, 3, t} 4 birim, {s, 1, 4, t} 6 birim, {s, 2, 4, t} 4 birim → |f| = 14.

106442265466410s1324t|f| = 14

Faz 1 sonrası artık ağ (akış çizgesi Gf): doymuş kenarlar yalnızca ters yönde (kesikli) kalır.

106442265466410s1324t033124

Faz 2 – BFS: s = 0; 2 = 1; 4 = 2; 1, 3 = 3; t = 4. s–t uzaklığı 3'ten 4'e çıktı. 4 → 1 kenarı çıkmaz sokaktır.

10/109/104/40/26/89/95/69/1010/10s1324t|f| = 19

Faz 2 – engelleyici akış: {s, 2, 4, 3, t} 5 birim (darboğaz 2 → 4) → |f| = 14 + 5 = 19.

101942269151910s1324t0∞∞1∞∞

Faz 3 – BFS: yalnızca s (0) ve 2 (1) ulaşılabilir; t'ye yol yok → algoritma biter. Min kesim ({s, 2}, diğerleri) = 10 + 9 = 19.

10/109/104/40/26/89/95/69/1010/10s1324t|f| = 19

Sonuç: maksimum akış 19; yalnızca 2 faz (2 + 1 BFS) yetti. Aynı ağda Ford-Fulkerson 5 artış yolu kullanmıştı.

Dinic

Dinic: Sözde Kod

DINIC(G, kaynak, hedef):
  akış = [ ]       // her kenar için 0
  maksimumAkış = 0
  döngü BFS(G, kaynak, hedef, akış) iken:
    // seviye çizgesi kuruldu
    döngü engelleyici akış var iken:
      delta = DFS(G, kaynak, hedef,
                  akış, seviye, ∞)
      maksimumAkış += delta
  döndür maksimumAkış

BFS(G, kaynak, hedef, akış):
  seviye[v] = −1, her v için
  seviye[kaynak] = 0
  kuyruk.ekle(kaynak)
  döngü kuyruk boş değil iken:
    u = kuyruk.çıkar()
    her bir (u, v) için G[u] içinde:
      eğer seviye[v] < 0 ve
           kapasite[u,v] − akış[u,v] > 0:
        seviye[v] = seviye[u] + 1
        kuyruk.ekle(v)
  döndür seviye[hedef] ≥ 0
DFS(G, u, hedef, akış, seviye, lim):
  eğer u == hedef: döndür lim
  her bir (u, v) için G[u] içinde:
    kalan = kapasite[u,v] − akış[u,v]
    eğer seviye[v] == seviye[u] + 1
         ve kalan > 0:
      delta = DFS(G, v, hedef, akış,
                  seviye, min(lim, kalan))
      eğer delta > 0:
        akış[u, v] += delta
        akış[v, u] −= delta   // ters
        döndür delta
  döndür 0

Dinic

Java: Seviyeli DFS ve Kaldığı Yer Dizisi

int dfs(int u, int t, int akis, int[] basla) {
  if (u == t) return akis;
  for (; basla[u] < komsu[u].size(); basla[u]++) {
    Kenar k = komsu[u].get(basla[u]);
    if (seviye[k.hedef] == seviye[u] + 1 && k.akis < k.kapasite) {
      int d = dfs(k.hedef, t, Math.min(akis, k.kapasite - k.akis), basla);
      if (d > 0) {
        k.akis += d;                                 // ileri kenar
        komsu[k.hedef].get(k.tersIndis).akis -= d;   // ters kenar
        return d;
      }
    }
  }
  return 0;   // u'dan t'ye seviyeli yol kalmadı
}
  • Kenarlar komşu listesinde tutulur; her kenar ters kenarının indisini (tersIndis) bilir.
  • basla[u]: u'da denenecek sıradaki kenar (current arc). Çıkmaz kenar bir daha denenmez; bir fazdaki tüm DFS'ler toplam O(V · E).
  • Her fazın başında basla sıfırlanır, seviyeler BFS ile yeniden hesaplanır.

Dinic

Dinic: Karmaşıklık O(V² · E)

  • Her faz bir BFS gerektirir: O(V + E).
  • Her fazdan sonra s–t uzaklığı kesin olarak artar ve uzaklık ≤ V − 1 olduğundan en kötü durumda V faz olabilir.
  • Bir fazdaki engelleyici akış: her artış yolu O(V) uzunluktadır ve en fazla E yol bulunur; kaldığı yer dizisiyle faz başına O(V · E).
  • Toplam: O(V) · O(V · E) = O(V² · E).
Birim kapasitelerTüm kapasiteler 1 ise O(E · √E); iki parçalı eşleme gibi birim ağlarda O(E · √V) (Hopcroft-Karp).
PratikteYarışma programlamada en çok kullanılan maksimum akış algoritmasıdır: basit ve genellikle sınırının çok altında çalışır.

İtme–Yeniden Etiketleme

İtme ve Yeniden Etiketleme (Push–Relabel)

  • A. Goldberg ve R. Tarjan (1988). Artış yolu aramaz; düğümler üzerinde yerel işlemlerle çalışır.
  • Kaynaktan çıkan tüm kenarları doldurarak aşırı akış başlatır; akış, korunum kısıtını geçici olarak bozan bir ön akıştır (preflow).
  • Her düğümün bir yükseklik (height) etiketi vardır; akış yalnızca yüksekten bir alçağa doğru itilir (push), su gibi.
  • Bir düğüm fazlasını itemiyorsa yüksekliği artırılır (relabel).
  • Aşırı akışı olan düğüm kalmayınca ön akış gerçek bir akıştır; hedefteki aşırı akış maksimum akışı verir.

İtme–Yeniden Etiketleme

Ön Akış ve Aşırı Akış (Excess Flow)

3724u₁u₂Vw₁w₂

e(V) = (3 + 7) − (2 + 4) = 4

  • Aşırı akış: e(v) = giren toplam akış − çıkan toplam akış.
  • Ön akış: kapasite kısıtına uyar, korunum yerine e(v) ≥ 0 ister (s hariç).
  • e(v) > 0 olan düğüm (s ve t dışında) aktif düğümdür; algoritma aktif düğüm kalmayınca biter.

İtme–Yeniden Etiketleme

Yükseklik Fonksiyonu ve Başlangıç

Başlangıç:

  • Tüm kenarların akışı 0.
  • h(s) = |V| (düğüm sayısı); diğer tüm düğümler h = 0.
  • s'ten çıkan her kenar doldurulur: f(s, v) = c(s, v), e(v) = c(s, v).

Değişmezler:

  • h(s) = |V| ve h(t) = 0 hiç değişmez.
  • Artık ağdaki her (u, v) kenarı için h(u) ≤ h(v) + 1.
  • Bu yüzden h(u), u'dan t'ye artık ağ uzaklığının bir alt sınırıdır.
h(s) = |V| seçilir, çünkü s'ten t'ye artık ağda yol olsaydı uzunluğu ≤ |V| − 1 olurdu ve h(s) ≤ |V| − 1 gerekirdi. Bu yüzden artık ağda hiçbir zaman s–t yolu yoktur; sonunda akış maksimumdur.

İtme–Yeniden Etiketleme

İtme (Push) ve Yeniden Etiketleme (Relabel)

İtme: push(u, v)

Koşul: e(u) > 0, cf(u, v) > 0 (kenarda kapasite ile akış arasında fark var) ve h(u) = h(v) + 1.

δ = min(e(u), cf(u, v)) kadar akış itilir: e(u) −= δ, e(v) += δ. Kenar doyarsa doyuran, aksi hâlde doyurmayan itme.

Yeniden etiketleme: relabel(u)

Koşul: e(u) > 0 ama artık ağdaki her (u, v) için h(u) ≤ h(v); yani hiçbir komşuya itilemiyor.

h(u) = 1 + min h(v), (u, v) artık ağda. Böylece en az bir itme mümkün olur.

Hedefe ulaşamayan fazla, yükseklik |V|'yi aşınca kaynağa geri itilir. Akış yüksekten alçağa itilir; yükseklik yalnızca artar.

İtme–Yeniden Etiketleme

İtme–Yeniden Etiketleme Örneği

0/130/100/30/60/70/100/5sABCDt
Düğümhe
s0−
A00
B00
C00
D00
t00

Ağ verilsin (akış/kapasite). 6 düğüm var: |V| = 6.

13/1310/100/30/60/70/100/5sABCDt
Düğümhe
s6−
A013
B010
C00
D00
t00

Başlangıç: h(s) = 6; s → A ve s → B doldurulur. e(A) = 13, e(B) = 10.

13/1310/100/30/60/70/100/5sABCDt
Düğümhe
s6−
A013
B110
C00
D00
t00

B ele alınır. A ile aynı yükseklikte (0) olduğundan fazlasını A'ya gönderemez → relabel: h(B) = 1 + min(h(A) = 0, h(s) = 6) = 1.

13/1310/103/30/60/70/100/5sABCDt
Düğümhe
s6−
A016
B17
C00
D00
t00

B şimdi fazlasını A'ya itebilir: δ = min(10, 3) = 3. e(A) = 16, e(B) = 7.

13/1310/103/30/60/70/100/5sABCDt
Düğümhe
s6−
A116
B17
C00
D00
t00

A ele alınır. İtebileceği alçak komşu yok → relabel: h(A) = 1 + min(h(C) = 0, h(t) = 0, h(B) = 1, h(s) = 6) = 1.

13/1310/103/36/67/70/100/5sABCDt
Düğümhe
s6−
A13
B17
C06
D00
t07

A şimdi C'ye 6 ve hedefe 7 birim iter (iki kenar da doyar). e(A) = 3, e(C) = 6, hedefte 7.

13/1310/103/36/67/70/100/5sABCDt
Düğümhe
s6−
A13
B17
C16
D00
t07

C relabel edilir: h(C) = 1 + h(D) = 1. (C'nin 6 birim fazlası şimdilik bekler; aktif düğümler istenen sırada seçilebilir.)

13/1310/103/36/67/70/100/5sABCDt
Düğümhe
s6−
A23
B17
C16
D00
t07

A relabel edilir: artık ağda yalnızca B (h = 1) ve s (h = 6) kaldı → h(A) = 2.

13/1310/100/36/67/70/100/5sABCDt
Düğümhe
s6−
A20
B110
C16
D00
t07

A'nın yüksekliği B'den fazla: 3 birimi B'ye (B → A akışını iptal ederek) iter. e(A) = 0, e(B) = 10.

13/1310/103/36/67/70/100/5sABCDt
Düğümhe
s6−
A23
B37
C16
D00
t07

B'nin gidebileceği başka kenar yok → relabel h(B) = 3; 3 birimi tekrar A'ya iter. e(A) = 3, e(B) = 7.

13/133/103/36/67/70/100/5sABCDt
Düğümhe
s6−
A63
B70
C16
D00
t07

A ile B arasında relabel–push sürer (h(A) = 4, h(B) = 5, h(A) = 6, h(B) = 7). B'nin yüksekliği kaynağı geçince: 3 birimi A'ya, 7 birimi kaynağa iter.

10/133/103/36/67/70/100/5sABCDt
Düğümhe
s6−
A70
B70
C16
D00
t07

A relabel: h(A) = 1 + min(h(s) = 6, h(B) = 7) = 7; 3 birimi kaynağa iter. Artık A ve B'de fazla yok.

10/133/103/36/67/76/100/5sABCDt
Düğümhe
s6−
A70
B70
C10
D06
t07

C ele alınır: fazlası 6 birim D'ye itilir (h(C) = 1 > h(D) = 0).

10/133/103/36/67/76/105/5sABCDt
Düğümhe
s6−
A70
B70
C10
D11
t012

D relabel (h = 1) ve hedefe 5 birim iter. D'de hâlâ 1 birim fazla var.

10/133/103/36/67/75/105/5sABCDt
Düğümhe
s6−
A70
B70
C11
D20
t012

D relabel: hedef kenarı dolu, tek komşu C (h = 1) → h(D) = 2. 1 birimi C'ye iter.

10/133/103/35/67/75/105/5sABCDt
Düğümhe
s6−
A71
B70
C80
D80
t012

C'nin yüksekliği A'yı (7) geçene kadar C–D arasında relabel–push sürer (C: 3, 5, 7, 8; D: 4, 6, 8). C 1 birim fazlayı A'ya iter.

9/133/103/35/67/75/105/5sABCDt
Düğümhe
s6−
A70
B70
C80
D80
t012

A 1 birim fazlayı kaynağa iter. Aktif düğüm kalmadı: maksimum akış = hedefe giren = 7 + 5 = 12 = kaynaktan çıkan 9 + 3.

İtme–Yeniden Etiketleme

İtme–Yeniden Etiketleme: Sözde Kod

PUSH_RELABEL(G, kaynak, hedef):
  yükseklik[kaynak] = |V|
  yükseklik[v] = 0, v ≠ kaynak
  aşırı[v] = 0, her v için
  akış[e] = 0, her kenar e için
  // ön akış: kaynak kenarlarını doldur
  her bir (kaynak, v) ∈ E için:
    c = kapasite[kaynak, v]
    akış[kaynak, v] = c
    akış[v, kaynak] = −c
    aşırı[v] = c
    aşırı[kaynak] −= c
döngü aşırı[u] > 0 olan u varken:
  // u ≠ kaynak, u ≠ hedef
  eğer kalan(u,v) > 0 ve
       yükseklik[u] == yükseklik[v]+1:
    // İtme
    delta = min(aşırı[u], kalan(u,v))
    akış[u,v] += delta
    akış[v,u] −= delta
    aşırı[u] −= delta
    aşırı[v] += delta
  değilse:
    // Yeniden etiketleme
    m = ∞
    her bir (u, v) için G[u] içinde:
      eğer akış[u,v] < kapasite[u,v]:
        m = min(m, yükseklik[v])
    yükseklik[u] = m + 1
döndür aşırı[hedef]
// kalan = kapasite − akış

İtme–Yeniden Etiketleme

Java: push ve relabel

boolean it(Dugum d) {
  for (Kenar k : d.kenarlar) {
    if (d.yukseklik > k.hedef.yukseklik
        && k.akis != k.kapasite) {
      int akis = Math.min(
        k.kapasite - k.akis, d.asiri);
      d.asiri -= akis;
      k.hedef.asiri += akis;
      k.akis += akis;
      tersKenariGuncelle(k, akis);
      return true;   // itme yapıldı
    }
  }
  return false;
}
void etiketle(Dugum d) {
  int minY = Integer.MAX_VALUE;
  for (Kenar k : d.kenarlar) {
    // yalnızca artık ağdaki kenarlar
    if (k.akis != k.kapasite
        && k.hedef.yukseklik < minY) {
      minY = k.hedef.yukseklik;
      d.yukseklik = minY + 1;
    }
  }
}

Ana döngü: aktif düğüm varken if (!it(d)) etiketle(d); — sonuç hedefin aşırı akışıdır. Ters kenarlar negatif akışla tutulur (kapasite 0).

İtme–Yeniden Etiketleme

İtme–Yeniden Etiketleme: Karmaşıklık

İşlemToplam sayıGerekçe
Yeniden etiketlemeO(V²)her düğümün yüksekliği ≤ 2|V| − 1 ve yalnızca artar
Doyuran itmeO(V · E)bir kenar yeniden doyabilmek için iki uçtaki yükseklik ≥ 2 artmalı
Doyurmayan itmeO(V² · E)potansiyel fonksiyonu Σ h(v) (aktif v) ile
  • Genel algoritma en kötü durumda O(V² · E); bir relabel en fazla derece kadar kenarı tarar (toplam O(V · E)).
  • FIFO seçimiyle O(V³), en yüksek etiket seçimiyle O(V² · √E).
  • Pratikte gap ve global relabeling sezgileriyle en hızlı genel amaçlı maksimum akış yöntemlerindendir.

Karşılaştırma ve Uygulamalar

Algoritmaların Karşılaştırması

AlgoritmaTemel işlemSüreÖrnek ağda (|f*| = 19)
Ford-Fulkersonherhangi bir artış yolu (DFS)O(E · |f*|)5 artış yolu (Örnek 2'deki sıra)
Edmonds-Karpen kısa artış yolu (BFS)O(V · E²)4 artış yolu, 5 BFS
Dinicseviye çizgesi + engelleyici akışO(V² · E)2 faz, 3 BFS
İtme–yeniden etiketlemeyerel push / relabelO(V² · E), FIFO O(V³)yol aramaz
SeçimKüçük tam sayı kapasiteler: Ford-Fulkerson yeterli. Genel amaç: Dinic. Çok büyük, yoğun ağlar: itme–yeniden etiketleme.
Ortak sonuçHepsi aynı |f*| değerini bulur; akışın kenarlara dağılımı farklı olabilir. Min kesim son artık ağdan okunur.

Karşılaştırma ve Uygulamalar

Uygulamalar

  • İki parçalı eşleme: çalışan–iş, öğrenci–proje atama (birim kapasiteler).
  • Kenar ayrık yollar (Menger): birim kapasiteli maksimum akış.
  • Görüntü bölütleme: ön plan/arka plan ayrımı minimum kesimle.
  • Ağ güvenilirliği: ağı bölmek için kesilmesi gereken en küçük toplam kapasite.
  • Ulaşım ve lojistik: boru hattı, trafik, havayolu çizelgeleme, proje seçimi.
sa1a2a3b1b2b3t

Maksimum akış 3 = en büyük eşleme: a₁–b₂, a₂–b₁, a₃–b₃.

Özet

Özet

KonuHatırlanacaklar
Akış0 ≤ f ≤ c; ara düğümlerde giren = çıkan; |f| = s'ten çıkan net akış
Artık ağileri c − f, ters f; artış yolu Gf'de s → t yolu, darboğaz = en küçük cf
Kesimc(S, T) = S'den T'ye kapasiteler; maks akış = min kesim; S = son Gf'de s'ten ulaşılanlar
Ford-Fulkersonherhangi bir artış yolu; O(E · |f*|), tam sayı kapasitelerde sonlanır
Edmonds-KarpBFS ile en kısa yol; O(V · E²)
DinicBFS seviye çizgesi + DFS engelleyici akış; ≤ V faz; O(V² · E)
Push–relabelh(s) = |V|, ön akış; yüksekten alçağa it, itemezsen etiketle; O(V² · E)

Özet

Etkileşimli Simülatörler

Ağ Akışı Simülatörü4–12 düğümlü rastgele kapasiteli bir ağ üretin, düğümleri sürükleyin; Ford-Fulkerson (DFS) ve Edmonds-Karp (BFS) ile her artış yolunu ve eklenen akışı adım adım izleyip iki yöntemi aynı ağ üzerinde karşılaştırın.
Önerilen denemeAynı ağda önce Ford-Fulkerson'ı, sonra Edmonds-Karp'ı çalıştırın: bulunan maksimum akış aynı, artış yollarının sayısı ve sırası farklı mı? Günlükteki yolları sayın.

Özet

Sık Yapılan Hatalar

Ters kenarları unutmakYalnızca ileri kenarlarla aramak açgözlü bir algoritmadır ve maksimumu kaçırabilir (örnekte 18 < 19).
Darboğazı kapasiteyle hesaplamakDarboğaz, kapasitelerin değil artık kapasitelerin minimumudur: c − f (ya da ters kenarda f).
Min kesimi kenar sayısı sanmakMin kesim en az kenarı değil, en küçük kapasite toplamını keser.
T → S kenarlarını saymakKesim kapasitesine yalnızca S'den T'ye giden kenarlar girer; geri yöndekiler eklenmez.
Ford-Fulkerson'ı polinom sanmakO(E · |f*|) kapasitelerin değerine bağlıdır; BFS (Edmonds-Karp) bu bağımlılığı kaldırır.
İtme yönünü karıştırmakAkış yüksekten alçağa, yalnızca h(u) = h(v) + 1 iken itilir; başlangıçta h(s) = |V| olmalıdır.

Özet

Örnek Problemler

54236243sabcdt
  1. |f*| için kaynak ve hedef tarafından üst sınır nedir?
  2. Edmonds-Karp hangi artış yollarını sırayla bulur? (BFS komşuları alfabetik dener.)
  3. Maksimum akış ve bir minimum kesim nedir?
  4. Son durumda cf(s, a) ve cf(c, d) kaçtır?
  5. Push–relabel başlangıcında h ve e değerleri nedir?
Cevapları göster
  1. s'ten çıkan 5 + 4 = 9, t'ye giren 4 + 3 = 7 → |f*| ≤ 7.
  2. s→a→c→t (3), s→b→d→t (3), s→b→d→c→t (1). İlk ikisi 3, sonuncusu 4 kenarlı.
  3. |f*| = 7; S = {s, a, b, c, d}: c→t 4 + d→t 3 = 7 (son artık ağda t dışındaki her düğüme ulaşılır).
  4. cf(s, a) = 5 − 3 = 2; cf(c, d) = f(d, c) = 1 (ters kenar).
  5. h(s) = 6, diğerleri 0; e(a) = 5, e(b) = 4, diğerleri 0 (s → a ve s → b doldurulur).

Özet

Alıştırmalar

  1. Bir kenarın kapasitesi 1 artırılırsa maksimum akış en fazla ne kadar artar?
  2. Tüm kapasiteler k ile çarpılırsa maksimum akış ve minimum kesim nasıl değişir?
  3. Düğüm kapasiteleri c(v) varsa problem nasıl modellenir?
  4. Son artık ağdan minimum kesimi bulan bir Java metodu yazın.
  5. "Kötü durum" ağında DFS'li Ford-Fulkerson ve Edmonds-Karp en fazla kaç artış yapar?
  6. s'ten t'ye kenar ayrık yol sayısı maksimum akışla nasıl bulunur?
Cevaplar / ipuçları
  1. En fazla 1 (her kesimin kapasitesi en çok 1 artar); kenar bir min kesimde değilse hiç artmayabilir.
  2. Akış ve tüm kesim kapasiteleri k katına çıkar; aynı kesim minimum kalır.
  3. Her v'yi vg → vç kenarına (kapasite c(v)) bölün; gelenler vg'ye, gidenler vç'den bağlanır.
  4. Son artık ağda s'ten BFS; ziyaret edilen u, edilmeyen v olan özgün (u, v) kenarları kesimdir.
  5. DFS'li Ford-Fulkerson en kötü 2000, Edmonds-Karp 2 artış.
  6. Her kenara kapasite 1 verin; maksimum akış = kenar ayrık yol sayısı (Menger).

Özet

Kaynaklar

  • Cormen, Leiserson, Rivest ve Stein, Introduction to Algorithms, 4. baskı, MIT Press, 2022 (Bölüm 24: Maximum Flow).
  • Kleinberg ve Tardos, Algorithm Design, Pearson, 2006 (Bölüm 7: Network Flow).
  • Sedgewick ve Wayne, Algorithms, 4. baskı, 2011 (Bölüm 6.4: Maximum Flow).
  • L. R. Ford ve D. R. Fulkerson, "Maximal Flow Through a Network", Canadian Journal of Mathematics 8, 1956.
  • J. Edmonds ve R. M. Karp, "Theoretical Improvements in Algorithmic Efficiency for Network Flow Problems", Journal of the ACM 19(2), 1972.
  • E. A. Dinic, "Algorithm for Solution of a Problem of Maximum Flow in Networks with Power Estimation", Soviet Math. Doklady 11, 1970.
  • A. V. Goldberg ve R. E. Tarjan, "A New Approach to the Maximum-Flow Problem", Journal of the ACM 35(4), 1988.

Son

Bölüm 4.4: Ağ Akışı
Sonraki bölüm: Bölüm 5: Dizgi Algoritmaları
1 / 1 Sercan KÜLCÜ, Tüm hakları saklıdır.