Zaawansowane algorytmy i struktury danych/Wykład 6
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ć [[Wykład 5#algorytm_Bellmana-Forda|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