Zaawansowane algorytmy i struktury danych/Wykład 10: Różnice pomiędzy wersjami
m |
|||
Linia 121: | Linia 121: | ||
1 <math>b = 0</math> | 1 <math>b = 0</math> | ||
2 skonstruuj graf <math>\overline{G}_f</math> | 2 skonstruuj graf <math>\overline{G}_f</math> | ||
− | 3 | + | 3 '''while''' <math>\overline{E}_f \neq \emptyset </math> '''do''' |
− | + | 4 '''begin''' | |
− | + | 5 znajdź ścieżkę <math>p</math> z <math>s</math> do <math>t</math> w <math>\overline{G}_f</math> | |
− | + | 6 '''for''' każda krawędź <math>(u,v) \in p</math> '''do''' | |
− | + | 7 '''begin''' | |
− | + | 8 <math>b(u,v) = b(u,v) + c_f(p)</math> | |
− | + | 9 <math>b(v,u) = -b(u,v)</math> | |
− | + | 10 usuń rekurencyjnie <math>u</math> i inne wierzchołki jeżeli jeżeli nie wychodzi z nich żadna krawędź residualna | |
− | + | 11 '''end''' | |
− | + | 12 '''return''' <math>b</math> | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
}} | }} | ||
Wersja z 10:51, 5 cze 2007
Abstrakt
W wykładzie tym przedstawimy trzy algorytmy znajdowania przepływu w grafie. Pierwszym będzie algorytm Edmondsa-Karpa działający w czasie algorytmie Hopcrofta-Karpa.
. Następnym będzie algorytm Dinica działający w czasie , oraz trzecim tak zwany algorytm trzech Hindusów, działający w czasie . Nazwiska tych tytułowych Hindusów to Malhotra, Kumar i Maheshwari. Dwa ostatnie algorytmy oparte będą na konstrukcji przepływów blokujących, które są analogiczną konstrukcją do konstrukcji maksymalnego zbioru rozłącznych ścieżek, której użyliśmy wAlgorytm Edmonds’a-Karp’a
Algorytm Edmonds'a-Karp'a to algorytm Forda-Fulkersona w, którym zamiast dowolnej ścieżki powiększającej wybieramy zawsze najkrótszą ścieżkę powiększającą. Zakładamy tutaj, że wszystkie krawędzie mają jednostkowe długości. Taka modyfikacja pozwala poprawić ograniczenie w czasie działania tego algorytmu. Udowodnimy, że algorytm Edmonds’a–Karp’a działa w czasie
. W naszej analizie będziemy korzystać z zapisu dla odległości z do w , przy założenie, że każda krawędź ma jednostkową wagę.Lemat 1
Dowód
Ze względu na sposób wybrania
, wiemy że odległość z wierzchołka się nie zmniejszyła, to znaczy:Twierdzimy, że
. Dlaczego? Gdybyśmy mieli , wówczas z nierówności trójkąta dla i oraz powyższych nierówności wynikałoby:Co jest sprzeczne z założeniem, że
. Jak możemy zatem otrzymać i ? Powiększeniu przepływu z do powinno także powiększyć przepływ z do . Algorytm Edmondsa–Karpa zawsze powiększa przepływ wzdłuż najkrótszych ścieżek i dlatego też najkrótsza ścieżka z do w posiada jako ostatnią krawędź. Dlatego mamy:
Następujące twierdzenie ogranicza liczbę iteracji algorytmu Edmondsa–Karpa.
Twierdzenie 2
Dowód
Niech
i będą wierzchołkami w połączonymi krawędzią . Ponieważ ścieżki powiększające są najkrótszymi ścieżkami, to dla kawędzi krytycznej , otrzymujemyGdy tylko przepływ jest zwiększony, krawędź
znika z sieci rezydualnej. Nie może ona się znów pojawić na żadnej innej ścieżce powiększającej dopóki przepływ z do nie będzie zmniejszony, a nastąpi to tylko wtedy, kiedy pojawi się na ścieżce powiększającej. Jeśli jest przepływem w i to zdarzenie ma miejsce, wówczas mamy:Ponieważ lematu 1, otrzymujemy
, co wynika z
Ponieważ każdą iterację algorytmu FORD-FULKERSON można zaimplementować w czasie
, to całkowity czas działania algorytmu Edmondsa-Karpa wynosi . W następnych częściach wykładu pokażemy, jak wykorzystując przepływy blokujące poprawić ten wynik do czasu .Przepływ blokujący
Przepływem blokującym w sieci rezydualnej {{{2}}}
nazywamy taki przepływ w , że:- każda ścieżka z do w jest najkrótszą ścieżką w ,
- oraz każda najkrótsza ścieżka w zawiera krawędź nasyconą w .
Zauważ, że jest to definicja, która odpowiada pojęciu maksymalnego zbioru najkrótszych ścieżek powiększających użytemu w Wykładzie 7. Załóżmy na chwilę, że mamy algorytm znajdujący przepływ blokujący. Pokażemy jak go wykorzystać do znalezienia przepływu maksymalnego, jest to algorytm Dinica. Algorytmy na znajdowanie przepływu blokującego pokażemy w dalszej części tego wykładu.
Algorytm [Dinica] znajduje przepływ maksymalny w grafie
DINIC1 2 while istnieje ścieżka od do w do 3 begin 4 znajdź przepływ blokujący w 5 6 end 7 return
Poprawność algorytmu Dinica wynika bezpośrednio z twierdzenia o maksymalnym przepływie i minimalnym przekroju, gdyż po zakończeniu algorytmu nie ma już w sieci ścieżek powiększających. Zastanówmy się teraz, ile razy może zostać wykonana pętla while, czyli innymi słowy ile razy będzie konieczne znalezienie przepływu blokującego.
Lemat 3
Dowód

Wniosek 4
Znajdowanie przepływu blokującego - Algorytm Dinica
Zanim przejdziemy do opisu algorytmów znajdujących przepływ blokujący, wprowadźmy pojęcie sieci warstwowej. Sieć warstwową
dla sieci rezydualnej definiujemy jako graf skierowany o następującym zbiorze krawędzi:Zauważmy, że wszystkie ścieżki w warunek 1 definicji przepływu blokującego. W grafie wszystkie ścieżki są najkrótsze, jednak nie wszystkie ścieżki muszą prowadzić do . Jeżeli usuniemy zawczasu z grafu Parser nie mógł rozpoznać (nieznana funkcja „\oveline”): {\displaystyle \oveline{G}_f} krawędzie, które prowadzą donikąd, to ścieżki z do będziemy mogli wyszukiwać w czasie .
z do są najkrótszymi ścieżkami. Jeżeli chcemy wyszukać przepływ blokujący, to zauważmy, że robiąc to w sieci warstwowej, będziemy mieli spełniony automatycznieAlgorytm [Dinica] znajduje przepływ blokujący w grafie
DINIC-PRZEPŁYW-BLOKUJĄCY1 2 skonstruuj graf 3 while do 4 begin 5 znajdź ścieżkę z do w 6 for każda krawędź do 7 begin 8 9 10 usuń rekurencyjnie i inne wierzchołki jeżeli jeżeli nie wychodzi z nich żadna krawędź residualna 11 end 12 return
Działanie tego algorytmu zobrazowane jest na następującej animacji. <flash>file=Zasd_ilustr_p.swf |width=800|height=300</flash>
Zauważmy, że po zakończeniu działania algorytmu, w grafie
nie pozostanie żadna ścieżka z do . Skonstruowany przepływ będzie więc przepływem blokującym.Główna pętla programu w liniach 5-17 wykonana zostanie co najwyżej Wniosku 4 widzimy, że czas działania algorytmu Dinica wynosi .
razy, bo w każdym jej przebiegu nasycana jest co najmniej jedna krawędź. Pętlę tę można zaimplementować tak, aby działała w czasie , dlatego całkowity czas działania tej procedury wynosi . Korzystając zZnajdowanie przepływu blokującego - Algorytm trzech Hindusów
W algorytmie tym użyjemy pojęcia przepustowości wierzchołka w sieci
, którą definiujemy jako:W algorytmie trzech Hindusów, który nazywany jest też algorytmem MKM (od nazwisk autorów), będziemy w każdym wykonaniu głównej pętli algorytmu nasycać jeden wierzchołek, przesyłając z niego przepływ do przodu i w pewnym sensie do tyłu. W czasie wykonywania pętli funkcja
przestanie spełniać warunek zachowania przepływu, jednak pod koniec ten warunek zostanie przywrócony. Użyjemy tutaj dwóch pomocniczych procedur:- procedury PRZEŚLIJ - jeżeli do wierzchołka wpływa większy przepływ niż wypływa, to procedura ta przesyła ten nadmiar do przodu w grafie , nasycając po kolei krawędzie wychodzące z ,
- procedury COFNIJ - jeżeli z wierzchołka wypływa więcej niż do niego wpływa, to procedura ta kompensuje ten niedomiar, przesyłając przepływ z wierzchołków, z których istnieją w krawędzie do , nasycając po kolei krawędzie wchodzące do .
Algorytm [Malhotra, Kumar i Maheshwari] znajduje przepływ blokujący w grafie
MKM-PRZEPŁYW-BLOKUJĄCYPRZEŚLIJ 11 for downto do 12 foreach do 13 COFNIJ 14 usuń z grafu poprawiając przepustowości wierzchołków sąsiednich 15 end 16 return1 2 skonstruuj graf 3 while do 4 begin 5 znajdź wierzchołek o najmniejszym 6 prześlij jednostek przepływu krawędziami wychodzącymi z 7 prześlij jednostek przepływu krawędziami wchodzącymi do 8 for to do 9 foreach do 10
Działanie tego algorytmu zobrazowane jest na następującej animacji. <flash>file=Zasd_ilustr_q.swf |width=800|height=300</flash>
Zauważmy, że ponieważ wybraliśmy wierzchołek o najmniejszej przepustowości, to zawsze w procedurach PRZEŚLIJ i COFNIJ uda nam się przesłać nadmiar bądź zrekompensować niedomiar w wierzchołku.
Zauważmy, że główna pętla procedury może wykonać się co najwyżej PRZEŚLIJ i COFNIJ. Co najwyżej razy będziemy przesyłać przepływ nasycając krawędzie. Natomiast liczba przesłań nie nasycających krawędzi nie przekroczy , gdyż dla każdego wierzchołka w wykonaniu procedury PRZEŚLIJ i COFNIJ wykonujemy co najwyżej jedno przesłanie nie nasycające, a operacji tych łącznie wykonywanych jest . Czas potrzebny na znalezienie przepływu blokującego wynosi więc . Łącząc ten algorytm z algorytmem Dinica, otrzymujemy algorytm znajdujący maksymalny przepływ w grafie w czasie .
razy, ponieważ za każdym razem nasycany jest co najmniej jeden wierzchołek grafu. Policzmy teraz, ile razy łącznie będą nasycane krawędzie w trakcie wykonywania procedur