Zaawansowane algorytmy i struktury danych/Wykład 6: Różnice pomiędzy wersjami
Linia 9: | Linia 9: | ||
== Problem najkrótszych ścieżek między wszystkimi parami wierzchołków == | == Problem najkrótszych ścieżek między wszystkimi parami wierzchołków == | ||
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 <math>|V|</math> 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 <math>O(|V| \log |V| + |E|)</math>, co daje nam algorytm rozwiązujący problem policzenia odległości między wszystkimi parami wierzchołków działający w czasie <math>O(|V|^2 \log |V| + |V||E|)</math>. | ||
można rozwiązać, wykonując <math>|V|</math> 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 <math>O(|V| \log |V| + |E|)</math>, co | |||
daje nam algorytm rozwiązujący problem policzenia odległości między | |||
wszystkimi parami wierzchołków działający w czasie <math>O(|V|^2 | |||
\log |V| + |V||E|)</math>. | |||
Jednakże tego rozwiązania nie możemy użyć jeżeli w grafie wagi | 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ć [[Wykład 5#algorytm_Bellmana-Forda|algorytm Bellmana-Forda]]. Otrzymamy wtedy algorytm działający w czasie <math>O(|V|^2|E|</math>. W rozdziale tym zaprezentujemy bardziej efektywne rozwiązania dla tego problemu. | ||
krawędzi mogą być ujemne. W takim przypadku możemy użyć [[Wykład | |||
5#algorytm_Bellmana-Forda|algorytm Bellmana-Forda]]. Otrzymamy wtedy | |||
algorytm działający w czasie <math>O(|V|^2|E|</math>. W rozdziale | |||
tym zaprezentujemy bardziej efektywne rozwiązania dla tego problemu. | |||
W rozdziale tym będziemy zakładać, że algorytmy na wejściu otrzymują | W rozdziale tym będziemy zakładać, że algorytmy na wejściu otrzymują {{kotwica|macierz_wag|''macierz wag''}} <math>W</math> rozmiaru <math>n\times n</math> reprezentującą wagi krawędzi <math>n</math>-wierzchołkowego grafu <math>G = (V,E)</math>. Dla macierzy tej zachodzi: | ||
{{kotwica|macierz_wag|''macierz wag''}} <math>W</math> rozmiaru <math>n\times n</math> | |||
reprezentującą wagi krawędzi <math>n</math>-wierzchołkowego grafu | |||
<math>G = (V,E)</math>. Dla macierzy tej zachodzi: | |||
Linia 40: | Linia 25: | ||
W problemie najkrótszych ścieżek między wszystkimi parami | W problemie najkrótszych ścieżek między wszystkimi parami wierzchołków chcemy wyznaczyć macierz <math>D</math> rozmiaru | ||
wierzchołków chcemy wyznaczyć macierz <math>D</math> rozmiaru | <math>n \times n</math> taką, że <math>d_{i,j}</math> jest równe odległości <math>\delta(i,j)</math> z wierzchołka <math>i</math> do wierzchołka <math>j</math>. Chcemy także wyznaczyć dla każdego wierzchołka <math>v</math> [[Wykład 5#drzewo_najkrótszych_ścieżek|drzewo najkrótszych ścieżek]] <math>T_v</math> ukorzenione w <math>v</math>. Podobnie jak w | ||
<math>n \times n</math> taką, że <math>d_{i,j}</math> jest równe | poprzednim rozdziale drzewo <math>T_v</math> możemy kodować dla każdego wierzchołka przy pomocy funkcji poprzedników <math>\pi_{v}</math>. Ponieważ tutaj interesuje nas wiele drzew to łatwiej będzie nam używać {{kotwica|macierz_poprzedników|'''macierzy poprzedników''}} <math>\Pi</math>. Macierz tą definiujemy używając funkcji <math>\pi_v</math> w następujący sposób: | ||
odległości <math>\delta(i,j)</math> z wierzchołka <math>i</math> do | |||
wierzchołka <math>j</math>. Chcemy także wyznaczyć dla każdego | |||
wierzchołka <math>v</math> [[Wykład 5#drzewo_najkrótszych_ścieżek|drzewo najkrótszych ścieżek]] | |||
<math>T_v</math> ukorzenione w <math>v</math>. Podobnie jak w | |||
poprzednim rozdziale drzewo <math>T_v</math> możemy kodować dla | |||
każdego wierzchołka przy pomocy funkcji poprzedników | |||
<math>\pi_{v}</math>. Ponieważ tutaj interesuje nas wiele drzew to | |||
łatwiej będzie nam używać {{kotwica|macierz_poprzedników|'''macierzy | |||
poprzedników''}} <math>\Pi</math>. Macierz tą definiujemy używając | |||
funkcji <math>\pi_v</math> w następujący sposób: | |||
Linia 60: | Linia 35: | ||
W pozostałej części tego wykładu zajmiemy się tylko wyznaczaniem | W pozostałej części tego wykładu zajmiemy się tylko wyznaczaniem macierzy odległości <math>D</math>. Jak to zostało pokazane w [[Ćwiczenia 5/Zadanie 3|Zadaniu 3]] do poprzedniego wykładu znając odległości w grafie drzewo najkrótszych ścieżek można wyznaczyć w czasie <math>O(|E|)</math>, a więc <math>|V|</math> drzew możemy wyliczyć w czasie <math>O(|E||V|)</math>. 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 <math>D</math>. | ||
macierzy odległości <math>D</math>. Jak to zostało pokazane w | |||
[[Ćwiczenia 5/Zadanie 3|Zadaniu 3]] do poprzedniego wykładu znając | |||
odległości w grafie drzewo najkrótszych ścieżek można wyznaczyć w | |||
czasie <math>O(|E|)</math>, a więc <math>|V|</math> drzew możemy | |||
wyliczyć w czasie <math>O(|E||V|)</math>. 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 | |||
<math>D</math>. | |||
Co więcej będziemy zakładać, że w grafie nie ma ujemnych cykli. | Co więcej będziemy zakładać, że w grafie nie ma ujemnych cykli. Ujemne cykle można wykryć w czasie <math>O(|V||E|)</math> przy użyciu [[wykład 5/algorytm_Bellmana-Forda|Algorytmu Bellmana-Forda]]. Zobacz [[Ćwiczenia 5#Zadanie 4| Zadanie 4]] do Wykładu 4. | ||
Ujemne cykle można wykryć w czasie <math>O(|V||E|)</math> przy | |||
użyciu [[wykład 5/algorytm_Bellmana-Forda|Algorytmu | |||
Bellmana-Forda]]. Zobacz [[Ćwiczenia 5#Zadanie 4| Zadanie 4]] do | |||
Wykładu 4. | |||
== Najkrótsze ścieżki i mnożenie macierzy == | == Najkrótsze ścieżki i mnożenie macierzy == |
Wersja z 22:57, 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
Załóżmy, że dane mamy dwie macierze wag oraz rozmiaru . Dla macierzy tych definiujemy operację l iloczynu odległości, której wynikiem jest także macierz rozmiaru , zdefiniowana jako:
Parser nie mógł rozpoznać (błąd składni): {\displaystyle (C \times_{\min} D)_{i,j} = \min_{k = 1,\ldots,n} C_{i,k} + D_{k,j}. </center> }} {{wniosek|wniosek_konkatenacja|1|3= Jeżeli założymy, że <math>C} i opisują minimalne wagi odpowiednio zbioru ścieżek odpowiednio i w pewnym grafie , to iloczyn odległości wyznacza minimalne wagi zbioru ścieżek powstałego z konkatenacji ścieżek ze zbioru ze ścieżkami zbioru . (1)
Pokażemy teraz, że produkt odległości jest operacją łączną.
Lemat io_łączny
rozmiaru zachodzi:
Dowód
Co więcej produkt odległości jest przemienny względem dodawania.
Lemat io_przemienny
i rozmiaru zachodzi:
oraz
Dowód
wzoru (1) oraz przemienności operacji
względem dodawania.
Zdefiniujmy macierz
rozmiaru
jako:
Macierz ta jest jedynką dla iloczynu odległości.
Lemat io_jedynka
Łą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:
Parser nie mógł rozpoznać (nieznana funkcja „\begin{cases}”): {\displaystyle W^{m} = \begin{cases} I_{\min}, &\mbox{jeżeli } m=0,\\ W \times_{\min} W^{m-1}, &\mbox{jeżeli } m>0. }
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 potęgi_odległości
najmniejszą wagę ścieżki wychodzącej z wierzchołka do wierzchołka spośród ścieżek, które zawierają mniej niż krawędzi, tzn.:
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 lemat_6
są macierzą nie istnieje cykl o ujemnej wadze to:
Zauważmy, że iloczyn odległości dwóch macierzy możemy policzyć w czasie wykorzystując następujący algorytm.
Algorytm algorytm_iloczyn_odległości
{{{3}}}
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_apsp_mnozenie
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 {{kotwica|wierzchołek_wewnetrzny|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 lemat_7
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
między wszystkimi parami wierzchołków I ODLEGŁÓŚCI-II(W) 1 , 2 for to do 3 for to do 4 for to do 5 6 return