Zaawansowane algorytmy i struktury danych/Wykład 9: Różnice pomiędzy wersjami
Nie podano opisu zmian |
|||
Linia 12: | Linia 12: | ||
{{wzor2|1= | {{wzor2|1= | ||
<math> | <math> | ||
\sum_{v\in V} f(u,v | \sum_{v\in V} f(u,v) = 0. | ||
</math> | </math> | ||
}} | }} | ||
Linia 19: | Linia 19: | ||
{{wzor2|1= | {{wzor2|1= | ||
<math> | <math> | ||
|f| = \sum_{u \in V | |f| = \sum_{u \in V} f(s,u). | ||
</math> | </math> | ||
}} | }} | ||
Linia 36: | Linia 36: | ||
{{lemat|1|lemat_1|3= | {{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: | Niech <math>G=(V,E)</math> będzie siecią przepływową oraz <math>f</math> przepływem w niej. Wtedy: | ||
# Dla wszystkich <math>X \ | # Dla wszystkich <math>X \subseteq V</math> mamy <math>f(X,X) = 0</math>. | ||
# Dla wszystkich <math>X,Y \ | # Dla wszystkich <math>X,Y \subseteq V</math> mamy <math>f(X,Y) = -f(Y,X)</math>. | ||
# Dla wszystkich <math>X,Y,Z \ | # Dla wszystkich <math>X,Y,Z \subseteq V</math> zachodzi:{{wzor2|1=<math>\begin{array}{r@{}c@{}l} | ||
{{wzor2|1= | 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). | ||
<math> | \end{array}</math> | ||
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).</math> | |||
# <math>|f| = f(s,V) = f(V,t)</math>. | # <math>|f| = f(s,V) = f(V,t)</math>. | ||
}} | }} | ||
Linia 50: | Linia 49: | ||
== Sieć rezydualna == | == 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ć | 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 | <math>c(u, v)</math>, wynosi | ||
Linia 57: | Linia 56: | ||
}} | }} | ||
Na przykład, jeśli <math>c(u, v) = 16</math> i <math>f(u, v) = 11</math>, wtedy | 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 <math>G_f = (V, E_f)</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= | {{wzor2|1= | ||
Linia 69: | Linia 68: | ||
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. | 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 | 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= | {{lemat|1|lemat_1|3= | ||
Linia 78: | Linia 77: | ||
{{wzor2|1= | {{wzor2|1= | ||
<math>(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).</math> | <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> | |||
}} | }} | ||
Linia 90: | Linia 92: | ||
{{wzor2|1= | {{wzor2|1= | ||
<math>\sum_{v \in V}(f+f')(u,v) = \sum_{v \in V}(f(u,v) + f'(u,v)) | <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.</math> | =\\&=& \sum_{v\in V}f(u,v) + \sum_{v\in V}f(u,v) = 0 + 0 = 0.\end{array}</math> | ||
}} | }} | ||
Linia 97: | Linia 99: | ||
{{wzor2|1= | {{wzor2|1= | ||
<math>|f + f'| = \sum_{v \in V}(f + f')(s,v) = \sum_{v \in V}(f(s,v) + f'(s,v)) | <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'|.</math> | =\\&=& \sum_{v \in V}f(s,v) + \sum_{v\in V}f'(s,v) = |f| + |f'|.\end{array}</math> | ||
}} | }} | ||
}} | }} | ||
Linia 104: | Linia 106: | ||
== Ścieżki powiększające == | == Ś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 prostą | 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. | ||
<flash>file=Zasd_ilustr_l.swf |width= | <flash>file=Zasd_ilustr_l.swf |width=800|height=300</flash> | ||
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: | 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: | ||
Linia 114: | Linia 116: | ||
}} | }} | ||
Zdefiniujmy tę zmianę przepływu związaną ze ścieżką <math>p</math> jako funkcję <math>f_p : V | 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= | {{wzor|wzor_1|1|3= | ||
Linia 120: | Linia 122: | ||
c_f(p) & \mbox{jeżeli } (u,v) \mbox{ jest na } p,\\ | c_f(p) & \mbox{jeżeli } (u,v) \mbox{ jest na } p,\\ | ||
-c_f(p) & \mbox{jeżeli } (v,u) \mbox{ jest na } p,\\ | -c_f(p) & \mbox{jeżeli } (v,u) \mbox{ jest na } p,\\ | ||
0 & w przeciwnym przypadku. | 0 & \mbox{w przeciwnym przypadku}. | ||
\end{cases} | \end{cases} | ||
</math>}} | </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>. | 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. | ||
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= | {{wniosek|2|wniosek_2|3= | ||
Linia 134: | Linia 134: | ||
== Przekroje w sieci == | == Przekroje w sieci == | ||
Twierdzenie | 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: | 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( | <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>. | = 19</math>, a jego przepustowość wynosi <math>c(v_1, v_3) + c(v_2, v_4) = 12 + 14 = 26</math>. | ||
<flash>file=Zasd_ilustr_b.swf |width= | <flash>file=Zasd_ilustr_b.swf |width=800|height=250</flash> | ||
Należy zaobserwować, że przepływ netto w przekroju może zawierać | 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= | {{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>.}} | 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 | {{dowod|||3=Zauważmy, że <math>f (S - s, V) = 0</math> z warunku zachowania przepływu, dlatego: | ||
{{wzor2|1= | {{wzor2|1= | ||
<math>f(S, T) = f (S, V) - f(S, S) =f(s, V) + f(S - s, V) = f(s, V) = |f|.</math> | <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. | |||
Jako w wniosek z tego lematu otrzymujemy, że przepustowość przekroju jest graniczeniem | |||
Linia 166: | Linia 167: | ||
{{wzor2|1= | {{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> | <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: | |||
{{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ą | |||
# <math>f</math> jest maksymalnym przepływem w <math>G</math>. | # <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. | # 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>. | # <math>|f| = c(S, T)</math> dla pewnego przekroju <math>(S, T)</math> w <math>G</math>. | ||
}} | |||
{{dowod|||3= | {{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]] | (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 | (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= | {{wzor2|1= | ||
<math>S = \{v \in V : \mbox{ istnieje ścieżka z } s \mbox{ do } v \mbox{ w } G_f</math>, | <math>S = \{v \in V : \mbox{ istnieje ścieżka z } s \mbox{ do } v \mbox{ w } G_f\}</math>, | ||
}} | }} | ||
oraz <math>T = V - S</math>. Podział <math>(S, T)</math> jest przekrojem: oczywiście <math>s \in S</math> i <math>t\in | 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) | (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. | ||
}} | }} | ||
Linia 209: | Linia 217: | ||
11 <math>f(u, v) = f(u, v) + c_f(p)</math> | 11 <math>f(u, v) = f(u, v) + c_f(p)</math> | ||
12 <math>f(v, u) = -f(u, v)</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. | Działanie tego algorytmu przestawione jest na następującej animacji. | ||
<flash>file=Zasd_ilustr_r.swf |width= | <flash>file=Zasd_ilustr_r.swf |width=800|height=300</flash> | ||
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. | 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= | <flash>file=zasd_ilustr_e.swf |width=800|height=300</flash> |
Wersja z 09:32, 26 wrz 2006
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 , w którym z każdą krawędzią wiążemy jej nieujemną przepustowość . W sieci przepływowej wyróżniamy dwa wierzchołki: źródło oznaczane jako oraz ujście oznaczane jako .
Niech będzie siecią oraz niech będzie dla niej funkcją przypisującą przepustowości. Przepływem w nazwiemy funkcję spełniającą następujące właściwości:
- Dla wszystkich zachodzi - warunek ten nazywamy warunkiem ograniczenia przepustowości.
- Dla wszystkich zachodzi - jest to warunek skośnej symetrii.
- Dla wszystkich żądamy aby zachodził warunek zachowania przepływu:
O wartości mówimy, że jest to wielkość przepływu z do . Wartość przepływu , oznaczamy i definiujemy jako sumaryczną wielkość przepływu wypływającego z wszystkimi krawędziami, tzn.:
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 może być podzbiorem dziedziny . W takim wypadku przyjmujemy, że wartością funkcji jest suma jej wartości dla zbioru , tzn.:
Używając tej notacji, możemy zapisać warunek zachowania przepływu dla wierzchołka jako . W poniższym lemacie używamy tej notacji do zapisania podstawowych właściwości przepływu.
Lemat 1
- Dla wszystkich mamy .
- Dla wszystkich mamy .
- Dla wszystkich 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}} - .
Dowód tego lematu pozostawiony jest jako Zadanie 1 do tego wykładu.
Sieć rezydualna
Intuicyjnie, dla danej sieci przepływowej i przepływu , 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ą ze źródłem i ujściem oraz niech będzie przepływem w . Rozważmy teraz parę wierzchołków . Ilość dodatkowego przepływu , którą możemy przesłać z do , zanim przekroczymy przepustowość , wynosi
Na przykład, jeśli i , wtedy możemy zwiększyć o jednostek, zanim przekroczymy ograniczenie przepustowości krawędzi .
Dla danej sieci i przepływu , sieć rezydualna zaindukowana przez to graf , gdzie:
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 są albo krawędziami w , albo krawędziami o odwróconym kierunku. Jeśli zachodzi dla krawędzi , to wtedy i . Jeśli dla krawędzi , to wtedy . W tym przypadku, , i dlatego . Jeśli ani ani nie pojawiają się w pierwotnej sieci, to wówczas i , a zatem też . Podsumowując, krawędź może się pojawić w sieci rezydualnej tylko wtedy, kiedy co najmniej jedna z krawędzi i jest w pierwotnej sieci. Dlatego też . Należy zauważyć, że sieć rezydualna jest także siecią przepływową o przepustowości krawędzi zadanej przez . 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
Dowód
W przypadku ograniczenia przepustowości zauważmy, ze dla wszystkich i dlatego:
W przypadku warunku zachowania przepływu, należy zauważyć, że dla wszystkich , mamy:
Ostatecznie otrzymujemy, że wartość wynosi:

Ścieżki powiększające
Jeśli dana jest sieć przepływowa i przepływ , wówczas ścieżka powiększająca jest ścieżką prostą z do w rezydualnej sieci . Z definicji sieci rezydualnej, każda krawędź na ścieżce powiększającej pozwala na przesłanie pewnego dodatkowego przepływu z do 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.
<flash>file=Zasd_ilustr_l.swf |width=800|height=300</flash>
Najwyższą wartość, o jaką można zwiększyć przepływ przy użyciu ścieżki , nazywamy rezydualną przepustowością . Wielkość ta jest dana przez:
Zdefiniujmy tę zmianę przepływu związaną ze ścieżką jako funkcję równą:
(1)
Wówczas jest przepływem w o wartości . Dodając do , otrzymamy kolejny przepływ w , którego wartość jest bliższa maksimum, co sformułowane jest w tym wniosku.
Wniosek 2
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 sieci przepływowej jest podziałem na i tak, że i . Jeśli jest przepływem, wtedy przepływ netto poprzez przekrój jest zdefiniowany jako . Przepustowość przekroju definiujemy jako . Minimalnym przekrojem sieci jest przekrój, którego przepustowość jest najmniejsza ze wszystkich przekrojów w sieci.
Poniższa ilustracja pokazuje przekrój w sieci przepływów. Przepływ netto poprzez ten przekrój wynosi: , a jego przepustowość wynosi .
<flash>file=Zasd_ilustr_b.swf |width=800|height=250</flash>
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 składa się z dodatnich przepływów płynących w dwa kierunki; dodatni przepływ z do jest dodawany, podczas gdy dodatni przepływ z do jest odejmowany. Z drugiej strony, przepustowość przekroju jest obliczana tylko od krawędzi odchodzących z do . Krawędzie biegnące z do nie są włączone do obliczeń . 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
Dowód
Jako w wniosek z tego lematu otrzymujemy, że przepustowość przekroju jest graniczeniem wartości przepływu.
Wniosek 4
Dowód
Niech będzie dowolnym przekrojem w i niech będzie dowolnym przepływem. Z lematu 3 i warunku ograniczenia przepustowości otrzymujemy:

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]
- jest maksymalnym przepływem w .
- Sieć rezydualna nie zawiera żadnych ścieżek powiększających.
- dla pewnego przekroju w .
Dowód
(2)(3): Przypuśćmy, że nie posiada żadnej ścieżki powiększającej, to znaczy że nie posiada żadnej ścieżki z do . Zdefiniujmy:
oraz:
Podział jest przekrojem: oczywiście i , ponieważ nie ma żadnej ścieżki z do w . Dla każdej pary wierzchołków i , mamy , gdyż w przeciwnym wypadku , co umiejscowiłoby w zbiorze . Dlatego też, z lematu 3, mamy .
(3)(1): Z wniosku 4 wiemy, że dla wszystkich przekrojów . Czyli warunek oznacza, że jest przepływem maksymalnym.
Algorytm Forda – Fulkersona
W każdej iteracji metody Forda–Fulkersona odnajdujemy dowolną ścieżkę powiększającą i zwiększamy przepływ na każdej krawędzi o przepustowość rezydualną . Poniżej zamieszczamy implementacje tej metody.
Algorytm [Forda-Fulkersona] znajduje przepływ maksymalny w grafie
FORD-FULKERSON() 1 for każda krawędź do 2 begin 3 4 5 end 6 while istnieje ścieżka z do w sieci rezydualnej do 7 begin 8 9 for każda krawędź do 10 begin 11 12 13 end 14 end 15 return
Działanie tego algorytmu przestawione jest na następującej animacji. <flash>file=Zasd_ilustr_r.swf |width=800|height=300</flash>
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 , gdzie jest przepływem maksymalnym w sieci. Jeżeli przepływ 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ć iteracji. Taki przykład pokazany jest na poniższej animacji.
<flash>file=zasd_ilustr_e.swf |width=800|height=300</flash>