1 / 26

ALGORYTMY I STRUKTURY DANYCH

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.

melba
Télécharger la présentation

ALGORYTMY I STRUKTURY DANYCH

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ALGORYTMY I STRUKTURY DANYCH WYKŁAD 03 cd. Wyszukiwanie Grażyna Mirkowska PJWSTK, 2003/2004

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

  3. 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.

  4. 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.

  5. 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.

  6. 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.

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

  8. 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.

  9. 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.

  10. 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.

  11. 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.

  12. 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.

  13. 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.

  14. 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.

  15. 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.

  16. 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.

  17. 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.

  18. 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], 1i  n e[i]x , xe[i+1], i+1  n xe[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.

  19. 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.

  20. 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.

  21. 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.

  22. Następne slajdy będą wykorzystane na ćwiczeniach G. Mirkowska, ASD_03 Wyszukiwanie c.d.

  23. 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.

  24. 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, in e[j]  x dla j=1,2,...,i-4,  bool , in+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.

  25. 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.

  26. 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.

More Related