• Nie Znaleziono Wyników

ALGORYTMY I STRUKTURY DANYCH

N/A
N/A
Protected

Academic year: 2021

Share "ALGORYTMY I STRUKTURY DANYCH"

Copied!
15
0
0

Pełen tekst

(1)

ALGORYTMY I STRUKTURY DANYCH

WYKŁAD 02 Algorytmy wyszukiwania Grażyna Mirkowska

PJWSTK, ITN semestr letni 2002

(2)

Plan wykładu

Wyszukiwanie w ciągu nieuporządkowanym.

Wyszukiwanie w ciągu uporządkowanym.

Metoda poszukiwań sekwencyjnych Metoda poszukiwań „skokowych”.

Optymalna długość skoku Metoda poszukiwań binarnych.

Analiza poprawności i kosztu

(3)

Wyszukiwanie w ciągu nieuporządkowanym

Problem Niech E będzie daną przestrzenią, a X jej skończonym podzbiorem. Zbadać, czy dany element x przestrzeni E należy do wybranego podzbioru X.

Metoda rozwiązania polega na porównywaniu kolejnych elementów ciągu, poczynając od

pierwszego, z elementem x. Jeśli badany element jest równy x, to kończymy postępowanie; jeśli nie, to rozważamy następny element ciągu.

Specyfikacja

Specyfikacja wp ={(ei ) ciąg n elementów przestrzeni E , n 1}

wk ={ wynik  ( i n) ei = x}

Zakładamy, że elementy ciągu są przechowywane w pewnej tablicy e[1], e[2],...,e[n].

(4)

Diagram przepływu

początek

koniec i n and not wynik

x= e[i]

wynik := true

wynik := false; i := 1;

i := i+1;

x  {e[1],...,e[i-1]}, wynik=false , i=1

x  {e[1],...,e[i-1]}, in+1,wynik=false, in

x=e[i], in wynik=true

x  {e[1],...,e[i-1]}, in, x e[i]

x  {e[1],...,e[i-1]}, in+1, wynik=false

Tak Nie

(5)

Algorytm Wersja 1

Wersja 1

{

i :=1; wynik := false;

while ( i  n and not wynik) { if x=e[i] then

wynik := true else

i := i+1 fi;

} }

wynik= true, i  n , e[i]=x lub

wynik=false, i=n+1, x  {e[1],...,e[i-1]}

wynik = true wttw dla pewnego i  n , e[i]=x

Wersja 2 Wersja 2

{

e[n+1]:= x; i:=1;

while (e[i]  x ) { i := i+1; }

wynik := (i  n );

}

(6)

Koszt algorytmu

Operacja dominująca = porównywanie elementów W najlepszym razie algorytm wykona 1 porównanie.

W najgorszym razie n- porównań.

Koszt

Koszt

średni średni A(n)=d Dn p(d) * t(d)

Prawdopodobi eństwo

wystąpienia danych d

Koszt realizacji algorytmu dla danych d

Niech p(xX)= p i załóżmy, że jest jednakowo prawdopodobne, że x znajduje się na 1szym, 2gim czy i-tym miejscu.

Wtedy p(x=e[i]) = p/n.

Zatem A(n) =1* p/n+ 2*p/n +...+n*p/n +n*(1-p) = n - (n-1)*p/2.

A koszt

pamięciowy

?

(7)

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

Specyfikacja

: wp= {(i<n) e[i]<e[i+1] , n>0 }

wk= {wynik= i wttw x należy do itego przedziału}

Metoda sekwencyjna

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

e[1] e[2] ... e[n-1] e[n]

Przedział 0 Przedział 1 Przedział n-1 Przedział n

e[3]

(8)

Metoda poszukiwań sekwencyjnych

{

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[i+1], i n

e[i]x  e[n], 1i  n

e[i]x , xe[i+1], i+1  n xe[i] , i n

Koszt Koszt

algorytmu algorytmu

W skrajnych przypadkach mamy 1 lub 2 porównania W najgorszym razie 2 + (n-1) porównań.Czyli W(n) = O(n).

(9)

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) =





)) 1 (

]) 1 [

] [ ( ...

3 ]) 1 [ ] 2 [ (

2 ]) [ ] 1 [

( 1 ]) 0 [ ] 1 [ 1 (

) 2 ] (

[ ] 1 2 [

] [ ] 1 1 [

] 0 [ ] 1 ) [

( 1

1

n n

e n

e e

e

n e n

e e

e a b

a i b

i e i

e a

b

n e n

e a

b e n e

A n

i

) 1 (

] 2 [ ]

[ ]

1 [

] [ ) 1 (

] [ ]

1 [ 2 1 2

1

1

2

a n b

i e n

e a

b e b a b

a b

n e n

i e e

b a a

b

n

n i

Jeśli długości przedziałów są takie same, to A(n) = n/2 +c, gdzie c<2

(10)

Skoki „co 4”

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

(11)

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

(12)

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 }

e[j]  x<e[n] dla j=1,2,...,i-k, i  n+k

(13)

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

(14)

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.

{ 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 := j }

wp : e[1]  x < e[n], n>1

wk : e[wynik]  x< e[wynik+1]

Niezmiennik e[i]  x  e[j], i  j

1+i = j oraz e[i]  x  e[j]

(15)

Koszt algorytmu bisekcji

Czy ten algorytm zatrzymuje się ? 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]

Cytaty