ALGORYTMY I STRUKTURY DANYCH WYKŁAD 03 cd. Wyszukiwanie Grażyna Mirkowska PJWSTK
G. Mirkowska, ASD_03 Wyszukiwanie c.d. Plan wykładu Problem min-max algorytm naiwny algorytm rekurencyjny optymalność Drugi co do wielkości element Algorytm turniej K-ty co do wielkości element ciągu Algorytm Hoare 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Specyfikacja algorytmu Minimum i maksimum Dany jest ciąg elementów e[i] i = 1,...,n należących do pewnego zbioru E liniowo uporządkowanego przez relację . Znaleźć największy i najmniejszy element tego ciągu. Problem Specyfikacja algorytmu Wp = { e[i] e[j] dla i j} Wk = { e[min] e[i] oraz e[max] e[i] dla wszystkich i =1,2...n}. Znajdź minimum metodą sekwencyjnego przeglądania ciągu. Znajdź maksimum, tą samą metodą. Algorytm naiwny T(A,n)= 2n-2 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Modyfikacja algorytmu naiwnego Algorytm naiwny nie jest optymalny! Jeśli e[i] jest większe od e[max], to nie ma potrzeby porównywać e[i] z e[min]. { min :=1; max :=1; for i := 2 to n do if e[i] >e[max] then max := i else if e[i]< e[min] then min := i fi fi od; } Algorytm 2 Niezmiennik ( 1j<i)(e[max] e[j] e[min]e[j]) Koszt W(n) = 2n-2 A(n) = O(n) Czy ten wynik można poprawić? 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Analiza kosztu średniego Uwaga 1 Pierwsze porównanie jest wykonywane w każdym przebiegu pętli. Uwaga 2 Drugie porównanie jest wykonywane tylko wtedy, gdy odpowiedź w pierwszym porównaniu jest negatywna. A(n) = S d Dn p(d)* t(d) Dn - zbiór wszystkich danych rozmiaru n. Założymy, że wszystkie permutacje są jednakowo prawdopodobne. Zbiór wszystkich permutacji p(d) = 1/n! 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
G. Mirkowska, ASD_03 Wyszukiwanie c.d. Koszt średni c.d. Niech d = a1...an będzie daną permutacją liczb 1...n i b = b1,...bn będzie ciągiem takim, że bi = liczba elementów większych niż ai na lewo od ai , tzn. o mniejszych indeksach w ciągu d. Przykład Niech d = 6752314, wtedy b = 0023353. Obserwacja (a) Ciąg b jest jednoznacznie wyznaczony przez d. (b) 0 bi < i Drugiego porównania w algorytmie nie wykonujemy tylko wtedy, gdy na lewo od i-tego elementu nie było liczby większej, czyli tylko wtedy, gdy bi =0. 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
G. Mirkowska, ASD_03 Wyszukiwanie c.d. Koszt średni c.d Prawdopodobieństwo tego, że bi =0 wynosi 1/i, ponieważ bi przyjmuje tylko wartości od 0 do i-1. Stąd prawdopodobieństwo wykonania drugiego porównania wynosi 1-1/i. Średni koszt dla danych d: t(d) = (n-1) + S i =2...n 1* p(drugie porównanie) = (n-1) + S i=2...n (1-1/i) = 2n-2 - lg n +c 1/x dx= O(lg|x|) Ostatecznie A(n) = S d 1/n! t(d) = 2n - lg n + c 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Min-max rekurencyjny -- przykład Założenie: n = 2 k Dany ciąg: 4, 5, 1, 8, 33, 11, 44, 10, 7, 2, 13, 22, 3, 55, 9, 6 4, 5, 1, 8, 33, 11, 44, 10 min= max= 7, 2, 13, 22, 3, 55, 9, 6 min= max= 1 44 7, 2, 13, 22 min= max= 3, 55, 9, 6 min= max= 4, 5, 1, 8 min= max= 33, 11, 44, 10 min= max= 1 8 10 44 4,5 33,11 44,10 7,2 13,22 1,8 3,55 9,6 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Min-max rekurencyjny -- przykład c.d. Dany ciąg: min = 1 max = 55 4, 5, 1, 8, 33, 11, 44, 10, 7, 2, 13, 22, 3, 55, 9, 6 4, 5, 1, 8, 33, 11, 44, 10 min= max= 7, 2, 13, 22, 3, 55, 9, 6 min=2 max=55 1 44 7, 2, 13, 22 min=2 max=22 3, 55, 9, 6 min=3 max=55 4, 5, 1, 8 min= max= 33, 11, 44, 10 min= max= 1 8 10 44 4,5 33,11 44,10 7,2 13,22 1,8 3,55 9,6 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Algorytm min-max rekurencyjny obiekt function min_max (int i, j); //deklaracja i tworzenie obietktów result, lewy, prawy; { if ( i+1=j ) then if e[j] > e[i] then result.max := j; result.min := i else result.min := j; result.max :=i fi else x:= (i+j-1) div 2; lewy := min_max( i, x); prawy := min_max( x+1, j); if e[prawy.min]<e[lewy.min] then result.min := prawy.min else result.min := lewy.min fi; if e[lewy.max]< e[prawy.max] then result.max := prawy.max else result.max := lewy.max fi; fi } min max obiekt i x j 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
G. Mirkowska, ASD_03 Wyszukiwanie c.d. Poprawność min-max wp = {( m) n = 2 m, e[i] <E, > dla i=1,...n} wk = {(i n) e[min] e[i] , (i n) e[i] e[max]} Jeżeli spełniony jest warunek początkowy wp , to po wykonaniu następujących instrukcji {wynik := min_max(1,n); min := wynik.min; max := wynik.max;} spełniony będzie warunek końcowy wk. Twierdzenie 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Czy algorytm min-max zatrzymuje się? W każdym wywołaniu funkcji min_max(i,j) parametry aktualne i, j spełniają warunek j-i+1 = 2 k dla pewnego k, 1 k m Lemat j = n, i =1 Dla pierwszego wywołania własność jest oczywiście spełniona. bo i+1=j Jeżeli w ciągu są tylko 2 elementy, tzn. k=1. Wtedy nie wywołujemy powtórnie funkcji min-max. Jeżeli k>1 oraz j-i+1 = 2 k , to funkcja zostanie wywołana dla nowych argumentów: i, x oraz x+1, j, ale wtedy x-i+1 = (i+j-1)/2 – i +1 = (j-i+1)/2 = 2 k-1 Min- max j-(x+1)+1 = j – ((i+j-1)/2 +1) +1 =(j-i+1)/2 = 2 k-1 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
G. Mirkowska, ASD_03 Wyszukiwanie c.d. c.d. ‘stop’ dla min-max jest 2 razy mniejsza Długość rozważanego przez funkcję min-max ciągu maleje w kolejnych wywołaniach. W konsekwencji proces musi się zakończyć dla k=1. Wniosek Jeśli spełniony jest warunek początkowy wp, to algorytm min_max zatrzymuje się dla dowolnych danych. 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Poprawność algorytmu min-max Dowód przez indukcję ze względu na liczbę wywołań rekurencyjnych funkcji min_max. Analogicznie dla minimum Dla jednego tylko wywołania , tzn. gdy m=1 wynik algorytmu jest poprawny. Załóżmy, że wynik algorytmu jest poprawny dla wewnętrznych wywołań, czyli if e[lewy.max]<e[prawy.max] then result.max := prawy.max else result.max := lewy.max fi; e[k] e[lewy.max] dla i k x oraz e[k] e[prawy.max] dla x+1 k j Po wykonaniu instrukcji : Mamy : e[k] e[result.max] dla i k j 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Koszt rekurencyjnego alg. min_max Operacja dominująca - porównywanie elementów Jeśli w ciągu są tylko 2 elementy, to wykonujemy 1 porównanie T(min_max, 2) = 1 T(min_max, 2 k)= 2* T(min_max,2 k-1) +2 Min- max Dla k>1 wykonujemy 2 wywołania rekurencyjnie Dwa dodatkowe porównania dla ustalenia ostatecznego wyniku T(2k) = 3*2 k-1 - 2 Ostatecznie: T(min_max, n) = 3/2 n - 2 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Czy można zrobić lepiej? min_max jest optymalnym rozwiązaniem problemu min-max Twierdzenie Każdy algorytm wyznaczający minimum i maksimum dowolnego ciągu e[1],...e[n] elementów dowolnej liniowo uporządkowanej przestrzeni musi wykonać w przypadku pesymistycznym co najmniej [3/2 n] – 2 porównania. 2018-12-01 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 = 78 element drugi co do wielkości = 45 3-ci największy = 33 4-ty największy = 22 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
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 2018-12-01 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. 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
G. Mirkowska, ASD_03 Wyszukiwanie c.d. Przykład W podanym ciągu szukamy 7tego co do wielkości elementu 10 , 5, 7, 9, 11, 4 , 3, 2, 12, 6, 1 mediana Część młodsza 5 7 9 4 3 2 6 1 10 Część starsza 11 12 5 7 9 4 3 2 6 1 Szukam 4-go największego mediana Część młodsza 4 3 2 1 5 Część starsza 7 9 6 Wynikiem jest element 5 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
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);//lub Partition(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] 2018-12-01 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] 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Algorytm rozdzielania int Partition (l, p: int){ x := e[p]; i := l - 1; j := l; while (j < p) do if e[j] ≤ x then swap(e[i+1], e[j]); i := i+1; fi; j := j+1 od ; swap(e[i+1],e[p]); result := i+1; return result } Rola wskaźników i, j w algorytmie Partition jest następująca: wszystkie elementy na pozycjach od l do i są mniejsze lub równe x, na pozycjach od i+1 do j-1, są większe od x. Pozostałych miejsc jeszcze nie zbadaliśmy. 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
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[ S j=1...n-k A(n-j, k) + S j=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) 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
G. Mirkowska, ASD_03 Wyszukiwanie c.d. Cwiczenia Na ćwiczeniach Inna wersja algorytmu min-max oraz Analiza algorytmu naiwnego wyszukiwania elementu k-tego co do wielkości. Przedyskutować znajdowanie mediany (tzn elementu, który powinien znaleźć sie na środku ciągu gdy zostanie on uporządkowany np. rosnąco.) Można założyc, że elementy nie powtarzają się , i że jest ich 2k+1. Można też rozważyć algorytm Partition (odmiana Split). 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Algorytm naiwny- kty co do wielkości 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] } 2018-12-01 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. 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
e[max] := maksimum(1,n); e[wynik] := maksimum(2,n); 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 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Czy można to zrobić lepiej? Metoda polega na porównywaniu sąsiednich elementów ciągu. Elementy większe (wygrywające) przechodzą do następnej ‘rundy’. 2 3 4 6 1 8 7 5 Metoda - Turniej 4 5 8 6 5 8 8 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Gdzie szukać elementu "drugiego" ? 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 2018-12-01 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 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
G. Mirkowska, ASD_03 Wyszukiwanie c.d. Algorytm min-max 3 Uwaga. Nie musimy przenosić samych elementów do tablic M i W. Wystarczy zapamiętać pozycje tych elementów. Idea algorytmu: Porównaj parami elementy danego ciągu. Mniejszy z każdej pary wstaw do ciągu M, a większy z każdej pary do ciągu W. Mniejsze: Większe: 5 8 34 44 7 4 1 11 4 2 Wspomnij o różnych wersjach tego algorytmu: Np.. bez pomocniczych tablic ale z zamianami , z innym ustawieniem par, np.:pierwszy-ostatni itd Wybierz minimum Wybierz maksimum Dany ciąg: 4, 5, 1, 8, 34, 11, 44, 4, 7, 2, 4, 5, 1, 8, 34, 11, 44, 4, 7, 2, drugi 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
G. Mirkowska, ASD_03 Wyszukiwanie c.d. Analiza kosztu { // min-max i:=1; k:=1; while i< n do if e[i] >e[i+1] then w[k] :=i; m[k] :=i+1 else w[k] :=i+1; m[k] :=i fi i := i+2; k := k+1; od; min := m[1]; max :=w[1]; for i := 2 to k-1 do if e[m[i]] < e[min] then min := m[i] fi; if e[w[i]]> e[max] then max := w[i] fi; od; } Operacja dominująca : porównywanie. Załóżmy, że n jest liczbą parzystą. 1szy krok = n/2 porównań Wybranie minimum = n/2 - 1 porównań Wybranie maksimum = n/2 - 1 porównań. Razem = 3n/2 -2 porównań 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
G. Mirkowska, ASD_03 Wyszukiwanie c.d. Analiza poprawności Niezmiennik { //rozdzielanie i:=1; k:=1; while i< n do if e[i] >e[i+1] then w[k] :=i; m[k] :=i+1 else w[k] :=i+1; m[k] :=i fi i := i+2; k := k+1; od; } Dla każdego j=1...k-1 istnieje takie u<k, że e[m[j]] e[w[u]] Dla każdego j=1...k-1 istnieje takie u<k, że e[w[j]] e[m[u]] Żaden indeks w tablicy w[i] nie może wskazywać minimum ciągu e. Żaden indeks w tablicy m[i] nie może wskazywać maksimum ciągu e. 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Analiza poprawności c.d. Wśród indeksów m[1], ...m[k] istnieje taki indeks min, że e[min] e[i] dla wszystkich i =1,...n Wśród indeksów m[1], ...m[k] istnieje taki indeks max, że e[i] e[max] dla wszystkich i =1,...n min := m[1]; max :=w[1]; for i := 2 to k-1 do if e[m[i]] <e[min] then min := m[i] fi; if e[w[i]]> e[max] then max := w[i] fi; od; e[min] e[i] dla wszystkich i =1,...n e[i] e[max] dla wszystkich i =1,...n 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.
Jak działa algorytm SPLIT? powrót 3 14 10, 5, 9, 8, 14, 7, 12, 3, 11 mediana i < j i j 10, 5, 9, 8, 3, 7, 12, 14, 11 i j mediana 7 10 i > j 10, 5, 9, 8, 3, 7, 12, 14, 11 i j 2018-12-01 G. Mirkowska, ASD_03 Wyszukiwanie c.d.