Zaawansowane algorytmy i struktury danych/Wykład 6

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania

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 G=(V,E). Przedstawimy trzy algorytmu rozwiązujące ten problem:

  • algorytm wykorzystujący mnożenie macierzy działający w czasie O(|V|3log|V|,
  • algorytm Floyda-Warshalla działający w czasie O(|V|3),
  • algorytm Johnsona działający w czasie O(V|2log|V|+|V||E|).

== 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 |V| 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 O(|V|log|V|+|E|), co daje nam algorytm rozwiązujący problem policzenia odległości między wszystkimi parami wierzchołków działający w czasie O(|V|2log|V|+|V||E|).

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 O(|V|2|E|. 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 W rozmiaru n×n reprezentującą wagi krawędzi n-wierzchołkowego grafu G=(V,E). Dla macierzy tej zachodzi:


Parser nie mógł rozpoznać (nieznana funkcja „\begin{cases}”): {\displaystyle w_{i,j} = \begin{cases} 0, & \mathrm{jeśli } i=j, \mathrm{waga krawędzi } (i,j), & \matkrm{jeśli } i\neq j \mathrm{ i } (i,j)\in E, \infty, & \matkrm{jeśli } i\neq j \mathrm{ i } (i,j)\neq E. \end{cases} }


W problemie najkrótszych ścieżek między wszystkimi parami wierzchołków chcemy wyznaczyć macierz D rozmiaru n×n taką, że di,j jest równe odległości δ(i,j) z wierzchołka i do wierzchołka j. Chcemy także wyznaczyć dla każdego wierzchołka v drzewo najkrótszych ścieżek Tv ukorzenione w v. Podobnie jak w poprzednim rozdziale drzewo Tv możemy kodować dla każdego wierzchołka przy pomocy funkcji poprzedników πv. Ponieważ tutaj interesuje nas wiele drzew to łatwiej będzie nam używać macierzy poprzedników Π. Macierz tą definiujemy używając funkcji πv w następujący sposób:


Πv,u=πv(u).


W pozostałej części tego wykładu zajmiemy się tylko wyznaczaniem macierzy odległości D. 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 O(|E|), a więc |V| drzew możemy wyliczyć w czasie O(|E||V|). 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 D.

Co więcej będziemy zakładać, że w grafie nie ma ujemnych cykli. Ujemne cykle można wykryć w czasie O(|V||E|) 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 C oraz D rozmiaru n×n. Dla macierzy tych definiujemy operację ×minl iloczynu odległości, której wynikiem jest także macierz rozmiaru n×n, 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 D opisują minimalne wagi odpowiednio zbioru ścieżek odpowiednio ΠC i ΠD w pewnym grafie G, to iloczyn odległości wyznacza minimalne wagi zbioru ścieżek powstałego z konkatenacji ścieżek ze zbioru ΠC ze ścieżkami zbioru ΠD.      (1)


Pokażemy teraz, że produkt odległości jest operacją łączną.

Lemat io_łączny

Dla macierzy C, D i E

rozmiaru n×nzachodzi:


(C×minD)×minE=C×min(D×minE).

Dowód

Powyższa równość wynika wprost z wzoru (1)) oraz

przemienności operacji min.

Co więcej produkt odległości jest przemienny względem dodawania.

Lemat io_przemienny

Dla macierzy C, D

i E rozmiaru n×nzachodzi:


C×min(D+E)=C×minD+C×minE,


oraz


(D+E)×minC=D×minC+E×minC.

Dowód

Te dwie równości wynikają ponownie z

wzoru (1) oraz przemienności operacji min

względem dodawania.

Zdefiniujmy macierz

Imin

rozmiaru

n×n

jako:

(Imin)i,j={0,jeśli i=j,,jeśli ij.

Macierz ta jest jedynką dla iloczynu odległości.

Lemat io_jedynka

Dla macierzy C rozmiaru n×n zachodzi:


Imin×minC=C×minImin=C.

Szablon:Dowód


Łą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 O(n3logn). Niech W będzie macierzą wag grafu G=(V,E). Rozważmy macierz Wm 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 Wm opisuje odległości między wierzchołkami grafu ale tylko dla ścieżek używających mniej niż m krawędzi.

Lemat potęgi_odległości

Element Wi,jm macierzy Wm zadaje

najmniejszą wagę ścieżki wychodzącej z wierzchołka i do wierzchołka j spośród ścieżek, które zawierają mniej niż m krawędzi, tzn.:


Parser nie mógł rozpoznać (nieznana funkcja „\mboc”): {\displaystyle w_{i,j}^{m} = \begin{cases} \min\{w(p): p \mbox{ ścieżka o długości } \le m \mboc{ z } u \mbox{ do } v\}, & \mbox{jeżeli istnieje ścieżka o długości } \le m \mboc{ z } u \mbox{ do } v,\\ \infty & \mbox{w przeciwnym przypadku.} \end{cases} }

Szablon: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 lemat_6

Jeżeli w grafie G=(V,E), w którym wagi krawędzi zadane

są macierzą W nie istnieje cykl o ujemnej wadze to:


δ(u,v)=Wu,v(k), dla kn1.

Szablon:Dowód

Zauważmy, że iloczyn odległości dwóch macierzy możemy policzyć w czasie O(|V|3) 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  D=W,
 2  k=1
 3 while n1>k do
 4   D=MNOŻENIE-ODLEGŁOŚCI(D,D)
 5   m=2m
 7  return D

Poprawności tego algorytmu wynika wprost z Lematu 6 ponieważ na zakończenie algorytmu D=Wm i m>n1.


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 p=(v0,,vl) jest każdy wierzchołek na ścieżce p różny od jej początku v0 i końca vl.

Niech zbiorem wierzchołków grafu G będzie V={1,,n}. Niech di,j(k) dla k=0,,n oznacza najmniejszą wagę ścieżki z i do j, spośród ścieżek których wierzchołki wewnętrzne należą do zbioru {v1,,vk. Pokażemy następujący rekurencyjny wzór na D(k).

Lemat lemat_7

Dla k=0,,n zachodzi:


di,j(k)={wi,j,jeżeli k=0,min(di,j(k1),di,k(k1)+dk,j(k1),jeżeli k1.


Szablon:Dowód

Wykorzystując wzór (2) możemy skonstruować następujący algorytm obliczający w czasie O(|V|3) 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  D(0)=W,
 2  for k=1 to n do
 3    for i=1 to n do
 4      for j=1 to n do
 5        di,j(k)=min(di,j(k1),di,k(k1)+dk,j(k1))
 6  return D(n)