Zaawansowane algorytmy i struktury danych/Wykład 6: Różnice pomiędzy wersjami

Z Studia Informatyczne
Przejdź do nawigacjiPrzejdź do wyszukiwania
Sank (dyskusja | edycje)
Sank (dyskusja | edycje)
Linia 13: Linia 13:


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


{{wzor2|1=<math>
{{wzor2|1=<math>

Wersja z 09:37, 19 lip 2007

Abstrakt

W wykładzie tym zajmiemy się problemem obliczania odległości w grafie między wszystkimi parami wierzchołków w grafie ważonym skierowanym G=(V,E). Przedstawimy trzy algorytmy 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 implementacja 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ć 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:


wi,j={0,jeśli i=j,waga krawędzi (i,j),jeśli ij i (i,j)E,,jeśli ij i (i,j)E.


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, ł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. Zadaniu 3 do tego wykładu polega na pokazaniu, jak znając odległości w grafie policzyć drzewo najkrótszych ścieżek w czasie O(|E|). Tak 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 3 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 C oraz D rozmiaru n×n. Dla macierzy tych definiujemy operację ×min iloczyn odległości, której wynikiem jest także macierz rozmiaru n×n, zdefiniowana jako:

(C×minD)i,j=mink=1,,nCi,k+Dk,j.      (1)


Wniosek 1

Jeżeli założymy, że C i D opisują minimalne wagi 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 ze zbioru ΠD.

Wniosek ten jest przedstawiony na poniższej animicji, gdzie zostały zaznaczone dwa zbiory ścieżek, pierwszy, zaznaczony na zielono, reprezentowany przez macierz A oraz graf GA, oraz drugi, zaznaczony na niebiesko, reprezentowany przez macierz B oraz graf GB. W wyniku wykonania mnożenia otrzymujemy macierz C oraz graf GC <flash>file=Zasd_ilustr_f.swf|width=600|height=500</flash>


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

Lemat 2

Dla macierzy C, D i E rozmiaru n×n zachodzi:
(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 3

Dla macierzy C, D i E rozmiaru n×n zachodzi:


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 4

Dla macierzy C rozmiaru n×n zachodzi:


Imin×minC=C×minImin=C.

Dowód

Mamy
(Imin×minC)i,j=mink=1,,n(Imin)i,k+Ck,j=

ponieważ wszystkie elementy (Imin)i,k równe są oprócz elementu i=k, możemy je pominąć w operacji min i:


=mink=i(Imin)i,k+Ck,j=Ii,i+Ci,j=Ci,j.

Pomysł algorytmu

Łączność iloczynu odległości ma dla nas bardzo ważne konsekwencje 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(|V|3log|V|). Niech W będzie macierzą wag grafu G=(V,E). Rozważmy macierz Wm zdefiniowaną jako:


Wm={Imin,jeżeli m=0,W×minWm1,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 nie więcej niż m krawędzi.

Lemat 5

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ą nie więcej niż m krawędzi, tzn.:


wi,jm={min{w(p):p ścieżka o długości m z u do v},jeżeli istnieje ścieżka o długości m z u do v,w przeciwnym przypadku.

Dowód

Tezę tę udowodnimy przez indukcję po m. Ścieżki używające 0 krawędzi istnieją tylko z każdego wierzchołka do niego samego i mają długość 0, a więc dla m=0 teza wynika wprost z definicji macierzy W0. Załóżmy teraz, że teza zachodzi dla m>0. Mamy wtedy Wm+1=W×minWm. Zauważmy, że definicja macierzy wag W opisuje ścieżki używające 1 krawędź. Korzystając teraz z Wniosku 1 otrzymujemy tezę dla m+1.


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

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.

Dowód

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 n1. Z Lematu 5 wynika więc, że odległości tych ścieżek są dobrze wyznaczone w Wk dla kn1.

Algorytm

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 Mnożenia macierzy odległości


 MNOŻENIE-ODLEGŁOŚCI(C,D)
 1  E macierz rozmiaru n×n
 2  for i=0 to n1 do
 3    for j=0 to n1 do
 4    begin
 5      ei,j=
 6      for k=0 to n1 do
 7        ei,j=min(ci,k+dk,j,ei,j)
 8    end
 9  return E

Ponieważ operacja iloczynu odległości jest łączna, 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  D=W
 2  m=1
 3  while n1>m do
 4  begin
 5    D=MNOŻENIE-ODLEGŁOŚCI(D,D)
 6    m=2m
 7  end
 8  return D

Poprawność 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 wewnętrznym ś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 {1,,k}. Pokażemy następujący rekurencyjny wzór na D(k).

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.      (2)

Dowód

Dla k=0 poprawność powyższego wzoru wynika bezpośrednio z definicji D0. Dla k>0 musimy pokazać, że


di,j(k)=min(di,j(k1),di,k(k1)+dk,j(k1)).


Niech p będzie najkrótszą ścieżką z i do j, której wierzchołki wewnętrzne należą do zbioru {v1,,vk}. Mamy dwa przypadki:

  • Wierzchołek vk nie leży na ścieżce p. Wtedy zachodzi di,j(k)=p(w)=di,j(k1). Ponieważ p jest najkrótszą ścieżką, to także p(w)di,k(k1)+dk,j(k1) i powyższy wzór zachodzi.
  • Jeżeli wierzchołek vk należy do ścieżki p, to występuje on dokładnie raz i możemy podzielić p na dwie ścieżki p1 z i do k oraz p2 z k do j. Ścieżki p1 i p2 nie zawierają wierzchołka vk 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 w(p1)=di,k(k1) oraz w(p2)=dk,j(k1). Otrzymujemy więc di,j(k)=w(p)=w(p1)+w(p2)=di,k(k1)+dk,j(k1). Ponieważ p jest najkrótszą ścieżką, p(w)di,j(k1) 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 O(|V|3) odległości między wszystkimi parami wierzchołków.

Algorytm Algorytm Floyda-Warshalla


 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)


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ą dodatnie, można obliczyć korzystając z algorytmu Dijkstry w czasie O(|V|2log|V|+|V||E|). Pokażemy tutaj, jak zmienić wagi w grafie tak, aby stały się one dodatnie, przy zachowaniu najkrótszych ścieżek.

Niech będzie dany graf skierowany G=(V,E) wraz z funkcją wagową w:E. Niech funkcja h:V będzie dowolną funkcją ze zbioru wierzchołków w liczby rzeczywiste. Dla funkcji h oraz w definiujmy nową funkcję wagową oznaczoną wh w następujący sposób:

wh(u,v)=w(u,v)+h(u)h(v).      (3)

Oznaczmy, przez δ(u,v) odległości w grafie G dla funkcji wagowej w oraz przez δh(u,v) odległości w grafie G dla funkcji wagowej wh.

Lemat 8

Dla funkcji w, wh oraz dowolnej ścieżki p=(v0,,vk) zachodzi:
wh(p)=w(p)+h(v0)h(vk).

Dowód

Mamy:


wh(p)=i=0k1wh(vi,vi+1)=
=i=0k1(w(vi,vi+1)+h(vi)h(vi+1))=
=i=0k1w(vi,vi+1)+i=0k1h(vi)i=0k1h(vi+1)=
=w(p)+h(v0)h(vk).


Widzimy więc, że zmiana długości ścieżki zależy tylko od jej końców. Otrzymujemy stąd wprost dwa wnioski.


Wniosek 9

Dla funkcji w, wh, oraz dowolnej pary wierzchołków zachodzi:
δh(u,v)=δ(u,v)+h(u)h(v).


Wniosek 10

Ścieżka p z wierzchołka u do wierzchołka v jest najkrótszą ścieżką w G=(V,E) dla funkcji wagową w wtedy i tylko wtedy, gdy jest najkrótszą ścieżką w G dla funkcji wagowej wh.

Dowód

Wniosek ten wynika wprost z Lematu 8 i Wniosku 9, który pokazuje, że odległości transformują się tak samo jak wagi ścieżek, a więc równość w(p)=δ(u,v) jest równoważna równości wh(p)=δh(u,v).


Funkcję h nazwiemy potencjałem jeżeli zachodzi:

wh(u,v)0, dla (u,v)E.      (4)


Pokażemy teraz, jak wyznaczyć funkcję potencjału h dla grafu G. Rozważmy następujący algorytm:

Algorytm Algorytm obliczania potencjału


 OBLICZ-POTENCJAŁ(G=(V,E),w)
 1  s nowy wierzchołek
 2  V=V{s}
 3  E=E{(s,v):vV}
 4  w(u,v)={w(u,v),jeżeli (u,v)E0jeżeli u=s0w pozostałych przypadkach
 5  (d,π)=BELLMAN-FORD(G,w,s)
 6  if (d,π)=NIL then
 7    return NIL (graf zawiera cykl ujemnej długości)
 8  return d (d(v) obliczone w algorytmie Bellmana-Forda jest potencjałem)

Działanie tego algorytmu przedstawione jest na poniższej animacji. <flash>file=Zasd_ilustr_c.swf |width=600|height=300</flash>

Lemat 11

Jeżeli graf G=(V,E) z wagami krawędzi zadanymi funkcją w zawiera cykl o ujemnej wadze, to algorytm OBLICZ-POTENCJAŁ zwraca wartość NIL. Natomiast w przeciwnym wypadku algorytm zwraca potencjał d(v) dla grafu G z funkcją wagową w.

Dowód

Zauważmy, że dodanie wierzchołka s do grafu G nie wprowadza nowych cykli, a jedynie powoduje, że wszystkie wierzchołki są osiągalne z s. Dlatego algorytm Bellmana-Forda uruchamiany dla G i wierzchołka s zwraca NIL wtedy i tylko wtedy, gdy G zawiera cykl o ujemnej wadze.

Zakładamy teraz, że graf G nie zawiera cyklu o ujemnej wadze, wtedy wartości d(v) jako odległości w grafie spełniają:


d(v)d(u)+w(u,v).


Innymi słowy:


wd(u,v)=w(u,v)+d(u)d(v)0,


co kończy dowód lematu.


Powyższy lemat jest ostatnim składnikiem potrzebnym nam do konstrukcji algorytmu Johnsona.

Algorytm Algorytm Johnsona


 JOHNSON(G=(E,V),w)
 1  d=OBLICZ-POTENCJAŁ(G,w)
 1  if d=NIL then return NIL
 3  for każda krawędź (u,v)E do
 4     wd(u,v)=w(u,v)+d(u)d(v)
 5  for każdy wierzchołek uV do
 6    (dh,π) = DIJKSTRA(G,wh,u)
 7    for każdy wierzchołek vV do
 8      d(u,v)=dh(v)+h(v)h(u)
 9  return D

Poprawność tego algorytmu wynika wprost z Lematu 11. Czas działania algorytmu jest równy sumie czasu działania algorytmu Bellmana-Forda i czasu potrzebnego na O(|V|) wywołań algorytmu Dijkstry, co daje całkowity czas O(|V||E|+|V|2log|V|).