Zaawansowane algorytmy i struktury danych/Wykład 6: Różnice pomiędzy wersjami
Nie podano opisu zmian |
|||
Linia 40: | Linia 40: | ||
== Najkrótsze ścieżki i mnożenie macierzy == | == Najkrótsze ścieżki i mnożenie macierzy == | ||
=== Iloczyn odległości i jego właściwości === | |||
Załóżmy, że dane mamy dwie [[#macierz_wag|macierze wag]] <math>C</math> oraz <math>D</math> rozmiaru <math>n\times n</math>. | Załóżmy, że dane mamy dwie [[#macierz_wag|macierze wag]] <math>C</math> oraz <math>D</math> rozmiaru <math>n\times n</math>. | ||
Linia 87: | Linia 89: | ||
<center><math> | <center><math> | ||
\left(D + E \right) \times_{\min} C = D \times_{\min} C + E \times_{min} C. | \left(D + E \right) \times_{\min} C = D \times_{\min} C + E \times_{min} C. | ||
</math></center> }} | </math></center> }} | ||
{{dowod||| Te dwie równości wynikają ponownie z [[#wzór_1|wzoru (1)]] oraz przemienności operacji <math>\min</math> względem dodawania. }} | {{dowod||| Te dwie równości wynikają ponownie z [[#wzór_1|wzoru (1)]] oraz przemienności operacji <math>\min</math> względem dodawania. }} | ||
Zdefiniujmy macierz <math>I_{\min}</math> rozmiaru <math>n \times n</math> jako: | Zdefiniujmy macierz <math>I_{\min}</math> rozmiaru <math>n \times n</math> jako: | ||
Linia 122: | Linia 124: | ||
= I_{i,i} + C_{i,j} = C_{i,j}. </math></center> }} | = I_{i,i} + C_{i,j} = C_{i,j}. </math></center> }} | ||
=== Pomysł algorytmu === | |||
Łączność iloczynu odległości ma dla nas bardzo ważne konsekwencję i pozwoli nam na konstrukcję algorytmu obliczania odległości w grafie między wszystkimi parami wierzchołków działającego w czasie <math>O(n^{3}\log n)</math>. Niech <math>W</math> będzie [[#macierz_wag|macierzą wag]] grafu <math>G = (V,E)</math>. Rozważmy macierz <math>W^m</math> zdefiniowaną jako: | Łączność iloczynu odległości ma dla nas bardzo ważne konsekwencję i pozwoli nam na konstrukcję algorytmu obliczania odległości w grafie między wszystkimi parami wierzchołków działającego w czasie <math>O(n^{3}\log n)</math>. Niech <math>W</math> będzie [[#macierz_wag|macierzą wag]] grafu <math>G = (V,E)</math>. Rozważmy macierz <math>W^m</math> zdefiniowaną jako: | ||
Linia 170: | Linia 174: | ||
{{dowod|||3= Jeżeli w grafie nie istnieje cykl o ujemnej wadze, to wszystkie najkrótsze ścieżki są ścieżkami prostymi, a więc mają długość co najwyżej <math>n-1</math>. Z [[potęgi_odległości|Lematu 5]] wynika więc że odległości tych ścieżek są dobrze wyznaczone w <math>W^{k}</math> dla <math>k \le n-1</math>. }} | {{dowod|||3= Jeżeli w grafie nie istnieje cykl o ujemnej wadze, to wszystkie najkrótsze ścieżki są ścieżkami prostymi, a więc mają długość co najwyżej <math>n-1</math>. Z [[potęgi_odległości|Lematu 5]] wynika więc że odległości tych ścieżek są dobrze wyznaczone w <math>W^{k}</math> dla <math>k \le n-1</math>. }} | ||
=== Algorytm === | |||
Zauważmy, że iloczyn odległości dwóch macierzy możemy policzyć w czasie <math>O(|V|^3)</math> wykorzystując następujący | Zauważmy, że iloczyn odległości dwóch macierzy możemy policzyć w czasie <math>O(|V|^3)</math> wykorzystując następujący | ||
Linia 229: | Linia 235: | ||
Niech <math>p</math> będzie najkrótszą ścieżką z <math>i</math> do <math>j</math>, której wierzchołki wewnętrzne należą do zbioru <math>\{v_1,\ldots,v_k\}</math>. Mamy dwa przypadki: | Niech <math>p</math> będzie najkrótszą ścieżką z <math>i</math> do <math>j</math>, której wierzchołki wewnętrzne należą do zbioru <math>\{v_1,\ldots,v_k\}</math>. Mamy dwa przypadki: | ||
* Wierzchołek <math>v_k</math> nie leży na ścieżce <math>p</math>. Wtedy zachodzi <math>d_{i,j}^{(k)} = p(w) = d_{i,j}^{(k-1)}</math>. Ponieważ <math>p</math> jest najkrótszą ścieżką to także <math>p(w) \le d_{i,k}^{(k-1)} + d_{k,j}^{(k-1)}</math> i powyższy wzór zachodzi. | * Wierzchołek <math>v_k</math> nie leży na ścieżce <math>p</math>. Wtedy zachodzi <math>d_{i,j}^{(k)} = p(w) = d_{i,j}^{(k-1)}</math>. Ponieważ <math>p</math> jest najkrótszą ścieżką to także <math>p(w) \le d_{i,k}^{(k-1)} + d_{k,j}^{(k-1)}</math> i powyższy wzór zachodzi. | ||
* Jeżeli wierzchołek <math>v_k</math> należy do ścieżki <math>p</math>, to występuje on dokładnie raz i możemy podzielić <math>p</math> na dwie ścieżki <math>p_1</math> z <math>i</math> do <math>k</math> oraz <math>p_2</math> z <math>k</math> do <math>j</math>. Ścieżki <math>p_1</math> i <math>p_2</math> nie zawierają wierzchołka <math>v_k</math> jako wierzchołka wewnętrznego. Ponieważ są to podścieżki najkrótszej ścieżki, więc same też są najkrótsze. Zachodzi więc dla nich <math>w(p_1) = d_{i,k}^{(k-1)}</math> oraz <math>w(p_2) = d_{k,j}^{(k-1)}</math>. Otrzymujemy więc <math>d_{i,j}^{(k)} = w(p) = w(p_1) + w(p_2) = d_{i,k}^{(k-1)} + d_{k,j}^{(k-1)}</math>. Ponieważ <math>p</math> jest najkrótszą ścieżką to <math>p(w) \le d_{i,j}^{(k-1)}</math> i wzór zachodzi także w tym przypadku. | * Jeżeli wierzchołek <math>v_k</math> należy do ścieżki <math>p</math>, to występuje on dokładnie raz i możemy podzielić <math>p</math> na dwie ścieżki <math>p_1</math> z <math>i</math> do <math>k</math> oraz <math>p_2</math> z <math>k</math> do <math>j</math>. Ścieżki <math>p_1</math> i <math>p_2</math> nie zawierają wierzchołka <math>v_k</math> jako wierzchołka wewnętrznego. Ponieważ są to podścieżki najkrótszej ścieżki, więc same też są najkrótsze. Zachodzi więc dla nich <math>w(p_1) = d_{i,k}^{(k-1)}</math> oraz <math>w(p_2) = d_{k,j}^{(k-1)}</math>. Otrzymujemy więc <math>d_{i,j}^{(k)} = w(p) = w(p_1) + w(p_2) = d_{i,k}^{(k-1)} + d_{k,j}^{(k-1)}</math>. Ponieważ <math>p</math> jest najkrótszą ścieżką to <math>p(w) \le d_{i,j}^{(k-1)}</math> i wzór zachodzi także w tym przypadku. | ||
Linia 245: | Linia 251: | ||
5 <math>d_{i,j}^{(k)} = \min(d_{i,j}^{(k-1)}, d_{i,k}^{(k-1)} + d_{k,j}^{(k-1)})</math> | 5 <math>d_{i,j}^{(k)} = \min(d_{i,j}^{(k-1)}, d_{i,k}^{(k-1)} + d_{k,j}^{(k-1)})</math> | ||
6 '''return''' <math>D^{(n)}</math> | 6 '''return''' <math>D^{(n)}</math> | ||
}} | |||
== Algorytm Johnsona == | |||
W algorytmie Johnsona wykorzystamy spostrzeżenie uczynione przez nas | |||
na początku wykładu, że odległości w grafie w którym wszystkie wagi | |||
krawędzi są dodanie można obliczyć korzystając z | |||
[[algorytm_dijkstry|algorytmu Dijkstry]] w czasie <math>O(|V|^2\log | |||
|V| + |V||E|)</math>. Pokażemy tutaj jak zmienić wagi w grafie tak, | |||
aby stały się one dodatnie, przy zachowaniu najkrótszych ścieżek. | |||
{{lemat|lemat_8|8|3= Niech będzie dany graf skierowany | |||
<math>G(V,E)=</math> wraz z funkcją wagową <math>w:E \to | |||
\mathcal{R}</math>. Niech <math>h:V \to \mathcal{R}</math> będzie | |||
dowolną funkcją z wierzchołków grafu w liczby rzeczywiste. | |||
Zdefiniujmy nową funkcję wagową <math>w_h</math>na podstawie | |||
<math>w</math> i <math>h</math>: | |||
{{wzor|wzor_3|3|3= | |||
<math> | |||
w_h(u,v) = w(u,v) + h(u) - h(v). | |||
</math> | |||
}} | |||
Niech <math>p = (v_0, \ldots, v_k)</math> będzie ścieżką z | |||
wierzchołka <math>v_0</math> do wierzchołka <math>v_k</math>. Wówczas | |||
}} | }} |
Wersja z 23:27, 21 lip 2006
Abstrakt
W wykładzie tym zajmiemy się problemem obliczanie odległości w grafie między wszystkimi parami wierzchołków w grafie ważonym skierowanym . Przedstawimy trzy algorytmu rozwiązujące ten problem:
- algorytm wykorzystujący mnożenie macierzy działający w czasie ,
- algorytm Floyda-Warshalla działający w czasie ,
- algorytm Johnsona działający w czasie .
Problem najkrótszych ścieżek między wszystkimi parami wierzchołków
Problem najkrótszych ścieżek między wszystkimi parami wierzchołków można rozwiązać, wykonując razy algorytm dla problemu najkrótszych ścieżek z jednego wierzchołka. Jeżeli w grafie wagi krawędzi są nieujemne to możemy użyć algorytmu Dijkstry. Najszybsza implementacji algorytmu Dijskstry wykorzystująca kopce Fibonacciego działa w czasie , co daje nam algorytm rozwiązujący problem policzenia odległości między wszystkimi parami wierzchołków działający w czasie .
Jednakże tego rozwiązania nie możemy użyć jeżeli w grafie wagi krawędzi mogą być ujemne. W takim przypadku możemy użyć algorytm Bellmana-Forda. Otrzymamy wtedy algorytm działający w czasie . W rozdziale tym zaprezentujemy bardziej efektywne rozwiązania dla tego problemu.
W rozdziale tym będziemy zakładać, że algorytmy na wejściu otrzymują macierz wag rozmiaru reprezentującą wagi krawędzi -wierzchołkowego grafu . Dla macierzy tej zachodzi:
W problemie najkrótszych ścieżek między wszystkimi parami wierzchołków chcemy wyznaczyć macierz rozmiaru
taką, że jest równe odległości z wierzchołka do wierzchołka . Chcemy także wyznaczyć dla każdego wierzchołka drzewo najkrótszych ścieżek ukorzenione w . Podobnie jak w
poprzednim rozdziale drzewo możemy kodować dla każdego wierzchołka przy pomocy funkcji poprzedników . Ponieważ tutaj interesuje nas wiele drzew to łatwiej będzie nam używać 'macierzy poprzedników . Macierz tą definiujemy używając funkcji w następujący sposób:
W pozostałej części tego wykładu zajmiemy się tylko wyznaczaniem macierzy odległości . Jak to zostało pokazane w Zadaniu 3 do poprzedniego wykładu znając odległości w grafie drzewo najkrótszych ścieżek można wyznaczyć w czasie , a więc drzew możemy wyliczyć w czasie . Czas ten jest mniejszy niż czas działania wszystkich prezentowanych w tym wykładzie algorytmów, więc bez straty ogólności, a zyskując na prostocie prezentacji możemy ograniczyć się tylko do wyznaczenia macierzy odległości .
Co więcej będziemy zakładać, że w grafie nie ma ujemnych cykli. Ujemne cykle można wykryć w czasie przy użyciu Algorytmu Bellmana-Forda. Zobacz Zadanie 4 do Wykładu 4.
Najkrótsze ścieżki i mnożenie macierzy
Iloczyn odległości i jego właściwości
Załóżmy, że dane mamy dwie macierze wag oraz rozmiaru . Dla macierzy tych definiujemy operację iloczyn odległości, której wynikiem jest także macierz rozmiaru , zdefiniowana jako:
(1)
Wniosek 1
Pokażemy teraz, że produkt odległości jest operacją łączną.
Lemat 2
Dowód

Co więcej produkt odległości jest przemienny względem dodawania.
Lemat io_przemienny
oraz
Dowód

Zdefiniujmy macierz rozmiaru jako:
Macierz ta jest jedynką dla iloczynu odległości.
Lemat 4
Dowód
Pomysł algorytmu
Łączność iloczynu odległości ma dla nas bardzo ważne konsekwencję i pozwoli nam na konstrukcję algorytmu obliczania odległości w grafie między wszystkimi parami wierzchołków działającego w czasie . Niech będzie macierzą wag grafu . Rozważmy macierz zdefiniowaną jako:
Pokażemy teraz, że macierz opisuje odległości między wierzchołkami grafu ale tylko dla ścieżek używających mniej niż krawędzi.
Lemat 5
Dowód

Zajmiemy się teraz konstrukcją algorytmu obliczającego najkrótsze ścieżki w grafie. W tym celu będziemy potrzebowali jeszcze udowodnić następujące dwa lematy.
Lemat 6
Dowód

Algorytm
Zauważmy, że iloczyn odległości dwóch macierzy możemy policzyć w czasie wykorzystując następujący algorytm.
Algorytm Mnożenia macierzy odległości
MNOŻENIE-ODLEGŁOŚCI(C,D) 1 macierz rozmiaru 2 for to do 3 for to do 4 5 for to do 6 e_{i,j} = \min(c_{i,k} + d_{k,j}, e_{i,j}) 7 return D'
Ponieważ operacja iloczynu odległości jest łączna to możemy wykorzystać algorytm szybkiego potęgowania i policzyć odległości przy pomocy następującego algorytmu.
Algorytm Algorytm obliczania odległości między wszystkimi parami wierzchołków I
ODLEGŁÓŚCI-I(W) 1 , 2 3 while do 4 MNOŻENIE-ODLEGŁOŚCI 5 7 return
Poprawności tego algorytmu wynika wprost z Lematu 6 ponieważ na zakończenie algorytmu i .
Algorytm Floyda-Warshalla
W algorytmie Floyda-Warshalla wykorzystamy inną cechę najkrótszych ścieżek niż ta użyta w algorytmie z wykorzystaniem iloczynu odległości. W poprzednim algorytmie konstruowaliśmy coraz dłuższe ścieżki, natomiast tutaj będziemy konstruować ścieżki przechodzące przez coraz większy zbiór wierzchołków. Wierzchołkiem wewnetrznym ścieżki jest każdy wierzchołek na ścieżce różny od jej początku i końca .
Niech zbiorem wierzchołków grafu będzie . Niech dla oznacza najmniejszą wagę ścieżki z do , spośród ścieżek których wierzchołki wewnętrzne należą do zbioru . Pokażemy następujący rekurencyjny wzór na .
Lemat 7
(2)
Dowód
Niech będzie najkrótszą ścieżką z do , której wierzchołki wewnętrzne należą do zbioru . Mamy dwa przypadki:
- Wierzchołek nie leży na ścieżce . Wtedy zachodzi . Ponieważ jest najkrótszą ścieżką to także i powyższy wzór zachodzi.
- Jeżeli wierzchołek należy do ścieżki , to występuje on dokładnie raz i możemy podzielić na dwie ścieżki z do oraz z do . Ścieżki i nie zawierają wierzchołka jako wierzchołka wewnętrznego. Ponieważ są to podścieżki najkrótszej ścieżki, więc same też są najkrótsze. Zachodzi więc dla nich oraz . Otrzymujemy więc . Ponieważ jest najkrótszą ścieżką to i wzór zachodzi także w tym przypadku.
Wykorzystując wzór (2) możemy skonstruować następujący algorytm obliczający w czasie odległości między wszystkimi parami wierzchołków.
Algorytm Algorytm Floyda-Warshalla
ODLEGŁÓŚCI-II(W) 1 , 2 for to do 3 for to do 4 for to do 5 6 return
Algorytm Johnsona
W algorytmie Johnsona wykorzystamy spostrzeżenie uczynione przez nas na początku wykładu, że odległości w grafie w którym wszystkie wagi krawędzi są dodanie można obliczyć korzystając z algorytmu Dijkstry w czasie . Pokażemy tutaj jak zmienić wagi w grafie tak, aby stały się one dodatnie, przy zachowaniu najkrótszych ścieżek.
Lemat lemat_8
wraz z funkcją wagową . Niech będzie dowolną funkcją z wierzchołków grafu w liczby rzeczywiste. Zdefiniujmy nową funkcję wagową na podstawie i :
(3)
Niech będzie ścieżką z
wierzchołka do wierzchołka . Wówczas