260 likes | 407 Views
ALGORYTMY I STRUKTURY DANYCH. WYKŁAD 03 cd. Wyszukiwanie Grażyna Mirkowska PJWSTK, 2003/2004. Plan wykładu. Drugi co do wielkości element Algorytm turniej K-ty co do wielkości element ciągu Algorytm Hoare Wyszukiwanie w ciągu uporządkowanym Algorytm bisekcji.
E N D
ALGORYTMY I STRUKTURY DANYCH WYKŁAD 03 cd. Wyszukiwanie Grażyna Mirkowska PJWSTK, 2003/2004
Plan wykładu • Drugi co do wielkości element • Algorytm turniej • K-ty co do wielkości element ciągu • Algorytm Hoare • Wyszukiwanie w ciągu uporządkowanym • Algorytm bisekcji G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Drugi największy element ciągu Problem Dany jest ciąg różnych elementów e[1],...,e[n] pewnej przestrzeni liniowo uporządkowanej < E, >. Znaleźć drugi co do wielkości element tego ciągu. WP = { e[i] e[j] dla i j , n>0}, WK = {1 wynik n, e[j] e[wynik] < e[max] dla j=1,2,...,n } e[wynik] = maximum({e[1]...,e[n]} - maximum{e[1],...,e[n]}) Algorytm naiwny : 1. Znaleźć element maksymalny. 2. Usunąć go z rozważań . 3. Znaleźć element maksymalny w pozostałym zbiorze. G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Algorytm naiwny { i := 2; max :=1; while i n do if e[i] > e[max] then max := i fi; i := i+1; od; pom := e[1]; e[1] := e[max]; e[max] := pom; i:=3; wynik := 2; while i n do if e[i] > e[wynik] then wynik := i fi; i := i+1; od;} e[max] := maksimum(1,n); • Max: = 1;for ( i =2; i<= n; i++){ if (e[i]>e[max]) {max:=i;}} Swap(e[1], e[max]); • wynik := 2;for ( i =3; i<= n; i++){ if (e[i]>e[wynik]){wynik:=i;}} e[wynik] := maksimum(2,n); Koszt T(n) = 2n -3 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Czy można to zrobić lepiej? 4 2 3 5 7 8 1 6 Metoda polega na porównywaniu sąsiednich elementów ciągu. Elementy większe (wygrywające) przechodzą do następnej ‘rundy’. Metoda - Turniej 4 5 8 6 5 8 8 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Analiza metody Każdy element, z wyjątkiem maksymalnego przegrał co najwyżej raz. Element drugi co do wielkości przegrał jedynie z elementem maksymalnym. Gdzie szukać elementu "drugiego" ? Wśród elementów, które grały z największym! Por. przykład G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Koszt algorytmu Turniej Załóżmy, że n= 2k. n -1 porównań Krok1. Zbudowanie drzewa turnieju. Krok 2. Wybranie elementu drugiego największego. lg n -1 Tyle, ile było ‘rund’! A ile elementów przegrało z największym? Razem : T(n)= n + lg n -2 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
k-ty największy element Problem: Dany jest ciąg n-elementów pewnej przestrzeni liniowo uporządkowanej <E, >. Znaleźć k-ty największy element tego ciągu. Przykład 2, 4, 6, 12, 78, 45, 3, 33, 17, 22 Element największy = 78element drugi co do wielkości = 453-ci największy = 334-ty największy = 22 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Pierwsze rozwiązanie Krok1. Wyszukaj element e[max] największy wśród elementów e[i],...,e[n]; Krok 2. Zamień elementy na pozycjach i-tej oraz max Krok 3. Powtórz postępowanie dla następnego i. Koszt : T(n) = (n-1) + (n-2) +... +(n-k) =k*n - k*(k+1)/2 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Algorytm naiwny Zakładam, że elementy w ciągu e nie powtarzają się. { x := 1; while x k do max := x; for i := x+1 to n do if e[i] > e[max] then max := i fi od; swap(e[x], e[max]); x := x+1; od; wynik := e[k]} Niezmiennik e[1]>...>e[x-1] >{e[x],...,e[n] } e[max] {e[x],...,e[n]} e[1]>...>e[x-1] >{e[x],...,e[n] } G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Czy można to zrobić taniej? M = mediana Rozdziel wszystkie elementy na większe od pewnego elementu M(część starsza) i na mniejsze od M (część młodsza). Umieść medianę tak by oddzielała cześć młodszą od starszej. Wynikiem jest mediana, jeśli w części starszej jest tylko k-1 elementów. W przeciwnym przypadku: jeśli elementów starszych jest >k-1, to szukaj k-tego elementu w części starszej. Jeśli elementów starszych jest mniej niż k-1, to szukaj elementu k-(liczba elementów starszych+1) wśród elementów młodszych. G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Przykład 5 7 9 4 3 2 6 1 11 12 Część młodsza Część starsza 4 3 2 1 7 9 6 Część młodsza Część starsza W podanym ciągu szukamy 7tego co do wielkości elementu 10 5 7 9 11 4 3 2 12 8 6 1 mediana 10 5 7 9 4 3 2 6 1 Szukam 4-go największego mediana 5 Wynikiem jest element 5 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Algorytm Hoare Zakładam, że elementy w ciągu nie powtarzają się i, że algorytm zwraca jako wynik wartość k-tego największego elementu. function Hoare(l, p, k){ j := SPLIT(l, p); if ( p-j = k-1) then wynik := e[j] else if p-j>k-1 then Hoare(j+1, p, k) else Hoare(l,j-1, k-(p-j+1)) fi fi} {e[1]...,e[j-1]}< e[j]<{e[j+1],...,e[n]} K-ty największy znajduje się wśród elementów e[j+1],... e[p] K-ty największy znajduje się wśród elementów e[l],... e[j-1] G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Algorytm rozdzielania int function SPLIT(lewy,prawy){ mediana := e[lewy]; i := lewy+1; j := prawy; bool := true; while (bool) do while (j>lewy andif e[j] mediana ) do j := j-1 od; while (i<j andif e[i] < mediana) do i := i+1 od; if (i<j) then swap(e[i], e[j]); i := i+1; j := j-1; else bool := false fi od; swap(e[lewy],e[j]); return j; } powrót (k, lewy< k <j) e[k] < e[j] (k, j < k prawy) e[j] e[k] G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Jak to działa? i < j 10, 5, 9, 8, 3, 7, 12, 14, 11 mediana j i i > j 10, 5, 9, 8, 3, 7, 12, 14, 11 j i powrót 3 14 10, 5, 9, 8, 14, 7, 12, 3, 11 mediana i j 7 10 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Koszt algorytmu Hoare Każdy element jest co najwyżej raz porównywany z medianą. Koszt algorytmu SPLIT Czyli T(SPLIT, n ) = n-1 = (n) Czyli W(n,k)= k*n – k(k+1)/2 W( n,k) = n-1 +W( n-1,k) A(n,k) = (n-1) + 1/n[ Sj=1...n-k A(n-j, k) + Sj=n-k+2... n A(j-1,k – (n-j+1)] Szukanie w części starszej Szukanie w części młodszej A(n,k) = O(n) G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Przedział 1 Przedział n-1 Przedział 0 Przedział n ... e[1] e[2] e[3] e[n-1] e[n] Wyszukiwanie w ciągu uporządkowanym Problem Dany jest ciąg rosnący e[1],..,e[n] oraz element x pewnej przestrzeni liniowo uporządkowanej <E, >. Chcemy ustalić przedział e[i], e[i+1], w którym ewentualnie mieści się x. Specyfikacja : wp= {(i<n) e[i]<e[i+1] , n>0 } wk= {wynik= i wttw x należy do itego przedziału} Metoda sekwencyjna1. Zbadamy przypadki skrajne: przedział 0 i przedział n-ty i ew. kończymy .2. Następnie porównujemy x z kolejnymi elementami ciągu poczynając od e[2]. Jeśli x jest mniejsze prawego końca rozważanego i-tego przedziału, to znaczy , że x znajduje się w tym przedziale, e[i] x <e[i+1]. Jeśli tak nie jest, to trzeba zbadać następny przedział. G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Metoda poszukiwań sekwencyjnych Poniważ x e[i+1], to i+1 nie może być równe n,bo z wcześniejszych porównań wiemy, że x<e[n]. Czyli i+1<n Koszt algorytmu { if x<e[1] then i := 0 else if x e[n] then i := n else i := 1; while x e[i+1] { i := i+1; } fi; fi; wynik := i;} e[i]x e[n], 1i n e[i]x , xe[i+1], i+1 n xe[i] , i n W skrajnych przypadkach mamy 1 lub 2 porównania W najgorszym razie 2 + (n-1) porównań.Czyli W(n) = O(n). e[i] x e[i+1], i n A koszt średni? G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Koszt średni algorytmu sekwencyjnego Rozszerzamy dany ciąg o elementy a i b, tzn. przyjmujemy e[0] = a i e[n+1] =b, gdzie [a,b] jest przedziałem, w którym mieszczą się elementy ciągu oraz x. Załóżmy, że prawdopodobieństwo tego, że x przyjmuje jakąś wartość z przedziału [a,b] jest zawsze takie samo. Mamy p(x [e[i],e[i+1])) = (e[i+1] – e[i])/(b-a) Koszt oczekiwany algorytmu A(n) = Jeśli długości przedziałów są takie same, to A(n) = n/2 +c, gdzie c<2 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Algorytm bisekcji Metoda „dziel i zwyciężaj” Podziel dany ciąg na dwie części. Sprawdź, w której połowie ciągu znajduje się poszukiwany element i dalej szukaj tą samą metodą w tej właśnie połowie. wp : e[1] x < e[n], n>1 wk: e[wynik] x< e[wynik+1] { i :=1; j := n; while j-i >1 do m := (i+j) div 2; if e[m] x then i := m else j := m fi od; wynik := i} Niezmiennike[i] x e[j], i j 1+i = j oraz e[i] x e[j] G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Koszt algorytmu bisekcji Czy ten algorytm zatrzymuje się ? Niech k będzie liczbą wykonanych iteracji pętli oraz odl(k) = j - i. Przed wykonaniem pętli mamy k=0 i odl(k) = n-1. odl(k+1) = odl(k)/2, jeśli odl(k) jest liczbą parzystą(odl(k)-1)/2 odl(k+1) (odl(k)+1)/2 , jeśli odl(k) jest liczbą nieparzystą Odl(k) jest liczbą całkowitą z przedziału [1,n-1 ] i ze wzrostem k maleje! Istnieje zatem takie k, że odl(k)=1. A więc algorytm zatrzymuje się. A jaka jest największa wartość k? k =[ lg n] G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Następne slajdy będą wykorzystane na ćwiczeniach G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Skoki „co 4” omiń Idea Porównujemy element x z co czwartym elementem danego ciągu tak długo aż znajdziemy element większy od x. Wtedy szukamy x sekwencyjnie wśród czterech poprzedzających go elementach ciągu. Metoda dokładniej: 1 krok: Zbadać czy x [e[1],e[n]). Jeśli nie, to ustalić wynik zgodnie ze specyfikacją, a jeśli tak to wykonać krok 2. 2 krok: Porównywać x z kolejnymi elementami o indeksach 4i, tak długo aż (a) znajdziemy element e[4i]>x lub (b) aż przekroczymy n (a) szukamy wyniku sekwencyjnie w przedziale [e[4i- 4], e[4i]), (b) szukamy wyniku sekwencyjnie w przedziale [e[4i- 4], e[n]). G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Algorytm skoki „co 4” { if x < e[1] then i :=0 else if x e[n] then i := n else i := 4; bool := false; while (i n and not bool) do if x e[i] then i := i + 4 else bool := true fi od; i := i- 4; while x e[i+1] do i := i+1 od; fi; fi; wynik := i } e[1] x e[n] e[j] x dla j=1,2,...,i-4, bool e[j] x dla j=1,2,...,i, bool, in e[j] x dla j=1,2,...,i-4, bool , in+4 e[j] x dla j=1,2,...,i-4, x<e[i], bool bool oraz e[i- 4] x<e[i] lub bool oraz e[i- 4] x<e[n] Koszt pesymistyczny: W(n)= 2 +[n/4]+3 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Skoki „co k” { if x < e[1] then i :=0 else if x e[n] then i := n else i := k; bool := false; while (i n and not bool) do if x e[i] then i := i + k else bool := true fi od; i := i-k; while x e[i+1] do i := i+1 od; fi; fi; wynik := i } Niezmiennik: e[j] x<e[n] dla j=1,2,...,i-k, i n+k G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Optymalne k Dla jakich wartości k algorytm ma najmniejszy koszt pesymistyczny? Koszt pesymistyczny wyraża się funkcją f(n) = 2 + n/k + ( k-1) Szukamy minimum tej funkcji: f’(k) = -n/k2 + 1 f’(k) = 0 dla k = n oraz f’’ ( n)>0 Koszt pesymistyczny będzie najmniejszy, gdy k = n Wniosek G. Mirkowska, ASD_03 Wyszukiwanie c.d.