Upload
laparise
View
142
Download
3
Embed Size (px)
DESCRIPTION
Dio iz seminarskog rada na temu Algoritmi pretraživanja
Citation preview
1. UVOD
U ovom radu ćemo razmotriti problem pronalaženja određene informacije u
velikom skupu podataka. Kao što ćemo videti, izvjesne metode organizacije podataka
(tj. strukture podataka) čine proces pronalaženja efikasnijim. S obzirom da je proces
pretraživanja vrlo čest u obradi podataka, poznavanje metoda i tehnika organizacije
podataka pretraživanja je vrlo važno.
Pod pretraživanjem podrazumijevamo provjeru da li se zadana vrijednost
pojavljuje u nekoj kolekciji vrijednosti (nizu, strukturi ili datoteci). Efikasnost
pretraživanja uglavnom se mjeri prosječnim brojem poređenja koje je potrebno izvesti u
postupku traženja različitih vrijednosti u datoj kolekciji. Što je algoritam brži to je
kompleksniji i koristi više radne memorije.
Neki od razloga za pretraživanje su : utvrđivanje da li je elementa član liste,
pronalaženje pozicije za umetanje novog elementa ako je lista sortirana, i pronalaženje
lokacije elementa za brisanje.
U ovom seminarskom obradit ćemo tri osnovna algoritma pretraživanja:
1. Sekvencijalna (linearna) pretraga
2. Binarna pretraga
3. Interpolacijska pretraga
1
2. SEKVENCIJALNO PRETRAŽIVANJE
Sekvencijalna pretraga se još naziva i linearna pretraga, a predstavlja proces
traženja podatka u nekom nizu na taj način da se redom, od prvog do zadnjeg,
uspoređuju svi elementi tog niza sa elementom kojeg tražimo dok se ne naiđe na traženi
element ili dok se ne izađe iz okvira niza. Prilikom sekvencijalne pretrage podatka, skup
podataka koji se pretražuje ne treba biti sortiran. Ova pretraga ujedno predstavlja i
najjednostavniji način pretrage skupa podataka, ali nedostatak joj je veliko vrijeme
izvršavanja.
Ova se vrsta pretrage naziva i linearna jer ovisnost vremena pretrage o broju
elemenata u nizu upravo predstavlja funkciju koja ima linearni rast.
Slika 1. Zavisnost vremena o broju članova niza kod sekvencijalne pretrage
t – vrijeme
n – broj članova niza
2
Primjer:
Ukoliko imamo niz brojeva: 3, 5, 3, 9, 0, 12, 9, 4 i sekvencijalnom pretragom želimo
naći poziciju broja 0 tada bi se sekvencijalno traženje odvijalo tako da bi prvo usporedili
da li je:
3 == 0 (nije)
5 == 0 (nije)
3 == 0 (nije)
9 == 0 (nije)
0 == 0 (jeste)
Ovdje bi se pretraga završila i vratio bi se indeks 4 koji predstavlja poziciju broja 0 u
nizu (indeks prvog elementa je 0).
U svrhu implementacije sekvencijalne pretrage u C++ programskom jeziku napisat
ćemo funkciju koja će kao ulazne parametre primati:
niz cjelobrojnih vrijednosti,
broj koji predstavlja dužinu tog niza,
broj koji tražimo u nizu.
Funkcija će vraćati cjelobrojnu vrijednost koja predstavlja indeks traženog broja
u nizu, a ukoliko funkcija ne pronađe broj u nizu vratit će broj -1.
int sekvencijalnaPretraga(int *niz, int duzina, int broj) {
for (int i = 0; i < duzina; i++) {
if (niz[i] == broj) {
return i;
} }
return -1;}
3
Funkcija radi na taj način da se krene od prvog elementa prema zadnjem i
provjerava se jednakost trenutnog elementa u nizu sa brojem koji se traži. Kada se
ispostavi da je trenutni element niza jednak traženom broju - funkcija će vratiti indeks
tog elementa niza (naredba return osim što vraća vrijednost također i prekida dalje
izvršavanje funkcije). Ukoliko se pređu svi elementi niza, a ne nađe se traženi broj
funkcija će vratiti negativnu vrijednost -1.
4
3. BINARNO PRETRAŽIVANJE
Binarna pretraga je algoritam za pretraživanje određene vrijednosti u nizu koji
mora biti sortiran. Također moramo znati i dužinu niza. Ovaj algoritam spada u grupu
„podijeli pa vladaj“ algoritama.
U svakom koraku algoritam upoređuje traženu vrijednost sa pivotom (srednji
element niza). Ako se vrijednosti podudaraju traženi elemnt je pronađen i algoritam
vraća poziciju ili index, ovisno o tome šta smo zadali da funkcija vraća. U slučaju da
vrijednosti nisu jednake algoritam tad provjerava da li je pivot veći ili manji od tražene
vrijednosti. Ako je vrijednost pivota manja od tražene vrijednosti, algoritam nastavlja
pretraživanje u desnoj polovini niza. U slučaju da je vrijednost pivota veća od tražene
vrijednosti, algoritam će pretraživanje nastaviti u lijevom dijelu nizu. Dakle svakom
iteracijom niz se prepolovljuje.
Slika 2. Ilustracija binarne pretrage
5
U prosjeku, ako su elementi sortirani, binarna pretraga čini oko log 2 (n )
usporedbi, gdje je n broj elemenata niza. Binarna pretraga je daleko efikasnija od
sekvencijalne, pa tako npr. ako u sortiranom nizu brojeva od 1 do 60 tražimo broj 47
sekvencijalna pretraga će napraviti 47 provjera, dok će binarna napraviti manje provjera
i dosta brže pronaći traženi element što nam i dokazuje ovaj primjer.
1. Da li je broj veći od 30? -Jeste -Razmatramo brojeve od 30-60
2. Da li je broj veći od 45? -Jeste -Razmatramo brojeve od 45-60
3. Da li je broj veći od 52? -Nije -Razmatramo brojeve od 45-52
4. Da li je broj veći od 48? -Nije -Razmatramo brojeve od 45-48
5. Da li je broj veći od 46? -Jeste -Razmatramo brojeve od 46-48
6. Pitamo dali je broj jednak sa 47. -Jeste -Vratimo njegovu vrijednost.
Kod binarne pretrage je sljedeći:
#include <iostream>
using namespace std; int main(){ int velicina=5; int niz[]={1,5,2,4,3};
int donji=0, srednji, gornji=velicina-1, trazeniBroj=3; while (gornji>donji) { srednji=(gornji+donji)/2; if (niz[srednji]<trazeniBroj) { donji=srednji+1; } else { gornji=srednji; } }
6
cout<<"traženi broj se nalazi na indeksu "<<gornji<<" odnosno traženi broj je "<<niz[gornji]<<endl;
7
4. INTERPOLACIJSKO PRETRAŽIVANJE
Interpolacijsko pretraživanje je algoritam za pretraživanje dane vrijednosti u
poljima koja su indeksirana i sortirana po vrijednostima ključeva. Ovaj algoritam
pretraživanja možemo uporediti sa načinom kako ljudi pretražuju imenik. Npr. ako
tražimo broj neke osobe čije prezime i ime počinje s nekim od zadnjih slova abecede,
logično je da cemo imenik otvoriti pri kraju. Interpolacijska pretraga je ustvari
modificirana binarna pretraga.
U interpolacijskoj pretrazi „srednji“ element nije sredina niza kao što je slučaj
kod binarne pretrage. Srednji element se izračunava na osnovu vrijednosti koja se traži i
vrijednosti krajnjih elemenata u trenutnom segmentu koji se pretražuje tako da se
pokuša procijeniti gdje bi u takvom sortiranom segmentu mogao biti traženi podatak. To
se izvršava uz pomoć vrijednosti ključeva elemenata koji se nalaze na granicama
preostalog prostora za pretraživanje. Taj prostor za pretraživanje je na početku cijeli niz
ili lista, i on se svakom sljedećom iteracijom algoritma smanjuje za pola. Na sljedećoj
slici prikazan je odabir srednjeg (middle) elementa.
Slika 3. Interpolacija indeksa middle
Vrijednost ključa proračunate pozicije se upoređuje s vrijednošću koja se
pretražuje. Ako se ne podudaraju preostali prostor za pretraživanje se smanjuje.
Preostali prostor za pretraživanje postaje dio prije ili poslije proračunate pozicije,
zavisno od usporedbe vrijednosti za pretraživanje i srednje elementa. Ako je srednji
8
element manji od traženog elementa, lijeva strana niza se odbacuje i pretraživanje se
nastavlja u desnom dijelu niza i obrnuto.
U prosjeku, ako su elementi sortirani, interpolacijska pretraga čini oko
log(log(n)) usporedbi, gdje je n broj elemenata koji se moraju provjeriti. U najgorem
slučaju može doći i do n provjera. U prosjeku interpolacijska pretraga je uspješnija i
daje bolje rezultate od binarnog pretraživanja.
U ovom primjeru je prikazana implementacija interpolacijskog pretraživanja :
int interpolacijskaPretraga (int K[ ], int key, int length){
int bottom = 0, top = length - 1, middle;
while (K[low] < key && K[top] >= key) {
middle = bottom + ((key - K[bottom]) * (top - bottom)) / (K[top] - K[bottom]);
if (K[middle] < key)
bottom = middle + 1;
else if (K[middle] > key)
top = middle - 1;
else
return middle;
} //kraj while petlje
if (K[bottom] == key)
return bottom;
else
return -1; }//kraj funkcije.
9
5. ZAKLJUČAK
Ovaj seminarski rad bih zaključio uporedbom ova tri algoritma za pretraživanje,
odnosno njihovim prednostima i slabostima.
Prednosti sekvencijalnog algoritma je u tome što je algoritam dosta jednostavan i
elemnti liste mogu biti u bilo kojem poretku. Dok su mu slabosti neefikasnost (dosta je
spor). Za listu od N elemenata u prosjeku mora provjeriti n/2 elemenata a ako se tražena
vrijednost ne nalazi u listi moraju se provjeriti svi elementi.
Prednosti binarnog pretraživanja su mnogo veća efikasost pretraživanja od
sekvencijalnog pretraživanja. Primjera radi, za listu od 1.048.576 elemenata pri
sekvencijalnom pretraživanju bismo imali u prosjeku 524.266 iteracija, dok bismo pri
binarnom pretraživanju imali najviše 20 iteracija. Slabosti binarnog pretraživanja su da
niz mora biti sortiran i moramo imati direktan pristup elementima (preko indeksa).
Prednost interpolacijskog pretraživanja je još veća efikasnost pretraživanja nego
kod binarnog pretraživanja. U prosjeku daje bolje rezultate nego binarna pretraga.
Nažalost to vrijedi samo u slučaju ako su dane vrijednosti u poljima indeksirane i
sortirane po vrijednostima ključeva.
10
PITANJA I ZADACI
1. Objasniti funkciju sekvencijalne pretrage.
2. Implementirati funkciju koja vraća broj provjera binarne i sekvencijalne
pretrage.
3. Izračunati broj provjera binarne pretrage za niz koji sadrži 32768 članova.
4. Kako interpolacijska pretraga pronalazi srednji element odnostno pivot ?
11
POPIS SLIKA
1. Zavisnost vremena o broju članova niza kod sekvencijalne pretrage 2.
2. Ilustracija binarne pretrage 5.
3. Interpolacija indeksa middle 8.
12
LITERATURA
[1] http://algoritam.org/category/ostalo/cpp-programiranje
[2] http://en.wikipedia.org/wiki/Interpolation_search
[4] http://en.wikipedia.org/wiki/Binary_search_algorithm
[5] http://en.wikipedia.org/wiki/Linear_search
[6] Šupić H.: Algoritmi i strukture podataka (skripta)
[7] Pjanić E.:Algoritmi i strukture podataka (skripta)
13