Zaawansowane algorytmy i struktury danych/Wykład 9: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Sank (dyskusja | edycje)
Nie podano opisu zmian
m Zastępowanie tekstu – „.</math>” na „</math>”
 
(Nie pokazano 20 wersji utworzonych przez 4 użytkowników)
Linia 1: Linia 1:
<flash>file=Zasd_Ilustr_b.swf |width=400|height=300</flash>
== Abstrakt ==
<flash>file=Zasd_Ilustr_e.swf |width=600|height=300</flash>
 
<flash>file=Zasd_Ilustr_l.swf |width=600|height=300</flash>
Wykład ten poświęcony będzie problemowi znajdowania maksymalnego przepływu w grafie. Zaczniemy od wprowadzenia potrzebnych pojęć, a następnie przestawimy metodę Forda-Fulkersona znajdowania maksymalnego przepływu w grafie.
 
== Podstawowe pojęcia ==
'''Siecią przepływową''', bądź krótko '''siecią''', nazywamy skierowany graf <math>G = (V,E)</math>, w którym z każdą krawędzią <math>(u,v) \in E</math> wiążemy jej nieujemną przepustowość <math>c(u,v) \ge 0</math>. W sieci przepływowej wyróżniamy dwa wierzchołki: '''źródło''' oznaczane jako <math>s</math> oraz '''ujście''' oznaczane jako <math>t</math>.
 
Niech <math>G</math> będzie siecią oraz niech <math>c:E \to \mathcal{R}_+</math> będzie dla niej funkcją przypisującą przepustowości. '''Przepływem''' w <math>G</math> nazwiemy funkcję <math>f:V \times V \to \mathcal{R}</math> spełniającą następujące właściwości:
* Dla wszystkich <math>u,v \in V</math> zachodzi <math>f(u,v) \le c(u,v)</math> - warunek ten nazywamy warunkiem '''ograniczenia przepustowości'''.
* Dla wszystkich <math>u,v \in V</math> zachodzi <math>f(u,v) = -f(v,u)</math> - jest to warunek '''skośnej symetrii'''.
* Dla wszystkich <math>u \in V -\{s,t\}</math> żądamy aby zachodził warunek '''zachowania przepływu''':
{{wzor2|1=
<math>
\sum_{v\in V} f(u,v) = 0.
</math>
}}
 
O wartości <math>f(u,v)</math> mówimy, że jest to wielkość przepływu z <math>u</math> do <math>v</math>. '''Wartość''' przepływu <math>f</math>, oznaczamy <math>|f|</math> i definiujemy jako sumaryczną wielkość przepływu wypływającego z <math>s</math> wszystkimi krawędziami, tzn.:
{{wzor2|1=
<math>
|f| = \sum_{u \in V} f(s,u).
</math>
}}
 
W '''problemie maksymalnego przepływu''' dla danej sieci chcemy znaleźć przepływ o największej wartości.
 
W dalszej części wykładu używać będziemy następującej notacji sumacyjnej, w której argument funkcji <math>f:X \to Y</math> może być podzbiorem <math>A</math> dziedziny <math>X</math>. W takim wypadku przyjmujemy, że wartością funkcji <math>f</math> jest suma jej wartości dla zbioru <math>A</math>, tzn.:
{{wzor2|1=
<math>
f(X,Y) = \sum_{x \in X} \sum_{y \in Y} f(x,y).
</math>
}}
 
Używając tej notacji, możemy zapisać warunek zachowania przepływu dla wierzchołka <math>v</math> jako <math>f(v,V) = 0</math>. W poniższym lemacie używamy tej notacji do zapisania podstawowych właściwości przepływu.
 
{{lemat|1|lemat_1|3=
Niech <math>G=(V,E)</math> będzie siecią przepływową oraz <math>f</math> przepływem w niej. Wtedy:
# Dla wszystkich <math>X \subseteq V</math> mamy <math>f(X,X) = 0</math>.
# Dla wszystkich <math>X,Y \subseteq V</math> mamy <math>f(X,Y) = -f(Y,X)</math>.
# Dla wszystkich <math>X,Y,Z \subseteq V</math> zachodzi:{{wzor2|1=<math>\begin{array}{r@{}c@{}l}
f(X \cup Y,Z) &=& f(X,Z) + f(Y,Z) - f(X \cap Y,Z) \mbox{ i } f(Z, X \cup Y)=\\ &=& f(Z,X) + f(Z,Y) - f(Z,X \cap Y).
\end{array}</math>
# <math>|f| = f(s,V) = f(V,t)</math>.
}}
}}
 
Dowód tego lematu pozostawiony jest jako [[../Ćwiczenia 8#zadanie_1|Zadanie 1]] do tego wykładu.
 
== Sieć rezydualna ==
 
Intuicyjnie, dla danej sieci przepływowej <math>G</math> i przepływu <math>f</math>, sieć rezydualna składa się z krawędzi, którymi można przesłać większy przepływ. Bardziej formalnie, przypuśćmy, że mamy sieć przepływową <math>G = (V, E)</math> ze źródłem <math>s</math> i ujściem <math>t</math> oraz niech <math>f</math> będzie przepływem w <math>G</math>. Rozważmy teraz parę wierzchołków <math>u, v \in V</math>. Ilość dodatkowego przepływu <math>c_f(u,v)</math>, którą możemy przesłać z <math>u</math> do <math>v</math>, zanim przekroczymy przepustowość
<math>c(u, v)</math>, wynosi
 
{{wzor2|1=
<math>c_f(u,v) = c(u,v) - f(u,v)</math>
}}
 
Na przykład, jeśli <math>c(u, v) = 16</math> i <math>f(u, v) = 11</math>, wtedy możemy zwiększyć <math>f(u, v)</math> o <math>c_f (u, v) = 5</math> jednostek, zanim przekroczymy ograniczenie przepustowości krawędzi <math>(u, v)</math>.
 
Dla danej sieci <math>G = (V, E)</math> i przepływu <math>f</math>, sieć rezydualna <math>G</math> zaindukowana przez <math>f</math> to graf <math>G_f = (V, E_f)</math>, gdzie:
 
{{wzor2|1=
<math>
E_f = \{(u, v) \in V \times V : c_f(u, v) > 0\}.
</math>
}}
 
To znaczy, tak jak napisaliśmy powyżej, że każdą krawędzią sieci rezydualnej lub '''krawędzią rezydualną''' można przepuścić przepływ, który jest większy niż 0.
 
Krawędzie w <math>E_f</math> są albo krawędziami w <math>E</math>, albo krawędziami o odwróconym kierunku. Jeśli zachodzi <math>f(u, v) < c(u, v)</math> dla krawędzi <math>(u, v)\in E</math>, to wtedy <math>c_f(u,v) = c(u, v) - f(u, v) > 0</math> i <math>(u, v) \in E_f</math>. Jeśli <math>f(u, v) > 0</math> dla krawędzi <math>(u, v) \in E</math>, to wtedy <math>f (v, u) < 0</math>. W tym przypadku, <math>c_f(v, u) = c(v, u) - f(v, u) > 0</math>, i dlatego <math>(v, u) \in E_f</math>. Jeśli ani <math>(u, v)</math> ani <math>(v, u)</math> nie pojawiają się w pierwotnej sieci, to wówczas <math>c(u, v) = c(v, u) = 0</math> i <math>f(u, v) = f(v, u) = 0</math>, a zatem też <math>c_f(u, v) = c_f(v, u) = 0</math>. Podsumowując, krawędź <math>(u, v)</math> może się pojawić w sieci rezydualnej tylko wtedy, kiedy co najmniej jedna z krawędzi <math>(u, v)</math> i <math>(v, u)</math> jest w pierwotnej sieci. Dlatego też <math>|E_f| \le 2 |E|</math>. Należy zauważyć, że sieć rezydualna <math>G_f</math> jest także siecią przepływową o przepustowości krawędzi zadanej przez <math>c_f</math>. Następujący lemat pokazuje, jak przepływ w rezydualnej sieci powiązany jest z przepływem w pierwotnej sieci przepływów.
 
{{lemat|1|lemat_1|3=
Niech <math>G = (V, E)</math> będzie siecią przepływową ze źródłem <math>s</math> i ujściem <math>t</math> i niech <math>f</math> będzie przepływem w <math>G</math>. Niech <math>G_f</math> będzie siecią rezydualną dla <math>G</math>, indukowaną przez <math>f</math>, i niech <math>f'</math> będzie przepływem w <math>G_f</math>. Wtedy suma przepływów <math>f + f'</math> jest przepływem w <math>G</math> o wartości <math>|f + f'| = |f| + |f'|</math>.
}}
 
{{dowod|||3=Po pierwsze musimy pokazać, że dla sumy przepływów warunki, symetrii skośnej, ograniczenia przepustowości jak i zachowania przepływu są spełnione. W przypadku symetrii skośnej zauważmy, że dla wszystkich <math>u, v \in V</math>, mamy:
 
{{wzor2|1=
<math>
\begin{array}{r@{}c@{}l}
(f + f')(u, v) &=& f(u, v) + f'(u, v) = -f(v, u) - f'(v, u) =\\&=& -(f(v, u) + f'(v, u))= -(f + f')(v, u).
\end{array}</math>
}}
 
W przypadku ograniczenia przepustowości zauważmy, ze <math>f'(u, v) \le c_f(u, v)</math> dla wszystkich <math>u, v \in V</math> i dlatego:
 
{{wzor2|1=
<math>(f + f')(u, v) = f(u, v) + f'(u, v) \le f(u, v) + (c(u, v) - f(u, v)) = c(u, v)</math>
}}
 
W przypadku warunku zachowania przepływu, należy zauważyć, że dla wszystkich <math>u \in V - {s, t}</math>, mamy:
 
{{wzor2|1=
<math>\begin{array}{r@{}c@{}l}\sum_{v \in V}(f+f')(u,v) &=& \sum_{v \in V}(f(u,v) + f'(u,v))
=\\&=& \sum_{v\in V}f(u,v) + \sum_{v\in V}f(u,v) = 0 + 0 = 0.\end{array}</math>
}}
 
Ostatecznie otrzymujemy, że wartość <math>f+ f'</math> wynosi:
 
{{wzor2|1=
<math>\begin{array}{r@{}c@{}l}|f + f'| &=& \sum_{v \in V}(f + f')(s,v) = \sum_{v \in V}(f(s,v) + f'(s,v))
=\\&=& \sum_{v \in V}f(s,v) + \sum_{v\in V}f'(s,v) = |f| + |f'|.\end{array}</math>
}}
}}
 
== Ścieżki powiększające ==
 
Jeśli dana jest sieć przepływowa <math>G = (V, E)</math> i przepływ <math>f</math>, wówczas '''ścieżka powiększająca''' <math>p</math> jest ścieżką prostą z <math>s</math> do <math>t</math> w rezydualnej sieci <math>G_f</math>. Z definicji sieci rezydualnej, każda krawędź <math>(u, v)</math> na ścieżce powiększającej pozwala na przesłanie pewnego dodatkowego przepływu z <math>u</math> do <math>v</math> bez naruszenia ograniczenia przepustowości krawędzi. Znajdowanie ścieżki powiększającej w sieci rezydualnej, a następnie powiększenie przy jej pomocy przepływu zobrazowane jest na następującej animacji.
 
[[File:Zasd_ilustr_l.svg|800x300px|thumb|center]]
Najwyższą wartość, o jaką można zwiększyć przepływ przy użyciu ścieżki <math>p</math>, nazywamy '''rezydualną przepustowością''' <math>p</math>. Wielkość ta jest dana przez:
 
{{wzor2|1=
<math>c_f(p) = \min \{c_f(u, v) : (u, v) \mbox{ jest na } p\}</math>
}}
 
Zdefiniujmy tę zmianę przepływu związaną ze ścieżką <math>p</math> jako funkcję <math>f_p : V \times V \to R</math> równą:
 
{{wzor|wzor_1|1|3=
<math>f_p(u,v) = \begin{cases}
c_f(p) & \mbox{jeżeli } (u,v) \mbox{ jest na } p,\\
-c_f(p) & \mbox{jeżeli } (v,u) \mbox{ jest na } p,\\
0 & \mbox{w przeciwnym przypadku}.
\end{cases}
</math>}}
 
Wówczas <math>f_p</math> jest przepływem w <math>G_f</math> o wartości <math>|f_p| = c_f(p) > 0</math>. Dodając <math>f_p</math> do <math>f</math>, otrzymamy kolejny przepływ w <math>G</math>, którego wartość jest bliższa maksimum, co sformułowane jest w tym wniosku.
 
{{wniosek|2|wniosek_2|3=
Niech <math>G = (V, E)</math> będzie siecią przepływową, niech <math>f</math> będzie przepływem w <math>G</math> i niech <math>p</math> będzie ścieżką powiększającą w <math>G_f</math>. Niech <math>f_p</math> będzie zdefiniowane jak we [[#wzor_1|wzorze 1]]. Zdefiniujmy funkcję <math>f' : V \times V \to \mathcal{R}</math> jako <math>f' = f + f_p</math>, wówczas <math>f'</math> jest przepływem w <math>G</math> o wartości <math>|f'| = |f| + |f_p| > |f|</math>.
}}
 
== Przekroje w sieci ==
 
Twierdzenie o maksymalnym przepływie i minimalnym przekroju, które za chwilę udowodnimy, pokazuje że przepływ jest maksymalny wtedy i tylko wtedy, kiedy jego sieć rezydualna nie zawiera żadnej ścieżki powiększającej. Jednak, aby udowodnić to twierdzenie, musimy wpierw wprowadzić pojęcie przekroju sieci przepływowej. '''Przekrój''' <math>(S,T)</math> sieci przepływowej <math>G = (V,E)</math> jest podziałem <math>V</math> na <math>S</math> i <math>T = V - S</math> tak, że <math>s\in S</math> i <math>t \in T</math>. Jeśli <math>f</math> jest przepływem, wtedy '''przepływ netto''' poprzez przekrój <math>(S,T)</math> jest zdefiniowany jako <math>f(S, T)</math>. '''Przepustowość przekroju''' <math>(S,T)</math> definiujemy jako <math>c(S,T)</math>. Minimalnym przekrojem sieci jest przekrój, którego przepustowość jest najmniejsza ze wszystkich przekrojów w sieci.
 
Poniższa ilustracja pokazuje przekrój <math>(\{s, v_1, v_2\}, \{v_3, v_4, t\})</math> w sieci przepływów. Przepływ netto poprzez ten przekrój wynosi:
<math>f(v_1, v_3) + f(v_2, v_3) + f(v_2, v_4) = 12 + (-4) + 11
= 19</math>, a jego przepustowość wynosi <math>c(v_1, v_3) + c(v_2, v_4) = 12 + 14 = 26</math>.
 
[[File:Zasd_ilustr_b.svg|800x250px|thumb|center]]
 
Należy zaobserwować, że przepływ netto w przekroju może zawierać negatywny przepływy pomiędzy wierzchołkami, jednakże przepustowość przekroju składa się wyłącznie z nieujemnych wartości. Innymi słowy, przepływ netto poprzez przekrój <math>(S,T)</math> składa się z dodatnich przepływów płynących w dwa kierunki; dodatni przepływ z <math>S</math> do <math>T</math> jest dodawany, podczas gdy dodatni przepływ z <math>T</math> do <math>S</math> jest odejmowany. Z drugiej strony, przepustowość przekroju <math>(S,T)</math> jest obliczana tylko od krawędzi odchodzących z <math>S</math> do <math>T</math>. Krawędzie biegnące z <math>T</math> do <math>S</math> nie są włączone do obliczeń <math>c(S,T)</math>. Powyższy lemat pokazuje, że przepływ netto przez jakikolwiek przekrój jest taki sam i równy jest wartości przepływu.
 
<div></div>
{{lemat|3|lemat_3|3=
Nich <math>f</math> będzie przepływem w sieci przepływów <math>G</math> ze źródłem <math>s</math> i ujściem <math>t</math> i niech <math>(S,T)</math> będzie przekrojem w <math>G</math>. Wtedy przepływ netto przez <math>(S,T)</math> wynosi <math>f(S, T) = |f|</math>.}}
 
{{dowod|||3=Zauważmy, że <math>f (S - s, V) = 0</math> z warunku zachowania przepływu, dlatego:
 
{{wzor2|1=
<math>f(S, T) = f (S, V) - f(S, S) =f(s, V) + f(S - s, V) = f(s, V) = |f|</math>
}}}}
 
Jako w wniosek z tego lematu otrzymujemy, że przepustowość przekroju jest graniczeniem wartości przepływu.
 
 
{{wniosek|4|wniosek_4|3=
Wartość dowolnego przepływu <math>f</math> w sieci przepływów <math>G</math> jest ograniczona z góry przez przepustowość dowolnego przekroju w <math>G</math>.
}}
 
{{dowod|||3
Niech <math>(S,T)</math> będzie dowolnym przekrojem w <math>G</math> i niech <math>f</math> będzie dowolnym przepływem. Z [[#lemat_3|lematu 3]] i  warunku ograniczenia przepustowości otrzymujemy:
 
{{wzor2|1=
<math>|f| = f(S,T) = \sum_{u \in S} \sum_{v \in T} f(u,v) \le \sum_{u \in S} \sum_{v \in T} c(u,v) = c(S,T)</math>
}}
}}
 
W szczególności maksymalny przepływ w sieci jest ograniczony od góry przez przepustowość najmniejszego przekroju w sieci. Twierdzenie o maksymalnym przepływie i minimalnym przekroju, które teraz postawimy i udowadnimy, mówi że wartość maksymalnego przepływu jest w rzeczywistości równa przepustowości najmniejszego przekroju.
 
{{twierdzenie|5 [O maksymalnym przepływie i minimalnym przekroju]|twierdzenie_5|3=Jeśli <math>f</math> jest przepływem w sieci przepływowej <math>G = (V, E)</math> ze źródłem <math>s</math> i ujściem <math>t</math>, wówczas następujące warunki są równoważne:
# <math>f</math> jest maksymalnym przepływem w <math>G</math>.
# Sieć rezydualna <math>G_f</math> nie zawiera żadnych ścieżek powiększających.
# <math>|f| = c(S, T)</math> dla pewnego przekroju <math>(S, T)</math> w <math>G</math>.
}}
 
{{dowod|||3=
(1)<math>\to</math>(2): Załóżmy przez sprzeczność, że <math>f</math> jest maksymalnym przepływem w <math>G</math>, ale że <math>G_f</math> posiada ścieżkę powiększającą <math>p</math>. Wówczas, z [[#wnisek 2|wniosku 2]], suma przepływów <math>f + f_p</math>, gdzie <math>f_p</math> jest dane [[#wzor_1|wzorem 1]], jest przepływem w <math>G</math> o wartości ściśle większej niż <math>|f|</math>, co jest sprzeczne z założeniem, że <math>f</math> jest przepływem maksymalnym.
 
(2)<math>\to</math>(3): Przypuśćmy, że <math>G_f</math> nie posiada żadnej ścieżki powiększającej, to znaczy że <math>G_f</math> nie posiada żadnej ścieżki z <math>s</math> do <math>t</math>. Zdefiniujmy:
 
{{wzor2|1=
<math>S = \{v \in V : \mbox{ istnieje ścieżka z } s \mbox{ do } v \mbox{ w } G_f\}</math>,
}}
 
oraz:
 
{{wzor2|1=  
<math>T = V - S</math>.
}}
 
Podział <math>(S, T)</math> jest przekrojem: oczywiście <math>s \in S</math> i <math>t\in T</math>, ponieważ nie ma żadnej ścieżki z <math>s</math> do <math>t</math> w <math>G_f</math>. Dla każdej pary wierzchołków <math>u \in S</math> i <math>v \in T</math>, mamy <math>f(u, v) = c(u, v)</math>, gdyż w przeciwnym wypadku <math>(u, v) \in E_f</math>, co umiejscowiłoby <math>v</math> w zbiorze <math>S</math>. Dlatego też, z [[#lemat3|lematu 3]], mamy <math>|f| = f(S, T) = c(S, T)</math>.
 
(3)<math>\to</math>(1): Z [[#wniosek_4|wniosku 4]] wiemy, że <math>|f| \le c(S, T)</math> dla wszystkich przekrojów <math>(S, T)</math>. Czyli warunek <math>|f| = c(S, T)</math> oznacza, że <math>f</math> jest przepływem maksymalnym.
}}
 
== Algorytm Forda – Fulkersona ==
 
W każdej iteracji  metody Forda–Fulkersona odnajdujemy dowolną ścieżkę powiększającą <math>p</math> i zwiększamy przepływ <math>f</math> na każdej krawędzi <math>p</math> o przepustowość rezydualną <math>c_f(p)</math>. Poniżej zamieszczamy implementacje tej metody.
 
{{algorytm|[Forda-Fulkersona] znajduje przepływ maksymalny w grafie <math>G</math>|algorytm_Forda-Fulkersona|
3=
  FORD-FULKERSON(<math>G = (V,E), s, t</math>)
  1 '''for''' każda krawędź <math>(u, v)\in E</math> '''do'''
  2 '''begin'''
  3  <math>f(u, v) = 0</math>
  4  <math>f(v, u) = 0</math>
  5  '''end'''
  6  '''while''' istnieje ścieżka <math>p</math> z <math>s</math> do <math>t</math> w sieci rezydualnej <math>G_f</math> '''do'''
  7  '''begin'''
  8    <math>c_f(p) =  \min \{c_f(u, v) : (u, v) \in  p\}</math>
  9    '''for''' każda krawędź <math>(u, v) \in p</math> '''do'''
  10  '''begin'''
  11    <math>f(u, v) = f(u, v) + c_f(p)</math>
  12    <math>f(v, u) = -f(u, v)</math>
  13  '''end'''
  14 '''end'''
  15 '''return''' <math>f</math>
}}
 
Działanie tego algorytmu przestawione jest na następującej animacji.
[[File:Zasd_ilustr_r.svg|800x300px|thumb|center]]
Czas działania metody Forda-Fuklersona zależy od wyboru ścieżki powiększającej. Jeżeli będziemy ją wybierać źle, to algorytm wręcz może się nie zakończyć. W przypadku, gdy przepustowości krawędzi są całkowito liczbowe, to łatwo możemy pokazać, że czas działania tego algorytmu wynosi <math>O(E|f^*|)</math>, gdzie <math>f^*</math> jest przepływem maksymalnym w sieci. Jeżeli przepływ <math>f^*</math> jest mały, to algorytm ten działa szybko, jednak może się zdarzyć, nawet dla prostego przykładu, że algorytm będzie musiał wykonać <math>f^*</math> iteracji. Taki przykład pokazany jest na poniższej animacji.
 
<flash>file=zasd_ilustr_e.swf |width=800|height=300</flash>

Aktualna wersja na dzień 11:25, 5 wrz 2023

Abstrakt

Wykład ten poświęcony będzie problemowi znajdowania maksymalnego przepływu w grafie. Zaczniemy od wprowadzenia potrzebnych pojęć, a następnie przestawimy metodę Forda-Fulkersona znajdowania maksymalnego przepływu w grafie.

Podstawowe pojęcia

Siecią przepływową, bądź krótko siecią, nazywamy skierowany graf G=(V,E), w którym z każdą krawędzią (u,v)E wiążemy jej nieujemną przepustowość c(u,v)0. W sieci przepływowej wyróżniamy dwa wierzchołki: źródło oznaczane jako s oraz ujście oznaczane jako t.

Niech G będzie siecią oraz niech c:E+ będzie dla niej funkcją przypisującą przepustowości. Przepływem w G nazwiemy funkcję f:V×V spełniającą następujące właściwości:

  • Dla wszystkich u,vV zachodzi f(u,v)c(u,v) - warunek ten nazywamy warunkiem ograniczenia przepustowości.
  • Dla wszystkich u,vV zachodzi f(u,v)=f(v,u) - jest to warunek skośnej symetrii.
  • Dla wszystkich uV{s,t} żądamy aby zachodził warunek zachowania przepływu:
vVf(u,v)=0.

O wartości f(u,v) mówimy, że jest to wielkość przepływu z u do v. Wartość przepływu f, oznaczamy |f| i definiujemy jako sumaryczną wielkość przepływu wypływającego z s wszystkimi krawędziami, tzn.:

|f|=uVf(s,u).

W problemie maksymalnego przepływu dla danej sieci chcemy znaleźć przepływ o największej wartości.

W dalszej części wykładu używać będziemy następującej notacji sumacyjnej, w której argument funkcji f:XY może być podzbiorem A dziedziny X. W takim wypadku przyjmujemy, że wartością funkcji f jest suma jej wartości dla zbioru A, tzn.:

f(X,Y)=xXyYf(x,y).

Używając tej notacji, możemy zapisać warunek zachowania przepływu dla wierzchołka v jako f(v,V)=0. W poniższym lemacie używamy tej notacji do zapisania podstawowych właściwości przepływu.

Lemat 1

Niech G=(V,E) będzie siecią przepływową oraz f przepływem w niej. Wtedy:
  1. Dla wszystkich XV mamy f(X,X)=0.
  2. Dla wszystkich X,YV mamy f(X,Y)=f(Y,X).
  3. Dla wszystkich X,Y,ZV zachodzi:
    Parser nie mógł rozpoznać (nieznana funkcja „\begin{array}”): {\displaystyle \begin{array}{r@{}c@{}l} f(X \cup Y,Z) &=& f(X,Z) + f(Y,Z) - f(X \cap Y,Z) \mbox{ i } f(Z, X \cup Y)=\\ &=& f(Z,X) + f(Z,Y) - f(Z,X \cap Y). \end{array}}
  4. |f|=f(s,V)=f(V,t).

Dowód tego lematu pozostawiony jest jako Zadanie 1 do tego wykładu.

Sieć rezydualna

Intuicyjnie, dla danej sieci przepływowej G i przepływu f, sieć rezydualna składa się z krawędzi, którymi można przesłać większy przepływ. Bardziej formalnie, przypuśćmy, że mamy sieć przepływową G=(V,E) ze źródłem s i ujściem t oraz niech f będzie przepływem w G. Rozważmy teraz parę wierzchołków u,vV. Ilość dodatkowego przepływu cf(u,v), którą możemy przesłać z u do v, zanim przekroczymy przepustowość c(u,v), wynosi

cf(u,v)=c(u,v)f(u,v)

Na przykład, jeśli c(u,v)=16 i f(u,v)=11, wtedy możemy zwiększyć f(u,v) o cf(u,v)=5 jednostek, zanim przekroczymy ograniczenie przepustowości krawędzi (u,v).

Dla danej sieci G=(V,E) i przepływu f, sieć rezydualna G zaindukowana przez f to graf Gf=(V,Ef), gdzie:

Ef={(u,v)V×V:cf(u,v)>0}.

To znaczy, tak jak napisaliśmy powyżej, że każdą krawędzią sieci rezydualnej lub krawędzią rezydualną można przepuścić przepływ, który jest większy niż 0.

Krawędzie w Ef są albo krawędziami w E, albo krawędziami o odwróconym kierunku. Jeśli zachodzi f(u,v)<c(u,v) dla krawędzi (u,v)E, to wtedy cf(u,v)=c(u,v)f(u,v)>0 i (u,v)Ef. Jeśli f(u,v)>0 dla krawędzi (u,v)E, to wtedy f(v,u)<0. W tym przypadku, cf(v,u)=c(v,u)f(v,u)>0, i dlatego (v,u)Ef. Jeśli ani (u,v) ani (v,u) nie pojawiają się w pierwotnej sieci, to wówczas c(u,v)=c(v,u)=0 i f(u,v)=f(v,u)=0, a zatem też cf(u,v)=cf(v,u)=0. Podsumowując, krawędź (u,v) może się pojawić w sieci rezydualnej tylko wtedy, kiedy co najmniej jedna z krawędzi (u,v) i (v,u) jest w pierwotnej sieci. Dlatego też |Ef|2|E|. Należy zauważyć, że sieć rezydualna Gf jest także siecią przepływową o przepustowości krawędzi zadanej przez cf. Następujący lemat pokazuje, jak przepływ w rezydualnej sieci powiązany jest z przepływem w pierwotnej sieci przepływów.

Lemat 1

Niech G=(V,E) będzie siecią przepływową ze źródłem s i ujściem t i niech f będzie przepływem w G. Niech Gf będzie siecią rezydualną dla G, indukowaną przez f, i niech f będzie przepływem w Gf. Wtedy suma przepływów f+f jest przepływem w G o wartości |f+f|=|f|+|f|.

Dowód

Po pierwsze musimy pokazać, że dla sumy przepływów warunki, symetrii skośnej, ograniczenia przepustowości jak i zachowania przepływu są spełnione. W przypadku symetrii skośnej zauważmy, że dla wszystkich u,vV, mamy:
Parser nie mógł rozpoznać (nieznana funkcja „\begin{array}”): {\displaystyle \begin{array}{r@{}c@{}l} (f + f')(u, v) &=& f(u, v) + f'(u, v) = -f(v, u) - f'(v, u) =\\&=& -(f(v, u) + f'(v, u))= -(f + f')(v, u). \end{array}}

W przypadku ograniczenia przepustowości zauważmy, ze f(u,v)cf(u,v) dla wszystkich u,vV i dlatego:

(f+f)(u,v)=f(u,v)+f(u,v)f(u,v)+(c(u,v)f(u,v))=c(u,v)

W przypadku warunku zachowania przepływu, należy zauważyć, że dla wszystkich uVs,t, mamy:

Parser nie mógł rozpoznać (nieznana funkcja „\begin{array}”): {\displaystyle \begin{array}{r@{}c@{}l}\sum_{v \in V}(f+f')(u,v) &=& \sum_{v \in V}(f(u,v) + f'(u,v)) =\\&=& \sum_{v\in V}f(u,v) + \sum_{v\in V}f(u,v) = 0 + 0 = 0.\end{array}}

Ostatecznie otrzymujemy, że wartość f+f wynosi:

Parser nie mógł rozpoznać (nieznana funkcja „\begin{array}”): {\displaystyle \begin{array}{r@{}c@{}l}|f + f'| &=& \sum_{v \in V}(f + f')(s,v) = \sum_{v \in V}(f(s,v) + f'(s,v)) =\\&=& \sum_{v \in V}f(s,v) + \sum_{v\in V}f'(s,v) = |f| + |f'|.\end{array}}

Ścieżki powiększające

Jeśli dana jest sieć przepływowa G=(V,E) i przepływ f, wówczas ścieżka powiększająca p jest ścieżką prostą z s do t w rezydualnej sieci Gf. Z definicji sieci rezydualnej, każda krawędź (u,v) na ścieżce powiększającej pozwala na przesłanie pewnego dodatkowego przepływu z u do v bez naruszenia ograniczenia przepustowości krawędzi. Znajdowanie ścieżki powiększającej w sieci rezydualnej, a następnie powiększenie przy jej pomocy przepływu zobrazowane jest na następującej animacji.

Plik:Zasd ilustr l.svg

Najwyższą wartość, o jaką można zwiększyć przepływ przy użyciu ścieżki p, nazywamy rezydualną przepustowością p. Wielkość ta jest dana przez:

cf(p)=min{cf(u,v):(u,v) jest na p}

Zdefiniujmy tę zmianę przepływu związaną ze ścieżką p jako funkcję fp:V×VR równą:

fp(u,v)={cf(p)jeżeli (u,v) jest na p,cf(p)jeżeli (v,u) jest na p,0w przeciwnym przypadku.      (1)

Wówczas fp jest przepływem w Gf o wartości |fp|=cf(p)>0. Dodając fp do f, otrzymamy kolejny przepływ w G, którego wartość jest bliższa maksimum, co sformułowane jest w tym wniosku.

Wniosek 2

Niech G=(V,E) będzie siecią przepływową, niech f będzie przepływem w G i niech p będzie ścieżką powiększającą w Gf. Niech fp będzie zdefiniowane jak we wzorze 1. Zdefiniujmy funkcję f:V×V jako f=f+fp, wówczas f jest przepływem w G o wartości |f|=|f|+|fp|>|f|.

Przekroje w sieci

Twierdzenie o maksymalnym przepływie i minimalnym przekroju, które za chwilę udowodnimy, pokazuje że przepływ jest maksymalny wtedy i tylko wtedy, kiedy jego sieć rezydualna nie zawiera żadnej ścieżki powiększającej. Jednak, aby udowodnić to twierdzenie, musimy wpierw wprowadzić pojęcie przekroju sieci przepływowej. Przekrój (S,T) sieci przepływowej G=(V,E) jest podziałem V na S i T=VS tak, że sS i tT. Jeśli f jest przepływem, wtedy przepływ netto poprzez przekrój (S,T) jest zdefiniowany jako f(S,T). Przepustowość przekroju (S,T) definiujemy jako c(S,T). Minimalnym przekrojem sieci jest przekrój, którego przepustowość jest najmniejsza ze wszystkich przekrojów w sieci.

Poniższa ilustracja pokazuje przekrój ({s,v1,v2},{v3,v4,t}) w sieci przepływów. Przepływ netto poprzez ten przekrój wynosi: f(v1,v3)+f(v2,v3)+f(v2,v4)=12+(4)+11=19, a jego przepustowość wynosi c(v1,v3)+c(v2,v4)=12+14=26.

Plik:Zasd ilustr b.svg

Należy zaobserwować, że przepływ netto w przekroju może zawierać negatywny przepływy pomiędzy wierzchołkami, jednakże przepustowość przekroju składa się wyłącznie z nieujemnych wartości. Innymi słowy, przepływ netto poprzez przekrój (S,T) składa się z dodatnich przepływów płynących w dwa kierunki; dodatni przepływ z S do T jest dodawany, podczas gdy dodatni przepływ z T do S jest odejmowany. Z drugiej strony, przepustowość przekroju (S,T) jest obliczana tylko od krawędzi odchodzących z S do T. Krawędzie biegnące z T do S nie są włączone do obliczeń c(S,T). Powyższy lemat pokazuje, że przepływ netto przez jakikolwiek przekrój jest taki sam i równy jest wartości przepływu.

Lemat 3

Nich f będzie przepływem w sieci przepływów G ze źródłem s i ujściem t i niech (S,T) będzie przekrojem w G. Wtedy przepływ netto przez (S,T) wynosi f(S,T)=|f|.

Dowód

Zauważmy, że f(Ss,V)=0 z warunku zachowania przepływu, dlatego:
f(S,T)=f(S,V)f(S,S)=f(s,V)+f(Ss,V)=f(s,V)=|f|

Jako w wniosek z tego lematu otrzymujemy, że przepustowość przekroju jest graniczeniem wartości przepływu.


Wniosek 4

Wartość dowolnego przepływu f w sieci przepływów G jest ograniczona z góry przez przepustowość dowolnego przekroju w G.

Dowód

3

Niech (S,T) będzie dowolnym przekrojem w G i niech f będzie dowolnym przepływem. Z lematu 3 i warunku ograniczenia przepustowości otrzymujemy:

|f|=f(S,T)=uSvTf(u,v)uSvTc(u,v)=c(S,T)

W szczególności maksymalny przepływ w sieci jest ograniczony od góry przez przepustowość najmniejszego przekroju w sieci. Twierdzenie o maksymalnym przepływie i minimalnym przekroju, które teraz postawimy i udowadnimy, mówi że wartość maksymalnego przepływu jest w rzeczywistości równa przepustowości najmniejszego przekroju.

Twierdzenie 5 [O maksymalnym przepływie i minimalnym przekroju]

Jeśli f jest przepływem w sieci przepływowej G=(V,E) ze źródłem s i ujściem t, wówczas następujące warunki są równoważne:
  1. f jest maksymalnym przepływem w G.
  2. Sieć rezydualna Gf nie zawiera żadnych ścieżek powiększających.
  3. |f|=c(S,T) dla pewnego przekroju (S,T) w G.

Dowód

(1)(2): Załóżmy przez sprzeczność, że f jest maksymalnym przepływem w G, ale że Gf posiada ścieżkę powiększającą p. Wówczas, z wniosku 2, suma przepływów f+fp, gdzie fp jest dane wzorem 1, jest przepływem w G o wartości ściśle większej niż |f|, co jest sprzeczne z założeniem, że f jest przepływem maksymalnym.

(2)(3): Przypuśćmy, że Gf nie posiada żadnej ścieżki powiększającej, to znaczy że Gf nie posiada żadnej ścieżki z s do t. Zdefiniujmy:

S={vV: istnieje ścieżka z s do v w Gf},

oraz:

T=VS.

Podział (S,T) jest przekrojem: oczywiście sS i tT, ponieważ nie ma żadnej ścieżki z s do t w Gf. Dla każdej pary wierzchołków uS i vT, mamy f(u,v)=c(u,v), gdyż w przeciwnym wypadku (u,v)Ef, co umiejscowiłoby v w zbiorze S. Dlatego też, z lematu 3, mamy |f|=f(S,T)=c(S,T).

(3)(1): Z wniosku 4 wiemy, że |f|c(S,T) dla wszystkich przekrojów (S,T). Czyli warunek |f|=c(S,T) oznacza, że f jest przepływem maksymalnym.

Algorytm Forda – Fulkersona

W każdej iteracji metody Forda–Fulkersona odnajdujemy dowolną ścieżkę powiększającą p i zwiększamy przepływ f na każdej krawędzi p o przepustowość rezydualną cf(p). Poniżej zamieszczamy implementacje tej metody.

Algorytm [Forda-Fulkersona] znajduje przepływ maksymalny w grafie G


 FORD-FULKERSON(G=(V,E),s,t)
 1 for każda krawędź (u,v)E do
 2 begin
 3   f(u,v)=0
 4   f(v,u)=0
 5  end
 6  while istnieje ścieżka p z s do t w sieci rezydualnej Gf do
 7  begin
 8    cf(p)=min{cf(u,v):(u,v)p}
 9    for każda krawędź (u,v)p do
 10   begin
 11     f(u,v)=f(u,v)+cf(p)
 12     f(v,u)=f(u,v)
 13   end
 14 end
 15 return f

Działanie tego algorytmu przestawione jest na następującej animacji.

Plik:Zasd ilustr r.svg

Czas działania metody Forda-Fuklersona zależy od wyboru ścieżki powiększającej. Jeżeli będziemy ją wybierać źle, to algorytm wręcz może się nie zakończyć. W przypadku, gdy przepustowości krawędzi są całkowito liczbowe, to łatwo możemy pokazać, że czas działania tego algorytmu wynosi O(E|f*|), gdzie f* jest przepływem maksymalnym w sieci. Jeżeli przepływ f* jest mały, to algorytm ten działa szybko, jednak może się zdarzyć, nawet dla prostego przykładu, że algorytm będzie musiał wykonać f* iteracji. Taki przykład pokazany jest na poniższej animacji.

<flash>file=zasd_ilustr_e.swf |width=800|height=300</flash>