Kiejtés

  • IPA: [ ˈdinit͡sɒlɡoritmuʃ]

Főnév

Dinic-algoritmus

  1. (matematika, algoritmusok) A Dinic-algoritmus egy hatékony megoldás a maximális áramlás problémájára irányított, kapacitással ellátott hálózatokban. Az algoritmust Eugene A. Dinic dolgozta ki 1970-ben, és az Edmonds-Karp-algoritmus optimalizált változata. Az algoritmus időbonyolultsága (O(V^2E)), de speciális esetekben (például egységkapacitású hálózatok) lineárisabb, (O(E ))-re csökkenthető.



Probléma meghatározása

Bemenet:

  • Egy irányított gráf (G = (V, E)), ahol:
    • (V) a csúcsok halmaza.
    • (E) az élek halmaza.
    • Minden élhez tartozik egy kapacitás (c(u, v)).
  • Egy forrás ((s)) és egy nyelő ((t)) csúcs.

Kimenet:

  • A maximális áramlás értéke, amely (s)-ből (t)-be jut a hálózatban.



Fő ötlet

A Dinic-algoritmus a hálózatot szintekre bontja, és csak olyan éleket használ, amelyek egy szintből a következőbe vezetnek (szintgráf). Az algoritmus iteratívan építi a maximális áramlást az alábbi lépésekkel:



Algoritmus működése

1. Szintgráf építése (BFS)

  • Használj szélességi keresést ((BFS)), hogy meghatározd a szinteket, ahol minden csúcs szintje az (s)-től való távolság.
  • Ha (t) nem érhető el, az algoritmus leáll, mert elérte a maximális áramlást.

2. Blokkoló áramlás keresése (DFS)

  • Mélységi keresést ((DFS)) használsz, hogy megtaláld a blokkoló áramlást, amely nem hagy ki egyetlen potenciális utat sem a szintgráfban.

3. Áramlás frissítése

  • A blokkoló áramlást hozzáadod a meglévő áramláshoz, majd frissíted a reziduális gráfot.

4. Ismétlés

  • Új szintgráfot hozol létre, és megismétled a folyamatot, amíg nincs több blokkoló áramlás.



Időbonyolultság

  • Általános eset: (O(V^2E)), ahol (V) a csúcsok száma, (E) az élek száma.
  • Egységkapacitású hálózat: (O(E )).



Pszeudokód

DinicAlgorithm(G, s, t):
    max_flow = 0

    amíg True:
        # Szintgráf építése (BFS)
        level = BFS(G, s, t)
        ha level[t] == -1:
            térj vissza max_flow

        # Blokkoló áramlás keresése (DFS)
        while True:
            flow = DFS(G, s, t, ∞, level)
            ha flow == 0:
                break
            max_flow += flow

function BFS(G, s, t):
    szintek = [-1] * len(G)
    szintek[s] = 0
    sor = [s]

    amíg sor nem üres:
        u = sor.pop(0)
        minden v szomszédos u-val:
            ha szintek[v] == -1 és kapacitás(u, v) > 0:
                szintek[v] = szintek[u] + 1
                sor.append(v)

    térj vissza szintek

function DFS(G, u, t, flow, level):
    ha u == t:
        térj vissza flow

    minden v szomszédos u-val:
        ha szint[u] + 1 == szint[v] és kapacitás(u, v) > 0:
            min_flow = min(flow, kapacitás(u, v))
            pushed = DFS(G, v, t, min_flow, level)
            ha pushed > 0:
                kapacitás(u, v) -= pushed
                kapacitás(v, u) += pushed
                térj vissza pushed

    térj vissza 0

Python implementáció

from collections import deque, defaultdict

class Dinic:
    def __init__(self, n):
        self.n = n
        self.graph = defaultdict(list)
        self.capacity = defaultdict(lambda: defaultdict(int))

    def add_edge(self, u, v, cap):
        self.graph[u].append(v)
        self.graph[v].append(u)
        self.capacity[u][v] += cap  # Több él esetén is összeadjuk a kapacitást

    def bfs(self, s, t):
        level = [-1] * self.n
        level[s] = 0
        queue = deque([s])
        while queue:
            u = queue.popleft()
            for v in self.graph[u]:
                if level[v] == -1 and self.capacity[u][v] > 0:
                    level[v] = level[u] + 1
                    queue.append(v)
        return level

    def dfs(self, u, t, flow, level, start):
        if u == t:
            return flow
        while start[u] < len(self.graph[u]):
            v = self.graph[u][start[u]]
            if level[u] + 1 == level[v] and self.capacity[u][v] > 0:
                min_cap = min(flow, self.capacity[u][v])
                pushed = self.dfs(v, t, min_cap, level, start)
                if pushed > 0:
                    self.capacity[u][v] -= pushed
                    self.capacity[v][u] += pushed
                    return pushed
            start[u] += 1
        return 0

    def max_flow(self, s, t):
        total_flow = 0
        while True:
            level = self.bfs(s, t)
            if level[t] == -1:
                break
            start = [0] * self.n
            while True:
                flow = self.dfs(s, t, float('inf'), level, start)
                if flow == 0:
                    break
                total_flow += flow
        return total_flow

# Példa használat
n = 6  # csúcsok száma
dinic = Dinic(n)
dinic.add_edge(0, 1, 10)
dinic.add_edge(0, 2, 10)
dinic.add_edge(1, 2, 2)
dinic.add_edge(1, 3, 4)
dinic.add_edge(1, 4, 8)
dinic.add_edge(2, 4, 9)
dinic.add_edge(3, 5, 10)
dinic.add_edge(4, 5, 10)

print("Maximális áramlás:", dinic.max_flow(0, 5))

Kimenet:

Maximális áramlás: 19

Előnyök

  1. Hatékonyság:
    • Az iteratív szintgráf-építés és blokkoló áramlás gyorsítja az algoritmust.
  2. Skálázhatóság:
    • Nagy és ritka gráfok esetén is hatékony.
  3. Egyszerűség:
    • Bár bonyolultnak tűnik, az implementáció logikusan felépíthető.



Hátrányok

  1. Memóriaigény:
    • Nagy gráfok esetén jelentős memóriát igényel a reziduális gráf tárolása.
  2. Speciális esetek:
    • Nagyon sűrű gráfoknál nem biztos, hogy gyorsabb, mint más algoritmusok (pl. Edmonds-Karp).



Alkalmazások

  1. Hálózati optimalizáció:
    • Adatátvitel optimalizálása számítógépes hálózatokon.
  2. Logisztikai problémák:
    • Maximális árufolyam tervezése.
  3. Áramkörök:
    • Elektromos áram optimalizálása.
  4. Játékok:
    • Győzelmi stratégiák számítása gráfreprezentált problémákban.



Összegzés

A Dinic-algoritmus egy hatékony és széles körben alkalmazott módszer a maximális áramlás problémájának megoldására. Az iteratív szintgráf-alapú megközelítésével gyors és megbízható eredményt ad, különösen ritka gráfok esetén. Az algoritmus egyszerű logikája és optimalizált működése miatt népszerű választás a modern hálózatok és optimalizációs problémák megoldására.