Vous êtes sur la page 1sur 136

Contents

1 Opti pojmovi o algoritmima 2


1.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.2 Klasikacija algoritama . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.3 Predstavljanje algoritama . . . . . . . . . . . . . . . . . . . . . . . . . . 5
2 Linijski i ciklicni algoritmi 6
2.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.2 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
2.3 Zadaci za samostalni rad . . . . . . . . . . . . . . . . . . . . . . . . . 12
3 Ciklicni algoritmi i algoritmi sa uslovom tacnosti 14
3.1 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.2 Zadaci za samostalni rad . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
4 Analiza kompleksnosti algoritama na primjerima 26
4.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.2 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
4.3 Analiza kompleksnosti nekih tipova algoritama . . . . . . . . . . . . . . . 28
4.3.1 Algoritmi konstantnog vremena . . . . . . . . . . . . . . . . . . . 28
4.3.2 Algoritmi u linearnom vremenu . . . . . . . . . . . . . . . . . . . 29
4.3.3 Algoritmi sa kvadratnim vremenom . . . . . . . . . . . . . . . . . 29
4.3.4 Algoritmi sa logaritamskim vremenom . . . . . . . . . . . . . . . 30
4.3.5 Algoritmi brzine
_
: . . . . . . . . . . . . . . . . . . . . . . . . . 30
4.3.6 Algoritmi sa eksponencijalnim vremenom . . . . . . . . . . . . . . 30
4.3.7 Kombinacije algoritama . . . . . . . . . . . . . . . . . . . . . . . 31
5 Euklidov algoritam 33
5.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
5.2 Kako radi Euklidov algoritam ? . . . . . . . . . . . . . . . . . . . . . . . 33
5.3 Zadaci za samostalni rad . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
6 Asimptotska procjena slozenosti algoritma 37
6.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.1.1 -notacija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.1.2 O-notacija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
6.1.3 -notacija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38
6.1.4 Primjeri racunanja slozenosti . . . . . . . . . . . . . . . . . . . . 39
7 Analiza kompleksnosti - nastavak 41
7.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
7.2 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42
7.3 Zadaci za samostalni rad . . . . . . . . . . . . . . . . . . . . . . . . . . . 44
8 Rekurzije 46
8.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46
8.2 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48
8.3 Zadaci za samostalni rad . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
1
9 Tjuringova maina 56
9.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
9.2 Alan Tjuring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
9.3 Alfabet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
9.4 Neformalni opis Tjuringove maine . . . . . . . . . . . . . . . . . . . . . 57
9.5 Formalni opis Tjuringove maine . . . . . . . . . . . . . . . . . . . . . . 59
9.6 Modeli izracunljivost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
9.6.1 Nedetrministicka Tjuringova maina . . . . . . . . . . . . . . . . 61
9.6.2 Neogranicena registarska maina . . . . . . . . . . . . . . . . . . . 65
9.6.3 While i for petlje (dijagrami toka) . . . . . . . . . . . . . . . . . . 66
9.6.4 Postova maina . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
9.7 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
10 Sortiranja 81
10.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
10.2 Sortiranje nizova - osnovne metode . . . . . . . . . . . . . . . . . . . . . 81
10.2.1 Sortiranje putem umetanja (Insertion sort) . . . . . . . . . . . . . 82
10.2.2 Shell sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
10.2.3 Sortiranje putem direktne podjele (Selection sort) . . . . . . . . . 89
10.2.4 Sortiranje putem zamjene (Bubble sort) . . . . . . . . . . . . . . 92
10.3 Poboljane metode (slozenost :log :) . . . . . . . . . . . . . . . . . . . . 97
10.3.1 Merge sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 97
10.3.2 Quick sort . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
11 Slucajni brojevi 105
11.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105
11.2 Uniformna raspodjela . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
11.2.1 Linearni kongruenti generator . . . . . . . . . . . . . . . . . . . . 108
11.2.2 Algoritam Marsaglia . . . . . . . . . . . . . . . . . . . . . . . . . 109
11.2.3 Lagged-Fibonacci . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
11.2.4 Mersenov tvister . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
11.3 Normalna distribucija . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112
11.4 Testiranje slucajnosti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
12 Grafovski algoritmi 117
12.1 Uvod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
12.2 Algoritmi pretrazivanja . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
12.3 Algoritmi najkraceg puta . . . . . . . . . . . . . . . . . . . . . . . . . . . 119
12.3.1 Dijkstra algoritam . . . . . . . . . . . . . . . . . . . . . . . . . . 120
12.4 Pohlepni algoritmi na grafovima . . . . . . . . . . . . . . . . . . . . . . . 122
12.4.1 Kruskalov algoritam . . . . . . . . . . . . . . . . . . . . . . . . . 123
12.4.2 Primov algoritam . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
12.5 Zadaci . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
12.6 Zadaci za samostalni rad . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
1
1 Opti pojmovi o algoritmima
1.1 Uvod
Termin "algoritam" je nastao po latinskom prevodu imena matematicara iz devetog vi-
jeka, Abu Jafar Muhammad Ibn Musu Al-Khowarizmi koji se bavio trigonometrijom,
astronomijom, zemljopisom, kartograjom, a smatra se ocem algebre jer je denirao
osnovna pravila rjeavanja linearnih i kvadratnih jednadzbi. Njegovi radovi su osnova
razvoja mnogih matematickih i prirodnih disciplina, meu njima i racunarstva.
Prvi zapis algoritma prilagoen racunaru pripada Adi Byron iz 1842, pa se zbog ovoga
smatra prvom programerkom, a racunao je Bernoullijeve brojeve. Racunar za koji je
napisan je bio analiticki stroj koji je zamislio, ali nikad u potpunosti proveo u djelo, Englez
Charles Babbage. Analiticki stroj je trebao biti prvi programabilni racunar, sastavljen
u potpunosti od mehanickih dijelova. Mehanicki dijelovi i zicka glomaznost su glavni
razlozi zato nikad nije zavren
1
.
Algoritam se denie na nekoliko nacina :
Algoritam je skup pravila kojima se provodi kalkulacija bilo rucno bilo putem maine
Algoritam je procedura od konacnog broja koraka kako bi se dobio trazeni rezultat
Algoritam je niz racunskih koraka kojima se ulaz transformie kako bi se dobio izlaz
Algoritam je niz operacija koje se izvode nad podacima koji trebaju biti organizo-
vani u strukturama podataka
Algoritam je apstrakcija programa koji se treba izvesti na zickoj maini (model
izracunavanja)
U tekstu [11] algoritam se denie kao "jasno speciciran matematicki process izracuna-
vanja; skup pravila koji ako se slijede daju zeljeni rezultat". U matematici, racunarstvu,
lingvistici i srodnim disciplinama, algoritam je konacan niz dobro denisanih naredbi
za ostvarenje zadatka, koji ce za dato pocetno stanje zavriti u denisanom konacnom
stanju.
Iz datih denicija se moze zakljuciti da je algoritam skup koraka odnosno postupak kojim
se odreeni problem rjeava u konacnom broju koraka. Istorijski gledano, svi problemi su
rjeavani nekim vidom algoritma ali je proteklo puno vremena da se napravi odgovarajuca
formalizacija.
Koncept algoritma je potekao kao sredstvo zapisivanja postupaka za rjeavanje matem-
atickih problema, poput pronalazenja zajednickog djelitelja dva broja ili mnozenja dva
broja. Koncept je formaliziran 1936. u vidu Turingovog stroja Alana Turinga i lambda
racuna Alonza Churcha, koji su jedan za drugim postavili temelje racunarstva.
Najpoznatiji algoritam u istoriji datira mnogo prije vremena starih grka; to je Euklidov
algoritam za racunanje najveceg zajednickog djelioca dva cijela broja.
Algoritmi imaju slijedeca svojstva:
1
Prije nekoliko godina su britanski inzinjeri uspjeli sastaviti potpuno funkcionalan ureaj koji je
zamislio Charles Babbage.
2
diskretnost : u odvojenim koracima se izvode diskretne operacije algoritma koje
vode ka konacnom cilju;
konacnost : oznacava sposobnost algoritma da nakon konacnog broja koraka daje
izlazne podatke odnosno rezultate;
determiniranost : za iste ulazne podatke algoritam uvijek daje iste rezultate
masovnost : algoritam je primjenjiv na veci broj ulaznih vrijednosti.
Osnovne komponente algoritma su :
Denicija problema
Ulazne velicine
Radne velicine
Postupak rjeavanja
Izlaz
Denicija problema treba biti jasna, sadrzajna i sa dovoljno elemenata kako bi se
problem mogao rijeiti. Problem se denie tekstualno i/ili izrazom. Denicija problema
treba biti egzaktna i nedvosmislena.
Ulazne velicine deniu skup podataka koji su predmet obrade (input). Ove velicine
mogu biti numericke velicine, fajlovi, tekstovi, graka itd.
Radne velicine su varijable koje se koriste u postupku rjeavanja problema. Mada
se koncept razlikuje po jezicima, svima im je zajednicko da zahtijevaju deklaraciju i
inicijalizaciju radnih velicina.
Deklaracija denie tip varijable a samim tim i njene moguce vrijednosti.
Incijalizacija je postupak davanja pocetnih vrijednosti varijablama. Ovo je posebno
vazno u ciklicnim algoritmima. U nekim slucajevima inicijalizacija se vri prvom dodjelom
vrijednosti.
Postupak rjeavanja denie svaki pojedini korak koji je potreban za rjeenje problema,
ukljucujuci deklaracije, inicijalizacije i svaku operaciju koja se obavlja.
Izlaz (output) denie rezultat rada koji moze biti numericka velicina, skup vrijednosti,
datoteka itd.
Svaki algoritam mora imati zavretak. Pravljenje tzv. vjecnih petlji je klasicna pro-
gramerska greka. Potrebno je razlikovati procedure od funkcija. U principu, svaka
procedura ima rezultat ali on ne mora biti vidljiv u svim slucajevima. Primjer je proce-
dura sortiranja koja se moze izvravati kao dio nekog veceg algoritma odnoso uslova za
naredne korake. Funkcija mora imati vrijednost i moze biti clan u operacijama.
Dizajn algoritma ukljucuje obaveznu kontrolu njegove ispravnosti kako bi se ustanovilo
da algoritam daje zeljeni rezultat.
3
1.2 Klasikacija algoritama
Algoritme je moguce klasicirati po raznim kriterijima:
Klasikacija s obzirom na tok
Linijski algoritmi se izvravaju korak po korak, bez vracanja na neki od prethod-
nih koraka niti se neki od koraka ili grupa koraka ponavlja u bilo kom smislu. Ovi
algoritmi mogu sadrzavati i grananja, mjesta na kojima se postupak nastavlja nakon
ispitivanja odreenog uslova.
Ciklicni algoritmi se realizuju na nacin da se ponavlja odreeni korak ili grupa
koraka. Ponavljanje se moze realizovati na dva nacina :
- Putem brojaca, kojim se zadaje koliko puta se odabrani korak ili grupa koraka
ponavlja. Bitno je napomenuti da se u ovom tipu ciklusa zadati broj koraka ne
moze mijenjati u toku samog izvrenja
- Putem uslova za koji se ne zna unaprijed koliko puta ce se izvriti. Ovo je slucaj
npr. kada se zeli postici odreena tacnost u racunanju; najcece nije poznato koliko
koraka treba napraviti da bi se tacnost postigla pa se trazi drugi nacin.
Najveca opasnost ciklicnih algoritama je formiranje tzv. vjecitih petlji jer uslov zavretka
nije dobro denisan.
Klasikacija prema implementaciji
Rekurzivni ili iterativni: Rekurzivni algoritam je algoritam koji poziva samog
sebe sve dok se ne postigne odreen uslov. Rekurzivni algoritmi su vrlo cesto
usko vezani uz implementaciju pojedine matematicke funkcije na primjer racunanje
Fibbonacijevih brojeva. Iterativni algoritmi su algoritmi koji ne pozivaju samog
sebe vec se oslanjaju na konstrukcije poput petlji i dodatne strukture podataka
da bi se rijeio problem. Vazno je napomenuti da je svaki rekurzivni algoritam
moguce pretvoriti u iterativni, i da je svaki iterativni algoritam moguce pretvoriti
u rekurzivni, iako ponekad to pretvaranje moze biti vrlo kompleksno.
Serijski ili paralelni: Vecina dananjih racunara sadrzi samo jedan procesor te
stoga obavlja naredbe jednu po jednu, to jest serijski. Algoritmi koji su dizajnirani
sa namjerom da se izvravaju u takvom okruzenju shodno tome se nazivaju serijski
algoritmi. Suprotno njima su paralelni algoritmi koji sa sve vecim brojem vieproce-
sorskih racunara dobivaju sve vecu vaznost. Paralelni algoritmi koriste mogucnost
vieprocesorskog sistema na nacin da problem podijele na vie malih potproblema
koje svaki procesor rjeava zasebno te se zatim rezultati spajaju. Paralelni algoritmi
uz resurse potrebne za obradu podataka takoer imaju i malu potronju resursa na
komunkaciju izmeu vie procesora. Algoritmi za sortiranje su jedan od primjera
algoritama koje je moguce znatno poboljati upotrebom paralelnih procesora, dok
je neke probleme sasvim nemoguce rijeiti paralelnim algoritmom.
Deterministicki ili stohasticki: Deterministicki algoritam je algoritam koji ce
pri svakom izvravanju u bilo kojim uslovima od istog unosa doci do istog izlaza na
nacin da svaki put slijedi identican niz naredbi. Stohashicki algoritmi je algoritam
koji barem u jednom dijelu izvravanja donese neku odluku slucajnim odabirom.
4
Tacan ili priblizan: Iako algoritmi u principu daju tacan rezultat, ponekad al-
goritam trazi priblizno rjeenje koje je dovoljno blizu tocnom, ili je tacno rjeenje
nemoguce naci.
Klasikacija prema strategiji rjeavanja
Brute force algoritmi - racunar "cistom silom" isprobava sve mogucnosti i trazi
odgovarajuce rjeenje. Ovo su najneekasnijji algoritmi jer ukazuju na nesistem-
aticnost i neanalitcnost u pristupu.
Podijeli i vladaj algoritmi (Divide and conquer). Problem se dijeli na vie istih,
manjih problema. Podjela tece tako dugo dok se ne doe do malog problema kojeg
je jednostavno rijeiti (obicno rekurzijom).
Dinamicki algoritmi - Metodama dinamickog programiranja rjeavaju se viefazni
procesi, tj. procesi u kojima se donosi niz meusobno zavisnih odluka. Dinamicko
programiranje poznato je i pod nazivom metoda donoenja viefaznih odluka.
Pohlepni algoritmi (greedy) - Pohlepni algoritam koristi metaheuristiku za
rjeavanje problema, takvu da u svakom koraku bira lokalno najbolje rjeenje, u
nadi da ce tako iznaci globalni optimum. Ovi algoritmi cesto ne daju najbolje
rjeenje vec brzu aproksimaciju najboljeg rjeenja.
Algoritmi za sortiranje i pobrojavanje (search and enumeration) - Algoritmi
sortiranja sluze za brzo sortiranje podataka, npr. niza brojeva. Mnogi se problemi
mogu rjeavati teorijom grafova.
1.3 Predstavljanje algoritama
Algoritmi se predstavljaju gracki i tekstualno.
Gracko predstavljanje se realizuje putem standardnih simbola koji predstavljaju po-
jedine korake i koji se povezuju linijama kao prikaz toka operacija. Pritom se dijagram
pravi tako da ide odozgo prema dolje s lijeva na desno.
Tekstualno predstavljanje moze biti putem pseudokoda ili putem odabranog program-
skog jezika. Pseudokod nije vezan ni za jedan specican programski jezik. U radu cemo
koristiti sljedece formulacije pseudokoda :
Ako je <uslov tada <operacija : Ispituje se <uslov i ako je zadovoljen realizuje
se <operacija; u suprotnom se realizuje alternativni blok
Za <varijablaod <g1do <g2korak <g3: Pocetak ciklusa u kojem<varijabla
mijenja vrijednosti od <g1 do <g2 sa korakom <g3. Ako je g1<g2 tada korak
mora biti pozitivan, u suprotnom je negativan
SveDokJe(<uslov) : pocetak ciklusa u kojem, u pravilu, nije poznat broj koraka.
Ciklus se izvrava sve dok vrijedi <uslov
c /: Pridruzivanje koje se cita "na lokaciju varijable c (odredite) upisati vrijed-
nost varijable /".
Blokovi odnosno logicki povezani skupovi naredbi se ogranicavaju parom zagrada ....
5
2 Linijski i ciklicni algoritmi
2.1 Uvod
Linijski algoritmi su oni koji se izvravaju sukcesivno odnosno oni u kojima se svaki korak
izvrava samo jednom. Algoritam moze sadrzavati grananja ali se ne vri povratak na
bilo od kojih prethodnih koraka.
Ciklicni algoritmi imaju dio koji se ponavlja. Broj ponavljanja se prati nekom varijablom
koja je u funkciji brojaca.
2.2 Zadaci
Zadatak. Napraviti algoritam rjeavanja kvadratne jednacine.
Rjeenje. Opta kvadratna jednacina je data izrazom cr
2
+ /r + c = 0. Ulazne velicine
za algoritam su c. /. c. Najprije se ispituje da li je c ,= 0 : provjera da li zadati para-
metri uopte mogu denisati kvadratnu jednacinu. Na narednom dijagramu je algoritam
rjeavanja kvadratne jednacine prikazan gracki.
Postupak rjeavanja kvadratne jednacine
Na dijagramu je vidljiv tok odozgo nanize, uz dva grananja odnosno mjesta na kojima
se ispituje uslov i donosi odgovarajuca odluka o nastavku. Ovaj isti algoritam se moze
predstaviti pseudokodom koji je u nastavku.
6
Algoritam : Kvadratna jednacina
Ulaz : a,b,c
// Najprije se ispituje da li je a = 0 ili ne
Ako je a=0 tada Kraj
// Izra cunavanje diskriminante
D b
2
4ac
Ako je 1 0 tada
{
// Rjeenja su realna i razli cita
x
1
-
/
2c
-
_
1
2c
x
2
-
/
2c
+
_
1
2c
}
Ina ce
{
//Da li je diskriminanta negativna
Ako je D<0 tada
{
//Rjeenja su kompleksna
Re -
/
2c
Im -
_
1
2c
x
1
(Re. Im)
x
2
(Re. Im)
}
Ina ce
{
//Rjeenja su jednaka
x
1
=x
2
-
/
2c
}
}
Izlaz : Rjeenja kvadratne jedna cine
7
Pseudokod je napisan na nacin da pojedine naredbe odnosno grupe naredbi odgovaraju
sadrzaju simbola na grakonu. Ovdje je simbolom oznaceno da se vrijednost sa desne
strane znaka smjeta na lokaciju na kojoj se nalazi velicina sa lijeve strane znaka.
Zadatak. Napraviti algoritam za racunanje sume :
o =
n

i=1
i
2
i + 1
Rjeenje. Jedina ulazna velicina u ovom slucaju je :. Sumiranje se vri u velicinu o
to podrazumijeva potrebu njene inicijalizacije. Kad je u pitanju sumiranje najprirodniji
nacin inicijalizacije je o = 0. Jedna od varijanti algoritma je u nastavku.
Algoritam sumiranja
Na dijagramu je vidljivo da se operacija
o o +
/
2
/ + 1
ponavlja onoliko puta koliko / ima razlicitih vrijednosti, u ovom slucaju :, koje se do-
bijaju tako da se / u svakom koraku poveca za 1. Na taj nacin / ima funkciju brojaca.
Pseudokod za ovaj algoritam je u nastavku.
Ovakav algoritam se naziva ciklicni zbog cinjenice da se jedan korak ponavlja. Pri tome
to ponavljanje moze biti unaprijed utvreno (kao u ovom slucaju) ili se operacija obavlja
dok se ne postigne odreeni uslov, npr. tacnost racunanja.
Pitanje : Koliko puta se obavi operacija sumiranja o o +
/
2
/ + 1
?
Isti algoritam je mogao biti napravljen na nacin da se u svakom ciklusu ispituje uslov, u
ovom slucaju da li je / dostigao trazenu vrijednost.
8
Sumiranje - varijanta 1
//Ra cunanje kona cne sume
Ulaz : :
//Inicijalizacija sume
o 0
Za / = 1 do :
{
o o +
/
2
/ + 1
}
Izlaz : o
Sumiranje - varijanta 2
Ulaz : :
//Inicijalizacija sume
o 0
1 /
a:o o +
/
2
/ + 1
/ / + 1
Ako je / _ : Idi na korak a:
Izlaz : o
U ovom algoritmu je najinteresantniji korak u kojem se ispituje da li je / _ :. Ovo je
potencijalno najveci (i najceci) izvor greke. Druga karakteristika je (bezuslovni) skok
na labelu koja je oznacena sa a:.

Citaocu se preputa da napravi odgovarajuci pseudokod.
Zadatak. Izracunati vrijednost izraza
o = 2r
4
3r
3
+ 4r
2
5r + 6
ne koristeci vie od 4 operacije sabiranja, mnozenja i oduzimanja.
Rjeenje. Da bi broj operacija mogao biti maksimalno smanjen dati izraz se napie u
obliku:
o = (((2r 3) r + 4) r 5) r + 6
Racunanje pocinje iz prve zagrade. Mnozenja koja se koriste se mogu simbolicki prikazati
na sljedeci nacin:
c 2 r 3
/ c r + 4
c / r 5
o c r + 6
Ovakav nacin koritenja varijabli je neracionalan ako se ima u vidu da se svaka od njih
koristi samo jednom. Ako se trazi suma onda se ta ista varijabla moze iskoristiti za svaki
korak na nacin da se prethodni sadrzaj brie i upie nova vrijednost. Simbolicki, to se
pie na sljedeci nacin:
o 2 r 3
o o r + 4
o o r 5
9
o o r + 6
Ovdje je vidljivo da se prvi red racuna na jedan a ostala tri reda na drugi nacin. Ovo se
moze promijeniti na nacin da se u svim koracima koristi isti obrazac sumiranja i mnozenja:
o 0
o o r + 2
o o r 3
o o r + 4
o o r 5
o o r + 6
U ovom nacinu rada se u svakom izrazu koecijenti polinoma pojavljuju kao sabirci.
Uopteno se ovo moze zapisati na sljedeci nacin:
o 0.
o o r +c
k
. / = :. 1. 1
Ovdje / = :. 1. 1 ima znacenje : / se mijenja od : do 1 sa korakom 1. To znaci
da se uzimaju koecijenti polinoma opadajucim redom indeksa pocev od koecijenta za
najveci stepen. Najvaznije u datoj relaciji je da se koriste samo dvije operacije; prva
od njih je dodjela vrijednosti a druga sadrzi jedno mnozenje i jedno sabiranje. Na ovaj
nacin se moze opisati racunanje vrijednosti polinoma proizvoljnog stepena. Na narednom
dijagramu je dat opisani algoritam.
Racunanje polinoma
U nastavku je pseudokod za ovaj algoritam.
Pitanje : Koliko puta se izvri korak u kojem se racuna o o r +c
k
?
Zadatak. Napraviti algoritam za racunanje prvog izvoda polinoma stepena :.
Rjeenje. Neka je polinom dat u optem obliku
1 (r) = c
n
r
n
+c
n1
r
n1
+... +c
1
r +c
0
Prvi izvod ovog polinoma je
10
Racunanje polinoma
//Ra cunanje vrijednosti polinoma
Ulaz : c
k
. / = 0. :
Ulaz : r
//Inicijalizacija
o 0
Za / = : do 0 korak 1
{
o o r +c
k
}
Izlaz : o
1
0
(r) = :c
n
r
n1
+ (: 1) c
n1
r
n2
+... + 2c
2
r +c
1
Najlaki nacin racunanja vrijednosti ovog polinoma za datu vrijednost r je sljedeci:
1
0
(r) = (... (:c
n
r + (: 1) c
n1
) r +... + 2c
2
) r +c
1
Slicno kao u prethodnom primjeru, kalkulacija se provodi koritenjem dvije osnovne op-
eracije
o 0
o o r +/ c
k
. / = :. 0. 1
Opisani algoritam je dat na sljedecem dijagramu.
Racunanje prvog izvoda polinoma
Jedina razlika u odnosu na prethodni algoritam je vidljiva u koraku o o r +/ c
k
.
Pitanje 1 : U slucaju da se trazi izvod bilo kojeg reda datog polinoma ta bi bio prvi
korak u dizajniranju ovog algoritma ?
Pitanje 2 : Da li je i na koji nacin povecan broj operacija koje se obavljaju prilikom
racunanja prvog izvoda ?
11
2.3 Zadaci za samostalni rad
Zadatak. Dati su realni brojevi r. . Ne koristeci druge operacije osim sabiranja, oduz-
imanja i mnozenja izracunati vrijednost izraza
3r
2

2
2r
2
7r
2
4
2
+ 15r + 2r
2
3r + 10 + 6
Ne koristiti vie od osam mnozenja, oduzimanja i sabiranja.
Zadatak. Dat je realan broj c. Koristeci se samo mnozenjem izracunati
c
4
, sa dvije operacije
c
6
, sa tri operacije
c
7
, sa cetiri operacije
c
8
, sa tri operacije
c
9
, sa cetiri operacije
c
10
, sa cetiri operacije
c
13
, sa pet operacija
c
13
, sa pet operacija
c
21
, sa est operacija
c
28
, sa pet operacija
c
64
, sa est operacija
Zadatak. Dat je prirodan broj :. Izracunati:

_
1 +
1
1
2
__
1 +
1
2
2
_
...
_
1 +
1
:
2
_
Exercise 1
1
sin 1
+
1
sin 1 + sin 2
+
1
sin 1 + sin 2 + sin 3
+...+
1
sin 1 + sin 2 +... + sin :

_
2 +
_
2 +... +
_
2
. .
n korijena

cos 1
sin 1
+
cos 1 + cos 2
sin 1 + sin 2
+
cos 1 + cos 2 + cos 3
sin 1 + sin 2 + sin 3
+... +
cos 1 + cos 2 +... + cos :
sin 1 + sin 2 +... + sin :

_
3 +
_
6 +
_
9 +... +
_
3 (: 1) +
_
3:
Zadatak. Dat je realni broj r. Izracunati
12
(r 2) (r 4) ... (r 64)
(r 1) (r 3) ... (r 63)
Zadatak. Dat je realan broj c i prirodni broj :. Izracunati:
c
n
Exercise 2 c (c + 1) (c + 2) ... (c +: 1)

1
c
+
1
c (c + 1)
+... +
1
c (c + 1) ... (c +:)

1
c
+
1
c
2
+
1
c
4
+... +
1
c
2
n
c (c :) (c 2:) ... (c :
2
)
Zadatak. Za dati prirodni broj : izracunati

k=1
1
/

k=1
1
/
5

k=1
1
(1 + 2/)
2

k=1
(1)
k
(2/ + 1) /

k=1
(1)
k+1
(/ + 1) /

k=1
(1)
k
(/ + 1)
/!

k=1
/!
1
2
+
1
3
+... +
1
/ + 1
13
3 Ciklicni algoritmi i algoritmi sa uslovom tacnosti
Algoritmi sa uslovom tacnosti su oni u kojima je kriterij zaustavljanja odreeni stepen
racunske tacnosti koja se postize na dva nacina :
Poreenjem dvije uzastopne parcijalne sume
Poreenjem sa nekom vrijednosti koja je referenetna (npr. najblizi cijeli broj)
3.1 Zadaci
Zadatak. Napraviti algoritam za racunanje sljedecih vrijednosti :
min r.
max r.
min r. . max r.
Rjeenje. Ulazne velicine za ovaj algoritam su r. . Ako se trazi minimum rezultat ne
bi trebao biti samo odgovor koji od dva broja je manji vec broj koji se kao rezultat
ispitivanja moze iskoristiti za neku drugu funkciju, operaciju ili slicno. Drugim rijecima,
trazi se da rezultat bude u obliku
`i: min r.
Analogno treba vrijediti i za maksimalnu vrijednost.
Algoritam za nalazenje minimalnog od dva data broja je na sljedecem dijagramu.
Nalazenje minimalnog od dva data broja
U nastavku je pseudokod za ovaj algoritam.
Analogni algoritam za nalazenje veceg od dva data broja je na sljedecem dijagramu.
14
Algoritam : Nalazenje minimalnog od dva broja
Ulaz : r.
Min x
Ako je < `i: tada
{
`i:
}
Izlaz : `i:
Nalazenje veceg od dva data broja
U nastavku je pseudokod za ovaj algoritam.
Algoritam : Nalazenje maksimalnog od dva broja
Ulaz : r.
`cr r
Ako je < `cr tada
{
`cr
}
Izlaz : `cr
Algoritamza istovremeno nalazenje najmanjeg i najveceg od dva data broja je na sljedecem
dijagramu.
15
Algoritam za istovremeno nalazenje i minimalnog i maksimalnog od dva data broja
Pseudokod za ovaj algoritam je u nastavku.
Algoritam : Nalazenje i minimalnog i maksimalnog broja
Ulaz : r.
`i: r
`cr
Ako je < `i: tada
{
`i:
}
Ako je r `cr tada
{
`cr r
}
Izlaz : `i:. `cr
Ono to je karakteristika ovog algoritma je da se rezultat dobija jedino poreenjem datih
velicina.
Zadatak. Neka je dat niz brojeva r
k
. / = 1. :. Napraviti algoritam koji ce racunati :
najmanji od datih brojeva
najveci od datih brojeva
i najmanji i najveci od datih brojeva
Rjeenje. Zadatakce biti rijeen za slucaj nalazenja minimalnog od datih brojeva. Kao i u
prethodnom zadatku, rezultat, npr. velicina `i:, bi trebao biti broj koji se moze koristiti
kao argument za neku drugu funkciju, operaciju i slicno. Prvi problem je inicijalizacija.
Logicno rjeenje je da se kao inicijalna vrijednost uzme prvi clan datog niza koji se poredi
sa preostalim clanovima. Opisani algoritam je na sljedecem dijagramu.
16
Nalazenje minimalnog broja u datom nisu
Pseudo kod za ovaj algoritam je dat u nastavku.
Algoritam : Nalazenje minimalnog broja u nizu
Ulaz : r.
`i: r
1
Za / = 1 do :
{
Ako je r
k
< `i: tada
{
`i: r
k
}
}
Izlaz : `i:

Citaocu se preputa da napravi odgovarajuci algoritam za nalazenje najveceg broja datog


niza.
Za nalazenje istovremeno i najveceg i najmanjeg clana datog niza brojeva potrebno je
raditi kao i u prethodnom zadatku sa manjom izmjenom u segmenu ispitivanja.
17
Istovremeno nalazenje minimalnog i maksimalnog elementa iz niza brojeva
Pseudokod za ovaj algoritam je dat u nastavku.
Algoritam : Istovremeno nalazenje minimalnog i maksimalnog broja u nizu
Ulaz : r.
`i: r
1
`cr r
1
Za / = 1 do :
{
Ako je r
k
< `i: tada
{
`i: r
k
}
Ina ce
{
Ako je r
k
`cr tada
{
`cr r
k
}
}
}
Izlaz : `i:. `cr
Zadatak. Napraviti algoritam za racunanje sume
o =
1

i=1
1
i
3
Rjeenje. U ovom zadatku je osnovni problem kriterij zaustavljanja. Kad su u pitanju al-
goritmi sumiranja redova, osnovni kriterij zaustavljanja je razlika izmeu dvije uzastopne
18
parcijalne sume. Ako je ta razlika manja od nekog unaprijed zadatog broja postupak
sumiranja se zaustavlja jer dodavanje novih clanova ne povecava bitno ili nikako tacnost
racunanja :
[o
k+1
o
k
[ <
Ovo znaci da je u dizajnu algoritma na svakom koraku potrebno imati dvije parcijalne
sume koje se porede. Ulazni parametar za ovaj algoritam, koji je dat na narednom
dijagramu, je broj , odabrani nivo tacnosti racunanja.
Sumiranje redova - varijanta 1
Pseudo kod za ovaj algoritam je dat u nastavku.
Algoritam : Sumiranje redova - varijanta 1
Ulaz :
/ 1
o
1
/
a: o
2
o
1
+
1
/
3
Ako je [o
2
o
1
[ < tada
{
Zavriti
}
Ina ce
{
o
1
o
2
/ / + 1
Idi na a:
}
Izlaz : Suma
Alternativni izgled ovog algoritma je u nastavku.
19
Algoritam : Sumiranje redova - varijanta 1a
Ulaz :
/ 1
o
1
/
a: o
2
o
1
+
1
/
3
Ako je [o
2
o
1
[ < tada Izlaz:
// Ako ne vrijedi gornji uslov nastavljaju se naredbe nakon uslova "Ako
..."
o
1
o
2
/ / + 1
Idi na a:
Izlaz : Suma
Ovakav dizajn je pogodan u slucajevima kada programski jezik omogucava realizaciju
naredbe bezuslovnog skoka "Idi na a:".

Ceci je dizajn dat na narednom dijagramu.
Sumiranje redova - varijanta 2
Pseudo kod za ovaj algoritam je dat u nastavku.
U oba slucaja, broj koraka u kojem se racuna suma je odreen velicinom .
Zadatak. Dat je realni broj r. Izracunati cijeli dio broja (najveci cijeli broj koji nije
veci od r), broj zaokruzen do najblizeg cijelog broja, cjelobrojni dio broja bez decimalnog
dijela. U matematici se ovaj broj obiljezava sa r| (oor). Pri tome se treba koristiti
standardnim operacijama (mnozenje, sabiranje, ...) odnosno smatra se da nisu raspolozive
interne funkcije kao to je [r[ i slicno.
Rjeenje. Da bi se naao cjelobrojni dio najprije se mora naci broj cijelih mjesta. Nakon
toga se trazi cjelobrojni dio unatrag po pozicijama.
Prvi dio zadatka se rjeava tako da se broj dijeli sa 10 (odnosno osnovom brojnog sis-
tema) dok se ne doe do broja koji je manji od 1. Ovo je ekvivalentno pomjeranju
20
Algoritam : Sumiranje reda - varijanta 2
Ulaz :
/ 1
o
1
0
o
2
/
SveDokJe([o
2
o
1
[ )
{
/ / + 1
o
1
o
2
o
2
o
1
+
1
/
3
}
Izlaz : o
2
decimalnog zareza ulijevo za po jednu poziciju prilikom svakog dijeljenja. Algoritam je
dat na sljedecem dijagramu. Funkciju brojaca cifara ima varijabla /.
Racunanje broja cifara realnog broja r
Pseudo kod je dat u nastavku
Algoritam : Nalazenje broja cifara realnog broja
Ulaz :
/ 0
c r
SveDokJe(c 1)
{
/ / + 1
c c,10
}
Izlaz : /
Jedno od vaznijih pitanja na ovom mjestu je : koliko puta se obavlja dijeljenje sa 10 da
bi se dobio broj cifara ? Ako se podsjetimo da je karakteristika logaritma realnog broja
21
jednaka broju cifara cjelobrojnog dijela umanjen za 1 onda je odgovor jasan : da bi se
dobio broj cifara realnog broja potrebno je log r| + 1 dijeljenja.
Drugi dio problema, nalazenje cjelobrojnog dijela, je neto kompleksniji jer je mnozenje
i uporeivanje jedini mehanizam. Da bi se problem rijeio potrebno je pripremiti radnu
varijablu, nazovimo je c,, i / puta uraditi sljedece :
- Vrijednost c pomnoziti sa 10
- Vrijednost c, postaviti na (c, + 1) 10
- Umanjivati c, za po 1 i na svakom koraku ispitivati da li je c, _ c; ako taj uslov vrijedi
nali smo cijeli broj koji nije veci od c; ovakvih oduzimanja na svakom koraku moze biti
najvie 10
Opisani algoritam je na narednom dijagramu
Nalazenje cjelobrojnog dijela realnog broja r
Pseudo kod ovog algoritma je u nastavku
NAPOMENA. Realni broj r se u racunaru zapisuje u formatu pokretnog zareza odnosno
u formatu koji odgovara zapisu r = r
M
10
x
E
gdje su :
22
Algoritam : Nalazenje cjelobrojnog dijela decimalnog broja
Ulaz :
/ 0
c r
SveDokJe(c 1)
{
/ / + 1
c c,10
}
c, 0
Za i = 1 do /
{
c c 10
c, (c, + 1) 10
1 :
SveDokJe(: _ 10)
{
c, c, 1
Ako je c, _ c tada IdiNa b:
}
b:
}
Izlaz : /
r
M
: Mantisa, broj r
M
[0; 1)
r
E
: Eksponent, cijeli (pozitivni ili negativni) broj
Prema najnovijim standardima, koji su izdati od strane IEEE, termin "mantisa" u gorn-
jem zapisu je zamijenjen terminom "signikand" kako bi se izbjegle terminoloke nejas-
noce koje se mogu pojaviti zbog znacenja kojeg termin "mantisa" ima za logaritme. U
jednom broju tekstova se uzima da signikand ima vrijednosti u intervalu [1. 10) ali je
znacenje potpuno identicno
3.2 Zadaci za samostalni rad
Zadatak. Dati su pozitivni realni brojevi r. c. .U nizu
1
.
2
. ... koji je formiran po
pravilu

0
= c.
k
=
1
2
_

i1
+
r

i1
_
naci prvi : za koji vrijedi nejednakost

2
i

2
i1

< .
Zadatak. Neka je
r
0
= 1; r
k
=
2 r
3
k1
5
23
Naci prvi clan r
n
za koji vrijedi [r
n
r
n1
[ < 10
5
.
Zadatak. Neka je

0
= 0;
k
=

k1
+ 1

k1
+ 2
Za dati realni broj 0 naci prvi clan
n
za kojeg vrijedi
n

n1
< .
Zadatak. Dat je realni broj c 0. Formiran je niz
r
0
=
_

_
min 2c; 0.95 c _ 1
c
5
1 < c < 25
c
25
inace
r
n
=
4
5
r
n1
+
c
5r
4
n1
. : = 1. 2. ...
Naci prvi clan r
n
za koji vrijedi
5
4
c [r
n+1
r
n
[ < 10
6
. Za pronaenu vrijednost clana
r
n
naci razliku c r
5
n
.
Zadatak. Za dati realni broj r i prirodni broj : izracunati
r
n
2
,2
n
Exercise 3 r
n
3
,3
n
Zadatak. Za date realne brojeve c. / (/ c) i prirodni broj : izracunati (,
1
+,
2
+... +,
n
)
/ gdje je
/ =
/ c
:
,
i
=
c +
_
i
1
2
_
/
1 +
_
c +
_
i
1
2
_
/
_
2
. i = 1. 2. .... :
Zadatak. Izracunati beskonacne sume sa datim nivoom tacnosti 0. Smatrati da je
potrebna tacnost dostignuta ako se suma na nekom koraku razlikuje za manje od od
prethodne sume.

i=1
1
i
2

i=1
1
i (i + 1)

i=1
(1)
i
i!
24

i=1
(2)
i
i!

i=1
(1)
i+1
i (i + 1) (i + 2)

i=1
1
4
i
+ 5
i+2
Zadatak. Dati su prirodan broj : i realan broj c 0. Niz r
0
. r
1
. r
2
. ... je formiran po
pravilu
r
0
= c. r
k
=
/ 1
/
r
i1
+
c
r
k1
i1
Naci prvu vrijednost r
n
za koju je

r
k
n
c

< 10
4
(Niz r
i

i2N
konvergira ka
k
_
c).
25
4 Analiza kompleksnosti algoritama na primjerima
4.1 Uvod
U ovom dijelu ce biti naveden jedan broj primjera analize slozenosti algoritama na nacin
da se nae to je moguce tacniji broj koraka. Na taj se dobija podatak o vremenskoj
slozenosti programa odnosno pokazatelju o mogucem vremenu trajanja odreenog algo-
ritma.
4.2 Zadaci
Primjer. Sekvencijalno sumiranje
U nastavku je pseudo kod za jednostavan slucaj sekvencijalnog sumiranja.
# Sumiranje Opis
1 Sumiraj(a,n) Ulaz : niz [c] duzine :
2 on:c 0 Inicijalizacija
3 Za i = 1 do : { Pocetak petlje
4 on:c on:c +c [i] Sumiranje
5 }
6 }
Table 1: Sekvencijalno sumiranje
Korak na liniji 2 se izvrava jednom. Petlja sa pocetkom na liniji 3 se izvrava : puta;
na svakom koraku te petlje se izvravaju dvije operacije na liniji 4 to znaci da je okvirni
broj koraka dat sa 1 (:) = 2: + 1.
Primjer. Ugnjezdena petlja
U ovom primjeru je prezentirana analiza slucaja kada je jedna petlja unutar druge (ugn-
jezdena petlja).
# Sumiranje Opis
1 Sumiraj(a,n) Ulaz : niz [c] duzine :
2 Za i = 1 do : { Pocetak spoljne petlje
3 on:c 0 Inicijalizacija sume
4 Za , = 1 do i { Pocetak unutranje petlje
5 on:c on:c +c [i] Sumiranje
6 }
7 Ispisati : on:c Ispisivanje meu sume
8 }
Table 2: Sumiranje u ugnjezdenim petljama
Spoljanja petlja, koja pocinje na liniji 2, se izvrava : puta. U svakom koraku se izvrava
inicijalizacija na liniji 2, rokoja se racuna kao jedan korak.
Unutranja petlja pocinje na liniji 4. Ako je i = 1 ona se ponavlja : 1 puta; ako je
i = 2 ona se ponavlja : 2 puta itd. U svakom od tih koraka se izvrava linija 5 koja
sadrzi dvije operacije. Linija 7 se izvrava jednom u svakom od : koraka. Ovo znaci da
je broj operacija u ovom algoritmu
26
1 (:) = 1 + 4: +
n

i=1
2 (i 1) =
= 1 + 4: + 2
n

i=1
(i 1) = 1 + 4: + 2
:(: 1)
2
1 (:) = :
2
+ 3: + 1
Zakljucak je da ovaj algoritam ima kvadratnu brzinu : ako se obim niza poveca dva puta
broj koraka se poveca barem 4 puta.
Primjer. Sumiranje
U sljedecem primjeru je prezentirano sumiranje posljednjih pet clanova odabranog niza.
# Sumiranje Opis
1 Sumiraj(a, n) Ulaz : niz [c] duzine :
2 Za i = 5 do : { Pocetak spoljne petlje
3 on:c c [i 4] Iniciranje sume clanom c [i 4]
4 Za , = i 3 do i { Pocetak unutranje petlje
5 on:c on:c +c [,] Sumiranje
6 }
7 Ispisati on:c Ispisivanje on:c
8 }
Table 3: Sumiranje posljednjih 5 clanova
Spoljanja petlja, koja pocinje na liniji 2, se izvrava : 4 puta. U svakom koraku se
izvrava inicijalizacija vrijednosti on:c i to sa clanom koji je pet pozicija udaljen od
pozicije clana od kojeg pocinje sabiranje. Ako je i = 5 tada je on:c c [1] itd. Ova op-
eracija traje jedan korak. Petlja na liniji 4 se izvrava 4 puta, za c [i 3] . c [i 2] . c [i 1]
i c [i]. U svakom koraku te petlje se izvode dvije operacije na liniji 5. Ispisivanje, na liniji
7, traje jedan korak. To znaci da je okvirni broj operacija u ovom algoritmu
1 (:) = 1 + 10 (: 4) = 10: 39
Zakljucak je da ovaj algoritam ima linearnu brzinu.
Primjer. Binarno pretrazivanje
Ovo je jedan od veoma cestih metoda pretrazivanja. Polazna osnova je niz duzine :
koji je sortiran rastucim redoslijedom i u kojem se treba pronaci vrijednost oznacena sa
1|,nc. Nacin na koji se obavlja ovaj posao je sljedeci:
Nae se "srednji" clan niza i 1|,nc uporedi sa tim clanom
Ako je 1|,nc manji od te vrijednosti tada se pretrazuje prva polovina niza; u
suprotnom pretrazuje se gornja polovina niza
Ovaj postupak se nastavlja sve dok se broj clanova za pretrazivanje ne svede na 1
Opisani postupak je opisan sljedecim pseudo kodom.
Ako je trazena vrijednost u sredini (sortiranog) niza petlja, koja pocinje na liniji 4, se
izvrava samo jednom.
27
# Binarno pretrazianje niza Opis
1 BinPret(c. :. 1|,nc) Ulaz : niz [c], : i 1|,nc
2 1o 1 Inicijalna vrijednost za donju granicu
3 Hi : Inicijalna vrijednost za gornju granicu
4 SveDokJe(1o _ Hi){
5 `id
1
2
(1o +Hi) Racunanje indeksa srednjeg clana
6 Ako Je (1|,nc < c (`id)) tada { Ako je trazeni element manji od c (`id) . . .
7 Hi `id 1 `id postaje gornja granica donje polovine niza
8 }
9 Inace Ako Je (1|,nc c (`id)) tada { Ako je trazeni element veci od c (`id). . .
10 1o `id + 1 `id postaje donja granica gornje polovine niza
11 }
12 Inace { Ako je trazeni element jednak c (`id). . .
13 Poruka : 1|,nc = c (`id) Izlaz Pronaen je 1|,nc
14 }
15 }
16 }
17 Poruka : Element nije pronaen 1|,nc nije pronaen
Table 4: Binarno pretrazivanje
U prvom prolazu se analizira niz duzine :, u narednom koraku niz duzine :,2, zatim niz
duzine :,2
k
i tako redom do duzine 1. Ovdje / oznacava koliko puta je vreno dijeljenje
sa 2. To znaci da za posljednji korak mora vrijediti
:
2
k
= 1 = : = 2
m
= log : = : log 2 = : =
log :
log 2
= log
2
: := lg 2
Na ovaj nacin je dobijena procjena maksimalnog broja koraka za postupak binarnog
pretrazivanja. Ako bi se broj elemenata povecao dva puta broj pretrazivanja bi bio
mnogo manji odnosno ne bi bio dvostruko veci to je znacajna uteda vremena rada.
4.3 Analiza kompleksnosti nekih tipova algoritama
4.3.1 Algoritmi konstantnog vremena
Primjer algoritma konstantnog vremena je izbor broja iz liste. Nije bitno koliko je lista
dugacka. U jednom koraku se odabire jedan broj i posao se zavrava. Ako se ulaz poveca
: puta vrijeme izvrenja se ne povecava odnosno "mijenja" se za faktor 1. U tom slucaju
se kaze da algoritam ima brzinu O(1).
2
Prosta naredba ima (1) vrijeme to je i razlog za naziv. Niz mnogo jednostavnih naredbi
jo uvijek se izvrava u vremenu (1) .
Primjer iz realnog zivota je izbor prvog dokumenta sa vrha gomile. Nije vazno kolika je
gomila. Algoritmi sa konstantnim vremenom su najbolji moguci algoritmi ukoliko vrijeme
same operacije nije predugacko. Primjeri ovih algoritama su:
2
Znacenje ce biti dato u poglavlju o asimptotskoj procjeni kompleksnosti
28
- Push i Pop operacije na stack-u (koji sadrzi : elemenata);
- Operacije umeatanja i uklanjanja u redu za izvrenje
4.3.2 Algoritmi u linearnom vremenu
Primjeri ovih algoritama su:
- Prolazak kroz listu (povezane liste ili niza) sa : elemenata
- Nalazenje maksimalnog ili minimalnog elementa u listi ili sekvencijalno pretrazivanje
nesortirane liste od : elemenata
- Prolazak stabla sa : cvorova
- Iterativno racunanje faktorijela broja :;
- Iterativno nalazenje :-tog Fibonacijevog broja
- Utvrivanje da li je broj paran ili ne
Linearni algoritmi su veoma uobicajeni u programiranju i generalno su prihvaceni kao
ekasni ako ne postoji bolji poznati nacin za njegovo ubrzanje.
Primjer programskog koda je :
for (int i = 0; i < n; i += c) // O(n)
statement(s);
Dodavanje konstante c brojacu petlje znaci da vrijeme trajanja petlje raste linearno u
odnosu na maksimalnu vrijednost za :. U ovom slucaju se petlja izvrava tacno :,c puta.
Analogno vrijedi ako se brojac i smanjuje za konstantu c.
4.3.3 Algoritmi sa kvadratnim vremenom
Primjeri ovih algoritama su :
- Neki jednostavniji algoritmi sortiranja npr. selection sort : elemenata
- Poreenje dva dvodimenzinalna niza od po : : elemenata
- Nalazenje duplikata u nesortiranoj listi od : elemenata (implementirano sa dvije ugn-
jezdene petlje)
Broj operacija, u oznaci O(:
2
), je proporcionalan kvadratu dimenzije resursa sa kojim
se radi.
Primjer programskog koda je :
for (int i = 0; i < n * n; i += c) // O(n
2
)
statement(s);
Maksimum petlje je :
2
tako da je vrijeme izvrenja kvadraticno. U ovom slucaju petlja
se izvrava tacno :
2
,c puta.
Primjer ugnjezdene petlje je :
for (int i = 0; i < n; i += c) { // O(n
2
)
for (int j = 0; j < n; i += c)
{
statement(s);
}
}
Primjeri algoritama brzine C(:
c
), c 1 su:
- Parsiranje putem stablasto udruzenih gramatika (tree-adjoining grammar parsing),
- Maksimalno poklapanje (matching) dva bipartitna grafa
29
4.3.4 Algoritmi sa logaritamskim vremenom
Primjeri ovih algoritama su
- Binarno pretrazivanje sortirane liste od : elemenata
- Operacije umetanja i nalazenja binarnog stabla sa : cvorova
- Operacije umetanja i uklanjanja u skupu (heap) sa : cvorova
Brzina ovih algoritama, u oznaci O(log :), raste sporije od velicine ulaza. Ako se ulaz
udvostruci vrijeme izvoenja se samo malo produzi. Klasican primjer algoritma u logari-
tamskom vremenu je binarno pretrazivanje. Primjer je poznata igra "pogaanje brojeva".
U toj igri jedan igrac mora pogoditi broj koji zamisli drugi igrac. Na svakom koraku se
vri pogaanje na nacin da saigrac kaze da li je predlozeni broj veci ili manji. Ako je broj
izmeu 1 i 100 prvi prijedlog je 50. Time se prostor pogaanja smanjuje za polovinu.
Naredni korak je predlaganje broja koji je u polovini odgovarajuceg intervala cime se
(grubo) suzava krug brojeva za pogaanje. Ako se u toj igri pocetni opseg udvostruci
broj pogaanja se ne udvostrucava. Ako se ulaz poveca : puta potrebno je log
2
: = lg :
koraka dok se ne doe do inicijalnog opsega.
Primjer programskog koda je :
for (int i = 1; i < n; i *= c) // O(log n)
statement(s);
Mnozenje brojaca petlje konstantom c znaci da maksimalna vrijednost za : mora rasti
eksponencijalno kako bi se vrijeme izvrenja petlje povecavalo linearno pa je iz tog razloga
vrijeme izvrenja logaritamsko. U ovom slucaju je c
k
= :, gdje je / broj prolaza. Na
osnovu ovoga je / = log
c
:. Analogno vrijedi ako se brojac smanjuje za konstantni faktor
c.
Brzinu O(:log :) = O(log :!) (linearitamsko, loglinear, quasilinear) imaju operacije
provoenja Furijeove transformacije, algoritmi sortiranja, kao to su quick sort, merge
sort heap sort.
4.3.5 Algoritmi brzine
_
:
Ovi algoritmi se izvravaju proporcionalno kvadratnom korijenu od : (velicina ulaza). U
ovom slucaju se izvrava petlja u kojoj i pocinje naprimjer od 1 i pravi se korak koji se
multiplikativno povecava za konstantu dok se ne postigne uslov i + i < :. Ova petlja se
nece izvriti svih : puta vec ce se zaustaviti kada i dostigne
_
:. Stoga ona ima vrijeme
(
_
:).
Primjer ovog algoritma je trazenje odgovora na pitanje da li je broj : prost. Odgovor
se moze dobiti tako da se provjerava da li je djeljiv sa svim brojevima koji su manji od
njega. Ako je : = 100 tada se moze stati ako je djelilac veci od 10 koji je
_
100.
4.3.6 Algoritmi sa eksponencijalnim vremenom
Primjeri ovih algoritama su:
- Problem trgovackog putnika
- Rekurzivna implementacija generisanja Fibonacijevih brojeva
- Hanojski tornjevi
- Generisanje svih permutacija od : elemenata
30
- Racunanje determinante putem racunanja minora
Ba kao to postoje algoritmi na koje povecanje obima ulaza nema uticaja postoje al-
goritmi za koje se cini da vrijeme izvrenja eksplodira. Kaze se da se eksponencijalni
algoritmi izvravaju u C(c
n
) ili eksponencijalnom vremenu.
Klasicni primjer algoritma sa eksponencijalnim vremenom izvrenja je Problem trgov-
ackog putnika (Traveling Salesman Problem - TSP), koji je do sada najvie izucavan u
teoriji algoritama. Zadatak je jednostavan. Dato je : gradova; trgovacki putnik mora
obici svaki grad tacno jednom prije nego ode kuci. Cilj je to uciniti na najbolji moguci
nacin bilo da je u pitanju najjeftiniji ili najkraci put. Pod najoptijim pretpostavkama,
jedini poznati nacin pouzdanog rjeavanja problema je da se ispita svaki moguci put i da
se odabere najbolja. Ne postoji poznati nacin da se eliminie razumni dio putanja bez
provjere svake od njih. Broj putanja je :!.
Algoritme sa eskponencijalnim vremenom izvrenja je potrebno izbjegavati to je vie
moguce. Umjesto direktnog rjeavanja traze se "heuristike" koje su kraci nacini da se
dobiju dobri rezultati ali to nije garancija da su oni i najbolji moguci. Heuristika za
problem trgovackog putnika moze biti : idi na najblizi neposjeceni grad; zatim povezi par
najblizih gradova. Dobra heuristika moze biti teka ali je dobit u programskom rjeenju.
Postoje bitne razlike izmeu pojedinih eksponencijalni algoritama.
Formalno gledano, vrijedi sljedeci odnos brzina algoritama
O(1) < O(log log :) < O(log :) < O(:) < O(:log :) < O(:
2
) < O(:
2
log :) <
O(:
3
) < ... < O(c
n
) < O(:!) < O(:
n
)
4.3.7 Kombinacije algoritama
Nizovi naredbi. Za sekvence naredbi, ukljucujuci moguce cijele blokova naredbi, uzima
se najgore moguce vrijeme izvrenja od svih naredbi. Naprimjer, blok vremena log : iza
kojeg slijedi linearni blok ima ukupno vrijeme koje je linearno; efekat log : petlje naprosto
icezava. Ne treba previe brinuti. Stara engleska izreka kaze : brini o dolarima a centi
ce se brinuti sami za sebe.
Konstrukcije Ako ... inace ... Za ove konstrukcije se uvijek uzima najgori moguci
slucaj ako ne postoji sigurnost ta ce se desiti. Najgori slucaj u bilo kojoj konstrukciji
ovog tipa je da se izvrava bilo Ako bilo ina ce dio, koji god da je od njih najgori. Iz
prakticnih razloga se uzima kako da se deavaju obje strane.
U izboru najgoreg moguceg slucaja mogu se slijediti dva prosta pravila.
1. Ako vrijeme ukljucuje stepen od : kao to je :
2
ili :
1=2
tada je blok sa vecim stepenom
od : gori
2. Ako su stepeni od : jednaki ili ako nema stepena od : blok sa vie log : je loiji
Naprimjer, ako se poredi :
_
:lg : sa lg
3
: prvi broj ima stepen :
1;5
dok drugi ima 0 kao
stepen za :. Dakle, prvi od njih je loiji.
Petlje. Vrijeme izvrenja jednostavne petlje (koja sadrzi samo jednostavne naredbe)
zavisi od toga koliko puta se petlja izvrava. Vrijeme petlji u nizu se sabira to znaci da
dominira petlja sa vecim vremenom izvrenja. Primjer je :
31
for (int i = 0; i < n; i += c) { // O(n)
statement;
}
for (int i = 0; i < n; i += c) { // O(n log n)
for (int j = 0; j < n; i *= c) {
statement;
}
}
Ugnjezdeni blokovi. Ako je blok ugraen unutar drugog bloka efekti se multipliciraju.
Ukupno vrijeme izvrenja postaje (:
2
). Primjer je poreenje dvije nesortirane liste
kako bi se vidjelo da li je neka stavka sadrzana u obje liste. Uzima se element prve liste i
poredi sa svakim elementom druge liste to uzima vrijeme reda :. S obzirom da se posao
ponavlja za : elemenata druge liste obavlja se :: = :
2
operacija poreenja. Dupliranje
obima ulaza ima za posljedicu cetiri puta duze vrijeme izvrenja.
32
5 Euklidov algoritam
5.1 Uvod
Euklidov algoritam je dobio je ime po starogrckom matematicaru Euklidu. To je na-
jekasniji algoritam za odreivanje najveceg zajednickog djelitelja dva ili vie brojeva.
Prvi poznati sacuvani opis Euklidovog algoritma se nalazi u Elementima (oko 300. go-
dine p.n.e.), to ga cini najstarijim numerickim algoritmom koji se jo uvijek aktivno
koristi. U originalu, objanjen je samo za prirodne brojeve i geometrijske duzine (re-
alne brojeve), ali je u 19. stoljecu primjenjen na polinome i na Gaussove cijele brojeve,
to je dovelo do razvoja novih pojmova apstraktne algebre. Euklidov algoritam je dalje
primjenjivan na drugim matematickim strukturama, poput cvorova i polinoma.
Euklidov algoritam ima iroku terijsku i prakticnu primenu. Predstavlja kljucni element
RSA algoritma, metode asimetricne kriptograje koja se u znacajnoj meri primenjuje
u elektronskom poslovanju. Moze se upotrijebiti za konstruiranje veriznih razlomaka,
u Sturmovoj metodi za odreivanje realnih nula polinoma i jo nekoliko suvremenih al-
goritama za faktorizaciju prirodnih brojeva. Na kraju, Euklidov algoritam je osnovno
sredstvo za dokazivanje teorema moderne teorije brojeva, kao to su Lagrangeova teo-
rem o cetiri kvadrata i osnovna teorema aritmetike o jedinstvenoj faktorizaciji prirodnih
brojeva. Euklidov algoritam je ekasan nacin za odreivanje NZD velikih brojeva zbog
toga to mu ne treba vie koraka od petostrukog broja cifara manjeg broja zapisanog sa
osnovom 10, to je dokazao Gabrijel Lame 1844. godine i time oznacio pocetak teorije
kompleksnosti.
U 20. stoljecu su razvijene metode za poboljanje ekasnosti Euklidovog algoritma.
5.2 Kako radi Euklidov algoritam ?
Teorem (Euklidov algoritam)
Neka su c. / Z gdje je c. / 0. c /. Pretpostavimo da je uzastopnom primjenom
teorema o dijeljenju ostatkom dobijen niz jednakosti
c = /
1
+:
1
. 0 < :
1
< /
/ = :
1

2
+:
2
. 0 < :
2
< :
1
...
:
j2
= :
j1

j
+:
j
. 0 < :
j
< :
j1
:
j1
= :
j

j+1
Tada je (c. /) = :
j
odnosno najveci zajednicki djelitelj je jednak posljednjem ostatku koji
je razlicit od nule u Euklidovom algoritmu
Do situacije :
j+1
= 0 se dolazi u konacno mnogo koraka jer :
j+1
= 0 implicira da je
`21(c. /) = `21(c. :
1
) = ... = `21(:
j1
. :
j
) = :
j
.
Na narednom dijagramu je data opta ema ovog algoritma
33
Euklidov algoritam za nalazenje najveceg zajednickog djelioca dva broja
Primjer. Euklidovim algoritmom naci najveci zajednicki djelitelj brojeva 3102 i 4002.
4002 = 1 3102 + 900
3102 = 3 900 + 402
900 = 2 402 + 96
402 = 4 96 + 18
96 = 5 18 + 6
18 = 3 6
= `21(4002. 3102) = 6
Pokazuje se da slozenost Euklidovog algoritma zavisi o logaritamski manjem broju / i to
nezavisno od c _ /.
Pojedine jednadzbe u postupku Euklidovog algoritma, kao u prethodnom primjeru, cemo
zvati Euklidske jednadzbe. Kako se vidi, provedeno je ukupno 10 dijeljenja. Ostaci su
takoe Fibonacijevi brojevi. Ovo je jasno jer iz jednakosti 1
n
= 1 1
n1
+ 1
n2
slijedi
da se dijeljenjem broja 1
n
sa 1
n1
u svakom koraku dobije kvocijent 1 i ostatak 1
n2
. Iz
ovoga generalno vrijedi
Teorem (Euklidov algoritam). Neka su :
0
= c i :
1
= / cijeli brojevi takvi da je c. / 0.
Ako se sukcesivnom primjenom algoritma o dijeljenju cijelih brojeva dobije
:
j
= :
j+1

j+1
+:
j+2
. 0 < :
j+2
< :
j+1
(, = 0. 1. .... : 2) i :
n+1
= 0
tada je `21(c; /) = :
n
tj. posljednji nenulti ostatak je `21(c; /).
Algoritam izlozen u navedenom teoremu naziva se Euklidov algoritam.
Propozicija. U Euklidovom algoritmu za svako i vrijedi :
i+2
<
1
2
:
i
.
34
Dokaz. Ako je :
i+1
_
1
2
:
i
tada je :
i+2
< :
i+1
_
1
2
:
i
. Neka je :
i+1

1
2
:
i
. Tada je
:
i
< 2:
i+1
. Tada iz :
i
=
i+2
:
i+1
+ :
i+2
slijedi
i+2
= 1 tj. :
i
= :
i+1
+ :
i+2
. Odavdje je
:
i+2
= :
i
:
i+1
<
1
2
:
i
. Dakle, tvrdnja vrijedi i u ovom slucaju
Ovaj algoritam vrijedi i za Fibonacijeve brojeve toce biti ilustrovano na dva Fibonacijeva
broja 1
11
= 89 i 1
12
= 144
144 = 1 89 + 55
89 = 1 55 + 34
55 = 1 34 + 21
34 = 1 21 + 13
21 = 1 13 + 8
13 = 1 8 + 5
8 = 1 5 + 3
5 = 1 3 + 2
3 = 1 2 + 1
2 = 1 2 + 0
Teorem. Neka je ,
1
= 1. ,
2
= 1. ,
n
= ,
n1
+ ,
n2
(: _ 3) Fibonacijev niz brojeva Za
svako : _ 2 Euklidov algoritam uzima tacno : dijeljenja za odreivanje GC1(,
n+1
. ,
n+2
).
Dokaz. Polazeci od rekurzivne jednakosti ,
i+2
= ,
i+1
+,
i
(i = 1. 2.) dobijamo
,
n+2
= ,
n+1
1 +,
n
,
n+1
= ,
n
1 +,
n1
...
,
4
= ,
3
1 +,
2
,
3
= ,
2
2
Dakle, Euklidov algoritam za odreivanje GC1(,
n+2
. ,
n+1
) uzima tacno : dijeljenja i
vrijedi GC1(,
n+2
. ,
n+1
) ,
2
1.
Teorem (Lame-ov teorem). Broj dijeljenja potrebnih za odreivanje najveceg zajed-
nickog djelioca prirodnih brojeva c i / ne prelazi petostruku vrijednost broja decimalnih
cifara manjeg od ta dva broja.
Dokaz. Neka je c /. Kada se primijeni Euklidov algoritam za odreivanje najveceg
zajednickog djelioca brojeva c = :
0
i / = :
1
dobija se sljedeci niz relacija:
:
0
= :
1

1
+:
2
. 0 < :
2
< :
1
:
1
= :
2

2
+:
3;
0 < :
3
< :
2
...
:
n2
= :
n1

n1
+:
n
. 0 < :
n
< :
n1
:
n1
= :
n

n
Koristi se : dijeljenja. Potrebno je primijetiti da su svi koecijenti
1
.
2
. ....
n1
veci ili
jednaki 1 i da je
n
_ 2 jer je :
n
< :
n1
. Zbog toga je
:
n
_ 1 = ,
2
:
n1
_ 2:
n
_ 2,
2
= ,
3
:
n2
_ :
n1
+:
n
_ ,
3
+,
2
= ,
4
:
n3
_ :
n2
+:
n1
_ ,
4
+,
3
= ,
5
35
...
:
2
_ :
3
+:
4
_ ,
n1
+,
n2
= ,
n
/ = :
1
_ :
2
+:
3
_ ,
n
+,
n1
= ,
n+1
Dakle, ako imamo : dijeljenja u Euklidovom algoritmu tada je min c. / _ ,
n+1
. Neka
je c =
1 +
_
5
2
. Tada je c
2
= c + 1. Matematickom indukcijom se jednostavno dokazuje
da je ,
n
c
n2
za svako : N, : _ 3. Zbog toga je / _ ,
n+1
c
n1
tj. log /
(: 1) log c. Kako je log c
1
5
to je log /
: 1
5
. Dakle, : 1 < 5 log /. Ako / ima
/ cifara u decimalnom zapisu onda je / < 10
k
pa je log / < /. To znaci da je : < 1 + 5/
odnosno : _ 5/.
5.3 Zadaci za samostalni rad
Zadatak. Dati su prirodni brojevi :. :
1
. :
2
. .... :
m
(: _ 2). Izracunati `21(:
1
. :
2
. .... :
m
)
koristeci se relacijom `21(:
1
. :
2
. .... :
k
) = `21(`21(:
1
. :
2
. .... :
k1
) . :
k
) i algorit-
mom Euklida.
Zadatak. Dati su prirodni brojevi : i :. Koritenjem Euklidovog algoritma naci:
Najveci zajednicki djelitelj (NZD) brojeva : i :
Najmanji zajednicki sadrzalac brojeva : i :
Brojeve j. koji nemaju zajednickih sadrzalaca za koje vrijedi :,: = j,
36
6 Asimptotska procjena slozenosti algoritma
6.1 Uvod

Cesto je teko, pa i nemoguce, izvesti egzaktnu formulu za broj operacija nekog algoritma.
Zato se proucava asimptotsko ponaanje broja operacija kad velicina ulaznih podataka
neograniceno raste. Najpoznatije asimpotske notacije slozenosti algoritma su: -notacija,
O-notacija i -notacija.
6.1.1 -notacija
Denicija. Neka je q (:) funkcija denisana na nekom podskupu skupa prirodnih brojeva
i ciji je skup vrijednosti neki podskup skupa realnih brojeva. Sa (q (:)) se oznacava
skup funkcija , (:) takvih da postoje pozitivne konstante c
1
, c
2
i prirodan broj :
0
takvi
da je
0 _ c
1
q (:) _ , (:) _ c
2
q (:) za svako : _ :
0
Ovdje oznacava klasu funkcija a , (:) = (q (:)) je oznaka za inkluziju , (:)
(q (:)).
Primjer 1. Neka je , (:) =
2
3
:
2
:, : N. Tada je , (:) = (:
2
). Najprije, vrijedi
c
1
:
2
_
2
3
:
2
: _ c
2
:
2
za svako :
0
_ : ako i samo ako c
1
_
2
3

1
n
_ c
2
za svako
:
0
_ :. Odavdje slijedi da mora biti c
2
_
2
3
. Kako c
1
mora biti pozitivan broj to mora
biti
2
3

1
n
_ 0. To znaci da je dovoljno uzeti :
0
= 3. Iz c
1
_
2
3

1
3
slijedi c
1
_
1
3
. Dakle,
vrijedi da je
1
3
:
2
_ , (:) _
2
3
:
2
za svako : _ 3.
Primjer 2. Neka je , (:) = c:
2
+ /: + c gdje su c. /. c konstante i c 0. Da li je
, (:) = (:
2
) ? Potrebno je odrediti konstante c
1
i c
2
i prirodan broj :
0
takve da je
c
1
:
2
_ c:
2
+/:+c _ c
2
:
2
za svako : :
0
. Neka je c
1
< c i c
2
c. Tada su nejednacine
(c c
1
) :
2
+/: +c _ 0 i (c
2
c) :
2
+/: +c _ 0 zadovoljene za sve prirodne brojeve :
0
takve da je :
0
max r
1
. r
2
.
1
.
2
gdje su r
1
i r
2
nule polinoma (c c
1
) :
2
+/:+c a
1
i
2
nule polinoma (c
2
c) :
2
+/: +c ako postoje; ako ne postoje onda je :
0
= 1. znaci,
vrijedi , (:) (:
2
). Takoe, ako je , (:) polinom stepena : ciji je vodeci koecijent
pozitivan onda je , (:) = (:
m
).
6.1.2 O-notacija
Denicija. Neka je q (:) realna funkcija denisana na nekom podskupu skupa prirod-
nih brojeva. Sa O(q (:)) se oznacava skup realnih funkcija , (:) denisanih na nekom
podskupu skupa realnih brojeva takvih da postoji pozitivna konstanta c i prirodan broj
:
0
takvi da je
0 _ , (:) _ c q (:) . za svako : _ :
0
Ovdje O oznacava klasu funkcija a , (:) = O(q (:)) je oznaka za inkluziju , (:)
O(q (:)). Treba primijetiti da , (:) = (q (:)) povlaci , (:) = O(q (:)).
Velicina O() se tumaci tako da je q (:) gornja granica za , (:). U tom smislu, oznaka
, (:) = O(q (:)) se tumaci da ", ne raste brze od q".
37
Notacija Veliko-O (O) ima dvije glavne oblasti primjene. U matematici se obicno koristi
da opie koliko blisko konacni niz aproksimira datu funkciju, posebno u slucaju skracenog
(truncated) Tejlorovog niza ili asimptotske ekspanzije. U kompjuterskoj nauci je korisna
za analizu algoritama. U obje vrste primjene funkcija koja se pojavljuje unutar C()
tipicno se bira da bude to je moguce jednostavnija, pri cemu se izostavljaju konstantni
faktori i clanovi manjeg reda.
Postoje dva formalno bliska ali bitno razlicita koritenja ove notacije: beskonacna (in-
nite) i innitezimalna asimptotika. Ova razlika je jedino u primjeni ali nije i principijelna.
Formalna denicija za O() je jednaka u oba slucaja sa razlicitim limitima za argumente
funkcije.
U nastavku ce biti navedeno nekoliko jednostavnih ali znacajnih osobina O notacije.
1. Ako je , (:) = O(q (:)) tada je c , (:) = O(q (:)) za svaku pozitivnu konstantu
c.
2. Ako je ,
i
(:) = O(q
i
(:)), i = 1. 2. .... / tada je
,
1
(:) +,
2
(:) +... +,
k
(:) = O((q
1
+q
2
+... +q
k
) (:))
3. Ako je ,
i
(:) = O(q (:)), i = 1. 2. .... / tada je
,
1
(:) +,
2
(:) +... +,
k
(:) = O(q (:))
4. Ako je ,
i
(:) = O(q
i
(:)), i = 1. 2. .... / tada je
,
1
(:) ,
2
(:) ... ,
k
(:) = O(q
1
(:) q
2
(:) ... q
k
(:))
Ako je , (:) monotono rastuca funkcija koja nije ogranicena, c 1 i c 0, tada
, (:)
c
= O
_
c
f(n)
_
Za , (:) = : dobija se :
c
= O(c
n
) a za , (:) = log
a
: dobija se (log
a
:)
c
= O
_
c
log
a
n
_
=
O(:) to znaci da proizvoljan stepen logaritamske funkcije raste spporije od linearne
funkcije.
Primjer. Kako je
lim
n!1
ln :
:

= 0
za svako c 0 tada vrijedi da je ln : = O(:

) za svako c 0.
Primjer. Neka je , (:) broj bita broja :. Tada je , (:) = [log
2
:] + 1. Kako je
lim
n!1
, (:)
log
2
:
= 1
tada vrijedi da je , (:) = O(log
2
:). S obzirom da je log
2
: =
ln n
ln 2
to je , (:) = O(ln :).
6.1.3 -notacija
Denicija. Neka je q (:) realna funkcija denisana na nekom podskupu prirodnih bro-
jeva. Sa (q (:)) se oznacava skup realnih funkcija , (:) denisanih na nekom podskupu
skupa realnih brojeva takvih da postoji konstanta c 0 i prirodan broj :
0
takvi da vrijedi
0 _ c q (:) _ , (:) za svako : _ :
0
.
Ovdje () oznacava klasu funkcija a , (:) = (q (:)) je oznaka za inkluziju , (:)
(q (:)).
38
Velicina () se tumaci tako da je q (:) donja granica za , (:). U tom smislu, oznaka
, (:) = (q (:)) se tumaci da ", raste najmanje kako raste q".
Iz denicije asimpotskih notacija direktno slijedi naredni teorem.
Teorem. Za bilo koje dvije funkcije , (:) i q (:) vrijedi , (:) = (q (:)) ako i samo ako
je , (:) = O(q (:)) i , (:) = (q (:)).
6.1.4 Primjeri racunanja slozenosti
Primjer 1. Sabiranje ili oduzimanje dva :-bitna cijela broja ima kompleksnost O(:).
Za analizu kompleksnosti mnozenja dva broja potreban je kratki prikaz postupka. Jedan
od mogucih nacina mnozenja dva cijela :-bitna broja je tzv. digitalni metod. Neka su
c = (c
2n1
c
2n2
...c
1
c
0
)
2
/ = (/
2n1
/
2n2
.../
1
/
0
)
2
Moze se staviti

1
= (c
2n1
c
2n2
...c
n+1
c
n
)
2
.
0
= (c
n1
c
n2
...c
1
c
0
)
2
1
1
= (/
2n1
/
2n2
.../
n+1
/
n
)
2
. 1
0
= (/
n1
/
n2
.../
1
/
0
)
2
Tada se moze staviti c = 2
n

1
+
0
i / = 2
n
1
1
+1
0
. Odavdje je
c / = (2
2n
+ 2
n
)
1
1
1
+ 2
n
(
1

0
) (1
0
1
1
) + (2
n
+ 1)
0
1
0
Ovo znaci da se za proizvod dva 2:-bitna broja moraju izracunati dvije razlike
1

0
i 1
0
1
1
dva :-bitna broja, tri proizvoda
1
1
1
, (
1

0
) (1
0
1
1
),
0
1
0
a zatim
izvriti pomjeranje ulijevo i sabiranje.
Ako se sa ` (:) oznaci broj bit operacija potrebnih za mnozenje dva :-bitna cijela broja
onda vrijedi
` (2:) _ 3 ` (:) +C :
gdje je C konstanta. Naime, svako mnozenje dva :-bitna cijela broja zahtijeva ` (:)
bitnih operacija a sabiranje, oduzimanje i pomjeranje ulijevo su operacije reda O(:).
Odavdje se dobija relacija
`
_
2
k
_
_ 1
_
3
k
2
k
_
gdje je 1 = max ` (2) . C.
Teorem. Mnozenje dva :-bitna cijela broja moze biti izvedeno koritenjem O
_
:
log
2
3
_
bit operacija.
Dokaz. Za mnozenje dva :-bitna broja je potrebno ` (:) bit operacija. Na osnovu
prethodnih relacija vrijedi:
` (:) = `
_
2
log
2
n
_
_ `
_
2
[log
2
n]+1
_
_ 1
_
3
[log
2
n]+1
2
[log
2
n]+1
_
< 1 3
[log
2
n]+1
_ 3 1
_
3
[log
2
n]
_
_ 31 3
[log
2
n]
= (31) :
log
2
3
Odavdje imamo da je ` (:) = O
_
:
log
2
3
_
.
Primjer 2. Naci O(:!).
Rjeenje. Kako je :! = 1 2 ... : = (... ((2 3) 4) 5...) :, za racunanje broja :! je
potrebno : 2 mnozenja. Najprije se mnozi 2 3 pa se dobijeni proizvod pomnozi sa 4,
novi rezultat sa 5 itd dok se ne doe do mnozenja sa :. U koraku (i 1) se i! mnozi sa
i + 1 pa je stoga broj mnozenja jednak : 2. Za odreivanje broja bit operacija treba
se podsjetiti cinjenice da je broj cifara proizvoda dva binarna broja jednak sumi cifara
faktora ili je za 1 manji od te sume. Neka broj : ima / bita. Svaki broj manji od : ima
39
najvie / bita. Stoga je :!, kao proizvod : brojeva sa najvie / bita, najvie :/ bitni broj.
Broj bita broja :! je manji ili jednak sumi bita svakog faktora to je manje ili jednako
:/. Zbog toga je, za svaki prirodan broj i _ :, broj i! najvie : /-bitni. Za mnozenje i!
sa i potrebno je najvie (:/)/ = :/
2
bit operacija. Kako ovakvih mnozenja ima (: 2)
to je za izracunavanje :! potrebno najvie
(: 2) (:/
2
) = :(: 2) (1 +log
2
:|)
2
= :(: 2) (lg :)
2
= O
_
(:lg :)
2
_
bit operacija.
40
7 Analiza kompleksnosti - nastavak
7.1 Uvod
Cilj analize algoritama je da se predvidi njegovo ponaanje, posebno brzina izvravanja,
bez realizacije na nekom (konkretnom) racunaru. Ideja je da se procijeni brzina rada bez
realizacije samog algoritma tako da procjena vrijedi za svaki racunar.
Tacno ponaanje algoritma je nemoguce predvidjeti osim u najjednostavnijim slucaje-
vima. Na ponaanje utice mnogo faktora pa se u obzir uzimaju samo glavne karakteristike
a zanemaruju se detalji vezani za tacnu realizaciju. Iz tog razloga analiza algoritma je pri-
blizna. Na taj nacin se, ipak, dobijaju znacajne informacije o algoritmu koje omogucavaju
uporeivanje razlicitih algoritama za rjeavanje istog problema.
Logican korak je da se zanemare konstantni faktori jer se brzine izvravanja algoritama
na raznim racunarima razlikuju priblizno za konstantan faktor. Od interesa je ocjena
algoritma kada ulazna velicina tezi beskonacnosti.
U analizi algoritama se za svaki ulaz odreuje njegova velicina (dimenzija) :. Velicina
ulaza nije striktno denisana; obicno je to mjera velicine memorijskog prostora potrebnog
za smjetanje ulaza.
Ocjena vremenske slozenosti algoritma se sastoji u brojanju racunskih koraka koje treba
izvriti. Termin "racunska operacija" moze obuhvatiti vie tipova operacija kao to je
sabiranje i mnozenje. Vrijeme izvravanja zavisi od konkretnog racunara, odabranog
programskog jezika i slicno. Stoga se u algoritmu izdvaja korak koji se ponavlja i koji na
taj nacin postaje osnova analize. Naprimjer, u sortiranju je to uporeivanje.
Osnovna pravila za kalkulisanje slozenosti algoritama su :
Svaka instrukcija u sekvenci se broji kao 1 bez obzira na to koliko je izraz slozen i
koliko se stvarno koristi mainskih instrukcija
Konstrukcija "Za Svaki <..." se broji : + 1 puta ako se tijelo petlje izvri : puta
Konstrukcija "Za svaki <" se broji : + 1 puta ako se tijelo petlje izvri : puta
Konstrukcija "Ako <" se broji kao 1 svaki put kad se "postavi pitanje" a ono
to uslovljava naredba "Ako ..." broji se onoliko puta koliko to zahtijeva konkretni
slucaj
Konstrukcija "SveDok(<uslov)" se broji : + 1 puta ako se tijelo petlje izvri :
puta
Na nekoliko narednih primjera ce biti pokazan nacin kalkulisanja slozenosti.
41
# Sekvencijalno trazenje Broj Opis
1 TraziSek(c. :. 1|,nc) Ulaz : niz [c] duzine : i 1|,nc
2 `c:co l 1 Inicijalizacija radne promjenljive
3 Za sve i = 1 do : { : + 1 Pocetak unutranje petlje
4 Ako je c [i] = 1|,nc tada { : Postavljanje upita
5 `c:co Postavljanje na drugu vrijednost
6 }
7 }
Table 5: Sekvencijalno pretrazivanje
7.2 Zadaci
Primjer. Sekvencijalno pretrazivanje.
U ovom primjeru je prezentirana metoda sekvencijalnog pretrazivanja niza u kojem se
trazi vrijednost 1|,nc.
Ovdje je oznaka da li se realizovao uslov "Ako ...". Na osnovu ovoga se moze zakljuciti
da se slozenost ovog algoritma izrazava izrazom
1 (:) = 2: + 2
Ovo je vrijednost za najgori slucaj, kada se uslov na liniji 3 izvri : puta. Na taj nacin
se zakljucuje da algoritam ima linearnu brzinu odnosno 1 (:) = O(:). Drugim rijecima,
linearno povecanje broja elemenata koji se ispituju znaci linearno povecanje vremena za
njegovo izvrenje.
Primjer. Bubble sort
U ovom primjeru je data analiza slozenosti algoritma tzv. Bubble sorta.
# Sortiranje Broj Opis
1 BubbleSort(c [:]) Sortiranje niza c [:]
2 Za i = 1 do : 1 { : Pocetak vanjske petlje
3 Za , = : 1 do i korak 1 { Pocetak unutranje petlje
4 Ako je (c [,] c [, + 1]) tada { Upit
5 / c [,] Zamjena vrijednosti
6 c [,] c [, + 1]
7 c [, + 1] /
8 }
9 }
10 }
Table 6: Analiza Bubble sort metode
Korak na liniji 2 se izvodi : puta. Korak na liniji 3 se za i = 1 izvodi : puta, za i = 2
izvodi : 1 puta, ..., sve do i = : 1 kada se izvodi 2 puta. Korak na liniji 4 se izvodi
sekvencijalno : 1. : 2. .... 1 puta za i = 1. : 1. Koraci na linijama 5, 6 i 7 se izvode
isti broj puta kao i korak (upit) na liniji 4. To znaci da je ukupan broj koraka ovog
algoritma
42
1 (:) = : + (1 + 2 + 3 +... +: 1) + 4 (1 + 2 +... + (: 1))
1 (:) = : +
:(: + 1)
2
1 + 4
:(: 1)
2
1 (:) =
:(5: 6)
2
Ovo je broj za najgori slucaj : kada je pocetni niz sortiran opadajucim redom. Zakljucak
je da je 1 (:) = O(:
2
) odnosno da se algoritam izvodi u kvadratnom vremenu.
Primjer. Sumiranje sa povecanjem inkrementa
Sljedeci primjer ilustruje kompleksnost u slucaju kada se u svakom koraku gornja granica
brojaca povecava dva puta.
# Korak Broj Opis
1 Sumiraj(:) Ulaz : broj iteracija (:)
2 / 1 1 Inicijalizacija
3 on:c 0 1 Inicijalizacija sume
4 Za i = 1 do : { : + 1 Pocetak spoljne petlje
5 Za , = 1 do / { Pocetak unutranje petlje
6 on:c on:c +i , 2
n
1 Sumiranje
7 }
8 / / +/ : Dupliranje varijable /
9 }
Table 7: Sumiranje sa rastucim inkrementom
Najprije cemo napraviti analizu ta ovaj algoritam radi. Ako je i = 1 tada se vri jedno
sumiranje na liniji 6. Ako je i = 2 tada se vre 4 sumiranja na liniji 6. Razlog je u cinjenici
da se linija 8, na kojoj se vrijednost za / udvostrucava, izvrava onoliko puta koliko se
promijeni i odnosno : puta. Na taj nacin unutranja petlja vri uzastopno sumiranje
1. 2. 4. .... 2
n1
clanova. Ne treba izgubiti iz vida da se unutranja petlja izvrava 2
k
+ 1
puta. Na osnovu toga, broj koraka izvrenja ovog algoritma je
1 (:) = 1 + 1 + (: + 1) + (1 + 2 + ... + 2
n1
+: 1) + (2
n
1) +:
1 (:) = 3: + 1 + 2 (2
n
1) = 2
n+1
+ 3: 1
Zakljucak je da je 1 (:) = C(2
n
) s obzirom da je 2
n+1
= 2
n
2.
Zadatak. Dokazati da je vrijeme 1 (:) = :
3
+ 20: + 1 jednako O(:
3
).
Dokaz. Prema deniciji O notacije, 1 (:) = O(:
3
) ako je 1 (:) _ c :
3
za neko : _ :
0
.
Ako je :
3
+ 20: + 1 _ c :
3
tada 1 +
20
:
2
+
1
:
3
_ c. Ovo vrijedi za svako : _ :
0
= 1 i
c _ 22. Za vece vrijednosti :
0
potreban je manji broj c (npr. za :
0
= 10 je c _ 1.201)
ali u svakom slucaju vrijedi trazena nejednakost.
Zadatak. Pokazati da vrijeme 1 (:) = :
3
+ 20: + 1 nije O(:
2
).
Dokaz. Prema deniciji O notacije, 1 (:) = O(:
3
) ako je 1 (:) _ c :
3
za neko : _ :
0
.
Ako je :
3
+ 20: + 1 _ c :
3
tada 1 +
20
:
2
+
1
:
3
_ c. Lijeva strana posljednje nejednakosti
43
raste neograniceno tako da ne postoji konstanta c. Stoga, O uslov ne moze vrijediti u
ovom slucaju.
Zadatak. Pokazati da je vrijeme 1 (:) = :
3
+ 20: + 1 jednako O(:
4
).
Dokaz. Prema deniciji O notacije, 1 (:) = O(:
4
) ako je 1 (:) _ c :
4
za neko : _ :
0
.
Ako je :
3
+ 20: + 1 _ c :
3
tada
1
:
+
20
:
3
+
1
:
4
_ c. Ovo vrijedi za svako : _ :
0
= 1 i
c _ 22. Za vece vrijednosti :
0
potreban je manji broj c (npr. za :
0
= 10 je c _ 1.201)
ali u svakom slucaju vrijedi trazena nejednakost.
Zadatak. Pokazati da je vrijeme 1 (:) = :
3
+ 20: jednako (:
2
).
Dokaz. Prema deniciji notacije, 1 (:) = (:
2
) ako je 1 (:) _ c :
2
za neko : _ :
0
.
Ako je :
3
+ 20: + 1 _ c :
2
tada : +
20
:
_ c. Lijeva strana nejednakosti ima minimalnu
vrijednost 8.94 za : =
_
20. Stoga uslov za vrijedi za svako : _ :
0
= 5 i c _ 9. Za
vece vrijednosti :
0
potreban je veci broj c (npr. za :
0
= 10 je c _ 12.01) ali u svakom
slucaju vrijedi trazena nejednakost.
7.3 Zadaci za samostalni rad
Zadatak. Napraviti algoritam i ispitati slozenost u sljedecim slucajevima

100

i=1
50

j=1
1
i +,
2

100

i=1
60

j=1
sin (i
3
+,
4
)

100

i=1
100

j=1
, i + 1
i +,

100

i=1
i

j=1
1
2, +i

k=1
/ (/ + 1) .. /
2

k=1
/
k

k=1
1
(/
2
)!

k=1
(1)
k
(2/
2
+ 1)!
Zadatak. Data je cjelobrojna matrica [c
ij
]
;j=1;;n
. Izracunati /
1
. /
2
. .... /
n
gdje je
44
/
i
=
n

j=1
c
2
ij
/
i
=
n

j=1
(1)
i+j
c
ij
/
i
=
n

j=1
c
ij
/
i
=
n

j=1
[c
ji
[
/
i
=
n

j=1
c
ij
, gdje je 1 < c
ji
_ :
/
i
= max c
ij
1jn
. /
i
= min c
ji
1jn
45
8 Rekurzije
8.1 Uvod
Rekurzija je situacija kada je za racunanje u jednom koraku potreban rezultat prethodnog
koraka. Postoje brojni primjeri rekurzija u matematici. Primjeri su :
Denicija faktorijela : 0! = 1. :! = (: 1)! :
Fibonacijevi brojevi: 1
n
= 1
n1
+1
n2
, pri cemu je 1
1
= c i 1
2
= /.
U teoriji algoritama pojam rekurzije se odnosi na rutine (funkcije, procedure) koje pozi-
vaju same sebe. One su tipicne za pristupe "podijeli pa vladaj" gdje funkcija ulaz dijeli
na manje dijelove i poziva se na svakom od tih dijelova. Primjer je binarno pretrazivanje
: u svakom koraku se trazi polovina prostora koji je dobijen u prethodnom koraku (npr.
sredina niza).
Ako za clanove niza 1
n
, : = 1. 2. ... vazi jednakost
1
n
= , (1
n1
. 1
n2
. .... 1
1
. :)
kaze se da niz 1
n
zadovoljava diferentnu jednadzbu ili rekurentni izraz. Specijalno, ako
se za neko / _ 1 clan 1
n
izrazava preko / prethodnih clanova niza
1
n
= , (1
n1
. 1
n2
. .... 1
nk
. :)
onda je / red te diferentne jednacine. Matematickom indukcijom se pokazuje da je ovaj
niz jednoznacno odreen sa prvih / clanova niza 1
1
. 1
2
. .... 1
k
.
Jedna od najpoznatijih diferentnih jednacina je ona koja denie Fibonacijev niz
1
n
= 1
n1
+1
n2
. 1
1
= 1
2
= 1
Za racunanje vrijednosti 1
n
potrebno je izvriti :2 koraka sabiranja to je neprakticno
za velike :.
Nacin procjene brzine rekurzivnih algoritmace biti prezentiran na jednom primjeru. Neka
je data rekurzivna relacija
1 (:) = 2 1 (:,2) +:. 1 (1) = 1
Izraz kojim se izracunava svaki clan niza koji se generie zove se rjeenje. U ovom slucaju
je cilj procijeniti gornju granicu za koju je 1 (:) _ , (:). Vrijedi:
1 (:) = 2 1 (:,2) +: =
= 2 [2 1 (:,4) +:,2] +: =
= 4 1 (:,4) + 2: =
= 4 [2 1 (:,8) +:,4] + 2: =
= 8 1 (:,8) + 3:
= ...
= 2
k
1
_
:,2
k
_
+/ :
Zna se da je 1 (1) = 1 i to je nacin da se posao nastavi.

Zelja je da se na desnoj strani
pojavi 1 (1) to znaci da je
46
:,2
k
= 1 = : = 2
k
= / = log
2
:
Na osnovu ovoga se nastavlja prethodna jednacina pa je:
1 (:) = 2
log
2
n
1 (1) + : log
2
: =
= : +: log
2
: = O(:lg :)
Opte rjeenje kojim se daju uslovi procjene vremena rekurentnih algoritama daje Master
teorem, koji je formulisan i dokazan od strane Cormen, Leierson, Rivest i Stein u knjizi
Introduction to Algorithms. Generaliziranu formu Master teorema dali su Akra i Bazzi
1998. godine i on se odnosi na mnogo iru klasu rekuzivnih algoritama.
Teorema. Asimptotsko ponaanje niza 1 (:) rjeenja rekurentnog izraza
1 (:) = c 1
_
:
/
_
+, (:) (1)
u kojem je c _ 1 i / 1 konstante i , (:) asimptotski pozitivna funkcija, dato je
jednakocu
1 (:) =
_
_
_

_
:
log
b
a
_
, (:) = O
_
:
log
b
a"
_
. 0

_
:
log
b
a
log
k+1
:
_
, (:) =
_
:
log
b
a
log
k
:
_
. / _ 0
(, (:)) , (:) =
_
:
log
b
a+"
_
. 0
U posljednjem slucaju , (:) mora zadovoljavati uslov regularnosti c , (:,/) _ c , (:)
za neku konstantu c < 1 i dovoljno veliko :.
Jedna od varijanti formulacije ovog problema je cilj analiza algoritma / pri cemu je broj
operacija 1 (:) za ulaz velicine : (vremenska slozenost) dat rekurentnim izrazom
1 (:) = c 1
_
:
/
_
+c :
k
pri cemu je c. /. c. / 0, / ,= 0 odnosno , (:) = c :
k
i zadata je vrijednost 1 (1).
Ovakva jednacina se dobija za algoritam kod kojeg se obrada ulaza velicine : svodi na
obradu c ulaza velicine :,/ poslije cega je potrebno izvriti jo c :
k
koraka da bi se od
parcijalnih rjeenja konstruisalo rjeenje kompletnog ulaza velicine :. Drugim rijecima,
broj c je broj podproblema na koje se dijeli pocetni problem. Za ove algoritme se kaze
da su tipa "podijeli pa vladaj" (divide-and-conquer) to je drugi naziv za algoritme koji
su zasnovani na dekompoziciji. Uobicajeno je da bude / N.
Dokaz. Dokaz ce biti proveden samo za podniz : = /
m
gdje je : cijeli nenegativni broj.
Mnozenjem izraza (1) sa c
m
,c dobija se rekurentni izraz
t
m
= t
m1
+
m
. t
0
=
1
c
1 (1)
gdje je t
m
=
1
c
c
m
1 (/
m
) i = /
k
,c. Rjeenje je
t
m
= t
0
+
m

i=1

i
47
Za ,= 1 je
m

i=1

i
=
1
m+1
1
1
pa se asimptotsko ponaanje niza t
m
opisuje sljedecim jednakostima
t
m
=
_
_
_
O(:) = 1
O(1) 0 < < 1
O(
m
) 1
S obzirom da je 1 (/
m
) = c c
m
t
m
, : = /
m
odnosno : = log
b
: redom se za 0 < < 1
(/
k
< c), = 1 (/
k
= c odnosno / = log
b
c) i 1 (/
k
c) dobija
1 (:) =
_
_
_
O(c
m
) = O
_
/
mlog
b
a
_
= O
_
:
log
b
a
_
c /
k
O(:c
m
) = O
_
log
b
: :
log
b
a
_
= O
_
:
k
log :
_
c = /
k
O((c)
m
) = O
_
/
mk
_
= O
_
:
k
_
c < /
k
Pogodno je upamtiti neke od narednih relacija.
Rekurzija Algoritam O()
1 (:) = 1 (:,2) +O(1) Binarno pretrazivanje O(log :)
1 (:) = 1 (: 1) +O(1) Sekvencijalno pretrazivanje O(:)
1 (:) = 2 1 (:,2) +O(1) Put po stablu O(:)
1 (:) = 1 (: 1) +O(:) Selection sort O(:
2
)
1 (:) = 2 1 (:,2) +O(:) Merge sort O(:log :)
Table 8: Uporedni pregled brzina algoritama
8.2 Zadaci
Zadatak. Neka je 1 (:) = 8 1
_
:
2
_
+ 1000:
2
.
Rjeenje. Ovdje je c = 8, / = 2, , (:) = 1000:
2
, log
b
c = log
2
8 = 3. Sada se provjerava
da li vrijedi
, (:) = O
_
:
log
b
a"
_
= 1000:
2
= O(:
3"
)
Ako se izabere = 1 tada se dobije 1000:
2
= O(:
2
). S obzirom da ovo vrijedi koristi se
prvi slucaj Master teoreme pa se zakljucuje da je
1 (:) =
_
:
log
b
a
_
= (:
3
)
Tacno rjeenje ovog rekurentnog izraza je 1 (:) = 1001:
3
1000:
2
sa uslovom 1 (1) = 1.
Zadatak. Neka je 1 (:) = 2 1
_
:
2
_
+ 10:.
Rjeenje. Ovdje je c = 2, / = 2, / = 0, , (:) = 10:, log
b
c = log
2
2 = 1. Sada se
provjerava da li vrijedi
, (:) = O
_
:
log
b
a
_
= , (:) = O(:)
48
Sada se koristi drugi slucaj Master teoreme pa se zakljucuje da je
1 (:) =
_
:
log
b
a
log
k+1
:
_
= (:log :)
Tacno rjeenje ovog rekurentnog izraza je 1 (:) = :+10: log
2
: uz uslov da je 1 (1) = 1.
Zadatak. Neka je 1 (:) = 2 1
_
:
2
_
+:
2
.
Rjeenje. Ovdje je c = 2, / = 2, , (:) = :
2
, log
b
c = log
2
2 = 1. Sada se provjerava da li
vrijedi
, (:) =
_
:
log
b
a+"
_
= (:
1+"
)
Ako se izabere = 1 tada se dobije :
2
= (:
2
). Koristi se treci slucaj Master teoreme,
s tim da se najprije provjerava uslov regularnosti :
c ,
_
:
/
_
_ c , (:) = 2
_
:
2
_
2
_ c :
2
Ako se izabere c = 1,2 tada je uslov zadovoljen \: N pa je 1 (:) = (, (:)) odnosno
1 (:) = (:
2
). Tacno rjeenje je 1 (:) = 2:
2
: uz uslov da je 1 (1) = 1.
Zadatak. Neka je 1 (:) = 6 1
_
:
3
_
+:
2
log :.
Rjeenje. U ovom slucaju je
log
b
c = log
3
6 = 1 + log
3
2 < 2
Na osnovu ovoga je
, (:) = :
2
log : =
_
:
1+log
3
2+"
_
S obzirom da se radi o slucaju (3) Master teoreme provjerava se uslov regularnosti:
c ,
_
:
/
_
_ c , (:)
6
_
:
3
_
2
log
:
3
_ c :log :
2
3
(log : log 3) _ c log : =
= c _
2
3

log : log 3
log :
=
2
3

_
1
log 3
log :
_
Ovaj uslov vrijedi za dovoljno veliko : pa se moze pisati da je
1 (:) = (, (:)) = (:
2
log :)
Zadatak. Za sljedece izraze, koritenjem Master teoreme, utvrditi da li su rjeivi :
1 (:) = 3 1
_
:
2
_
+:
2
1 (:) = 4 1
_
:
2
_
+:
2
49
1 (:) = 1
_
:
2
_
+ 2
n
1 (:) = 2
n
1
_
:
2
_
+:
n
1 (:) = 16 1
_
:
4
_
+:
1 (:) = 2 1
_
:
2
_
+:log :
1 (:) = 2 1
_
:
2
_
+
:
log :
1 (:) = 2 1
_
:
4
_
+:
0:51
1 (:) =
1
2
1
_
:
2
_
+
1
:
1 (:) = 16 1
_
:
4
_
+:!
1 (:) =
_
2 1
_
:
4
_
+ log :
1 (:) = 3 1
_
:
2
_
+:
1 (:) = 3 1
_
:
3
_
+
_
:
1 (:) = 4 1
_
:
2
_
+c:
1 (:) = 3 1
_
:
4
_
+:log :
1 (:) = 3 1
_
:
3
_
+
:
2
1 (:) = 4 1
_
:
2
_
+
:
log :
1 (:) = 64 1
_
:
8
_
:
2
log :
1 (:) = 7 1
_
:
3
_
+:
2
1 (:) = 4 1
_
:
2
_
+ log :
1 (:) = 1
_
:
2
_
+:(2 cos :)
Rjeenje.
1 (:) = 3 1
_
:
2
_
+:
2
= 1 (:) = (:
2
) (slucaj 3)
1 (:) = 4 1
_
:
2
_
+:
2
= 1 (:) = (:
2
log :) (slucaj 2)
50
1 (:) = 1
_
:
2
_
+ 2
n
= 1 (:) = (:
2
) (slucaj 3)
1 (:) = 2
n
1
_
:
2
_
+:
n
= ne primjenjuje se (c nije konstanta)
1 (:) = 16 1
_
:
4
_
+: = 1 (:) = (:
2
) (slucaj 1)
1 (:) = 2 1
_
:
2
_
+:log : = 1 (:) =
_
:log
2
:
_
(slucaj 2)
1 (:) = 2 1
_
:
2
_
+
:
log :
=ne primjenjuje se (nepolinomijalna razlika izmeu , (:)
i :
log
b
a
)
1 (:) = 2 1
_
:
4
_
+:
0:51
= 1 (:) = (:
0:51
) (slucaj 3)
1 (:) =
1
2
1
_
:
2
_
+
1
:
=ne primjenjuje se (c < 1)
1 (:) = 16 1
_
:
4
_
+:! = 1 (:) = (:!) (slucaj 3)
1 (:) =
_
2 1
_
:
4
_
+ log : = 1 (:) = (
_
:) (slucaj 1)
1 (:) = 3 1
_
:
2
_
+: = 1 (:) =
_
:
lg 3
_
(slucaj 1)
1 (:) = 3 1
_
:
3
_
+
_
: = 1 (:) = (:) (slucaj 1)
1 (:) = 4 1
_
:
2
_
+c : = 1 (:) = (:
2
) (slucaj 1)
1 (:) = 3 1
_
:
4
_
+:log : = 1 (:) = (:log :) (slucaj 3)
1 (:) = 3 1
_
:
3
_
+
:
2
= 1 (:) = (:log :) (slucaj 2)
1 (:) = 4 1
_
:
2
_
+
:
log :
= 1 (:) = (:
2
) (slucaj 1)
1 (:) = 64 1
_
:
8
_
:
2
log : =ne primjenjuje se jer , (:) nije pozitivna
1 (:) = 7 1
_
:
3
_
+:
2
= 1 (:) = (:
2
) (slucaj 3)
1 (:) = 4 1
_
:
2
_
+ log : = 1 (:) = (:
2
) (slucaj 1)
1 (:) = 1
_
:
2
_
+:(2 cos :) =Ne primjenjuje se. Pripada slucaju 3 ali je naruen
uslov regularnosti (pretpostavimo da je : = 2:/ gdje je / neparan i proizvoljno
veliki. Za svaki takav izbor od : pokazuje se da je c _ 3,2 pa je naruen uslov
regularnosti)
U primjeru 7 razlika izmeu , (:) i :
log
b
a
se moze prikazati kao kolicnik
51
, (:)
:
log
b
a
=
:
log :
:
log
2
2
=
:
: log :
=
1
log :
Jasno je da je
1
log :
< :
"
za bilo koje 0. Stoga razlika nije polinomijalna i ne moze
se primijeniti Master teorema.
8.3 Zadaci za samostalni rad
Zadatak. Neka je
c
0
= 1; c
k
= /c
k1
+ 1,/. / = 1. 2. . .
Za dati prirodni broj : naci c
n
.
Zadatak. Neka je

1
=
2
= 0;
3
= 1.5

i
=
i + 1
i
2
+ 1

i1

i2

i3
Za dati prirodni broj : naci
n
.
Zadatak. Neka je
r
0
= c. r
1
= d
r
k
= r
k1
+: r
k2
+/. / = 1. 2. ...
Za date realne brojeve . :. c. d. / i prirodni broj : izracunati r
n
.
Zadatak. Neka je
n
1
= n
2
= 0.
1
=
2
= 1
n
i
=
n
i1
n
i2

i1

i2
1 +n
2
i1
+
2
i1

i
=
n
i1

i1
[n
i2
+
i1
[ + 2
. i = 3. 4. ...
Za dati prirodni broj : naci
n
.
Zadatak. Neka je
c
0
= c
1
= 1
c
i
= c
i2
+
c
i1
2
i1
. i = 2. 3. ...
Naci proizvod c
0
c
1
... c
14
.
Zadatak. Neka je
c
1
= /
1
= 1
c
k
=
1
2
_
_
/
k1
+
1
2
_
c
k1
_
/
k
= 2c
2
k1
+/
k1
. / = 2. 3. ...
52
Za dati prirodni broj : naci sumu
n

k=1
c
k
/
k
.
Zadatak. Neka je
r
1
=
1
= 1.
r
i
= 0.3 r
i1

i
= r
i1
+
i1
. i = 2. 3. ...
Za dati prirodni broj : naci sumu
n

i=1
r
i
1 +[
i
[
.
Zadatak. Neka je
c
1
= /
1
= 1
c
k
= 3/
k1
+ 2c
k1
/
k
= 2c
k1
+/
k1
. / = 2. 3. ...
Za dati prirodan broj : naci sumu
n

k=1
2
k
(1 +c
2
k
+/
2
k
) /!
Zadatak. Neka je
c
1
= n. /
1
=
c
k
= 2/
k1
+c
k1
/
k
= 2c
2
k1
+/
k1
. / = 2. 3. ...
Za date realne brojeve n. i prirodni broj : naci sumu
n

k=1
c
k
/
k
(/ + 1)!
Zadatak. Neka je
r
1
= r
2
= r
3
= 1
r
i
= r
i1
+r
i3
. i = 4. 5. ...
Naci sumu
100

i=1
r
i
2
j
.
Zadatak. Dat je cijeli broj : 1. Naci najveci cijeli broj / za koji je 4
k
< :.
Zadatak. Dat je prirodni broj :. Naci najmanji broj oblika 2
r
koji prelazi :.
Zadatak. Dat je prirodan broj :. Izracunati
1 2 + 2 3 4 +... +: (: + 1) ... 2:
Zadatak. Izracunati
53
1
1 +
1
3 +
1
5 +
1
...
...
101 +
1
103
Zadatak. Za dati realni broj r ,= 0 izracunati
r
r
2
+
2
r
2
+
4
r
2
+
8
...
... r
2
+
256
r
2
Zadatak. Za dati prirodni broj : i realni broj t izracunati
(2t)
n
:!!
_
:
2
_
[n=2]
.
Zadatak. Niz Fibonacijevih brojeva n
0
. n
1
. n
2
. ... se formira po pravilu n
0
= 0. n
1
=
1. n
i
= n
i1
+n
i2
.
Za dati prirodan broj : izracunati prvih : Fibonacijevih brojeva
Niz ,
0
. ,
2
. ... se formira po pravilu ,
0
= 0. ,
1
= 1. ,
i
= ,
i1
+ ,
i2
+ n
i2
. Za dati
prirodan broj : generisati niz ,
0
. ,
1
. ,
2
. .... ,
n
.
Zadatak. Za zadati prirodni broj : izracunati :!.
Zadatak. Formirati niz Fibonacijevih brojeva
koristeci se neposredno formulom 1
n
= 1
n1
+1
n2
.
koristeci se formulama za :-ti clan
n
k
=
1
_
5
_
1 +
_
5
2
_
n

1
_
5
_
1
_
5
2
_
n
Zadatak. Dati su pozitivni cijeli brojevi :. :. Izracunati (:. :) gdje je
(:. :) =
_
_
_
_
_
:+ 1 : = 0
(: 1. 1) : ,= 0. : = 0
(: 1. (:. :1)) : 0.: 0
_
_
54
Zadatak. Niz polinoma je zadat na sljedeci nacin 1
0
(r) = 1. 1
1
(r) = r. 1
k
(r) =
2r1
k1
(r) 1
k2
(r). Formirati niz 1
2
. 1
3
. .... 1
8
.
Zadatak. Niz polinoma je zadat na sljedeci nacin H
0
(r) = 1. H
1
(r) = r. H
k
(r) =
rH
k1
(r) (/ 2) H
k2
(r).
Naci polinome H
2
. .... H
6
Za date realne brojeve c
1
. .... c
6
formirati polinom c
0
H
0
(r) +... +c
6
H
6
(r)
Za dati realni broj c izracunati H
0
(c) +... +H
6
(c)
55
9 Tjuringova maina
9.1 Uvod
Digitalni racunar se na apstraktnom nivou obicno prikazuje kao cjelina sastavljena od
procesora, memorije i ulazno-izlaznih ureaja. Procesor iz memorije pribavlja naredbe
i podatke nad kojima se vri obrada u skladu sa znacenjem naredbi a dobijeni rezultati
se vracaju u memoriju. Podaci koji ce biti obraeni se, preko ulazno-izlaznih ureaja,
unose u memoriju odnosno iz memorije se preuzimaju rezultati obrade i prikazuju na
odgovarajuci nacin. Komunikacija djelova racunara se obavlja preko magistrala.
Tjuringova maina je preteca ovakvog modela racunara, pri cemu su neka svojstva ideali-
zovana. To se odnosi na memoriju za koju se pretpostavlja da je potencijalno beskonacna.
Preciznije, na pocetku izvravanja Tjuringove maine zauzet je samo konacan broj mem-
orijskih registara, a isto vazi i u svakom koraku izracunavanja. Ne postoji ogranicenje
koliki je taj konacan broj registara. U svakom koraku izracunavanja moguce je i zahti-
jevati novi, do tada neiskoriteni memorijski registar i svaki takav zahtjev se ispunjava.
Sa druge strane, Tjuringova maina je restrikcija koncepta savremenog racunara u smislu
operacija koje je u stanju izvravati a koje su elementarne. Zanimljivo je da su te op-
eracije ipak dovoljne za opisivanje proizvoljnih algoritama. Njihova prednost u odnosu
na bogatije programske jezike je upravo u jednostavnosti koja olakava analizu.
9.2 Alan Tjuring
Alan Mathison Turing je bio engleski matematicar, logicar, kriptoanaliticar i kompjuter-
ski naucnik. Ostvari je veliki uticaj na kompjutersku nauku time to je dao formal-
izaciju koncepata "algoritma" i "izracunavanja" putem Tjuringove maine, koja je odi-
grala znacajnu ulogu u kreiranju modernih kompjutera. Za Tjuringa se smatra da je
otac kompjuterske nauke i vjetacke inteligencije. U zickom smislu, imao je mnoge
karakteristike koje upucuju da je imao Aspergerov sindrom
3
.
Tokom drugog svjetskog rata Tjuring je radio za vladinu kolu za kriptograju (GCCS)
u Bletchley Park, Britanskom centru za deifrovanje. Vremenom je postao voa sekcije
koja je bila odgovorna za razbijanje ifara njemacke mornarice. Razvio je niz tehnika za
razbijanje njemackih ifara, ukljucujuci i metod Bombe, elektromehanicke maine koja je
mogla pronaci postavke maine Enigma.
Nakon rata je radio za National Physical Laboratory gdje je kreirao jedan od prvih diza-
jna racunara sa pohranjenim programom, ACE. Godine 1948 se doao u Max Newmans
Computing Laboratory na Manchester University gdje je pomagao u razvoju Manchester
kompjutera i gdje se zainteresovao za matematicku biologiju. Napisao je clanak o hemi-
jskoj osnovi morfogeneze i predvidio oscilatorne hemijske reakcije kao to su reakcija
Bjelousov-

Zabotinski (Belousov-Zhabotinsky oscilating reaction) koja je prvi put uocena


1960. godine.
3
To je poremecaj iz spektra autizma (autism spectrum disorder - ASD) kojeg karakteriu znacajne
tekoce u socijalnoj interakciji, skupa sa ogranicenim i repetitivnim obrascima ponaanja i interesa.
Od drugih tipova autizma se razlikuje po relativno visokom stepenu ocuvanja lingvistickog i kognitivng
razvoja. Mada se ne uzima kao element dijagnoze, cesto se pojavljuju slucajevi zicke "trapaovosti" i
atipicnog koritenja jezika.
56
Tjuringva homoseksualnost je rezultirala kriminalnim progonom godine 1952 kada je ho-
moseksualnost bila ilegalna u Velikoj Britaniji. Prihvatio je tretman zenskim hormonima
(hemijska kastracija) kao alternativu za zatvor. Umro je 1954, nekoliko sedmica prije
svog 42-og roendana, od trovanja cijanidom (gljivama). Istraga je utvrdila da je to
bilo samoubistvo; njegova majka i neki drugi su vjerovali da je umro nesretnim slucajem.
Dana 10.09.2009. godine, nakon Internetske kampanje, Britanski premijer Gordon Brown
je objavio javno izvinjenje u ime Britanske vlade zbog nacina na koji je Alan Tjuring bio
tretiran nakon rata.
9.3 Alfabet
Svaki problem se izrazava u nekom jeziku. Alfabet je skup znakova koji su nedjeljive
cjeline. Rijec na nekom alfabetu je bilo koja konacna sekvenca znakova tog alfabeta.
Sekvenca od nula znakova se naziva prazna rijec. Rijeci se razdvajaju znakom blanko
koji se ne smatra dijelom alfabeta vec pomocnim simbolom.
Jezik je neki poskup skupa svih rijeci odgovarajuceg alfabeta. Rijec t je podrijec rijeci
ako postoje, mozda i prazne, rijeci n i tako da je = nt.
Alfabet je obicno konacan skup znakova jer sve to se moze iskazati beskonacnim pre-
brojivim alfabetom c
1
. c
2
. ... moze se iskazati i najjednostavnijim, unarnim, alfabetom
= 1. Rijeci alfabeta 1. 11. 111. ... se mogu identikovati sa znacima proizvoljnog
beskonacnog alfabeta. Ako se posebno ne naglasi, u nastavku ce biti koriten unarni
alfabet = 1. Pored simbola 1 ce biti koriten i blanko znak za cije oznacavanje ce,
radi preglednosti, biti koriten znak 0.
9.4 Neformalni opis Tjuringove maine
Tjuringova maina se sastoji od :
Trake, koja je podijena u celije, memorijske registre, koja se neograniceno pruza
lijevo i desno; broj celija (tj. duzina trake) je neogranicen; sadrzaj svake celije je ili
znak 1 ili blanko znak (znak 0),
Glave, koja se uvijek nalazi nad tacno jednom celijom trake i moze:
- procitati sadrzaj celije nad kojom se nalazi i
- upisati u celiju nad kojom se nalazi znak 1 ili 0 (blanko znak, tj. obrisati celiju)
ili se pomjeriti za jedan korak u lijevo ili u desno u odnosu na trenutnu poziciju,
Indikatora stanja maine
Tjuringova maina se u svakom trenutku nalazi u tacno jednom od konacno mnogo stanja
koje se eventualno mijenja nakon svakog koraka izracunavanja. Skup svih stanja maine
ce biti oznacen sa o =
1
.
2
. .... Izvravanje maine se izvodi pod dejstvom programa
koji cini neki konacan niz naredbi. Svaka naredba je cetvorka oblika

i
: o
j
57
gde su
i
i
j
neka stanja iz skupa o, : je znak nad kojim se nalazi glava maine a
o 1. 0. 1. 1 je oznaka operacije. U svakom koraku rada maina analizira stanje u
kojem se nalazi i sadrzaj celije nad kojom je glava a zatim izvrava naredbu koja ima
odgovarajuce vrijednosti parametara
i
i :. Efekat izvrenja naredbe je dvojak. Najprije
se, u zavisnosti od vrijednosti parametra o, obavi:
Ako je o = 1 tada se u celiju nad kojom se nalazi glava upisuje znak 1,
Ako je o = 0 tada se u celiju nad kojom se nalazi glava upisuje znak 0,
Ako je o = 1 tada se glava pomjera ulijevo za jednu celiju
Ako je o = 1 tada se glava pomjera udesno za jednu celiju
Nakon toga maina mijenja stanje i prelazi u stanje
j
.
Primjeri naredbi su :

5
0 1
17
: Ako se maina nalazi u stanju
5
a glava nad znakom blanko u celiju se
upisuje znak 1 i prelazi se u stanje
17
;

1
0 0
2
: Ako se maina nalazi u stanju
1
a glava nad znakom blanko u celiju se
upisuje blanko znak i prelazi u stanje
2
. Ovakva naredba sluzi samo za promjenu
stanja maine;

0
1 1
0
: Ako se maina nalazi u stanju
0
a glava nad znakom 1 glava se pomjera
ulijevo a maina ostaje u istom stanju
Ako se zeli da maina radi deterministicki program smije sadrzavati samo jednu naredbu
za svaku kombinaciju stanja
i
i sadrzaja celije : nad kojom je glava. Naprimjer u
programu se ne smiju pojaviti sljedece naredbe :

4
1 1
5

4
1 1
2
jer im se poklapaju vrijednosti parametara
i
i : a vrijednosti parametara o i
j
razlikuju.
U slucaju nedeterministickih maina ovakav zahtjev ne postoji.
Konvencija je da se stanje
0
o zove pocetno stanje. Rijec se na traci prikazuje kao
neprekidan niz celija koje sadrze znak 1 a sa lijeve i desne strane rijeci se nalazi najmanje
po jedan znak blanko odnosno znak 0. U pravilu, na pocetku i kraju glava maine se
nalazi iznad prve celije slijeva koja sadrzi znak 1. Skup stanja o ce biti proiren novim
stanjem
z
koje ce se zvati zavrno stanje. Maina u tom stanju prekida izvrenje.
58
9.5 Formalni opis Tjuringove maine
Neka su :
o : konacan skup stanja

0
: pocetno stanje,
0
o

z
: zavrno stanje,
z
o
= 0. 1 alfabet
o : (o
z
) ( ' 1. 1) o
Tada se Tjuringova maina denie kao ureena petorka (o.
0
.
z
. . o).
Opis trake je preslikavanje 1 : Z tako da ako je u celiji sa indeksom . upisan znak
0 ili 1 tada je 1 (.) = 0 ili 1 (.) = 1.
Konguracija Tjuringove maine ` = (o.
0
.
z
. . o) je trojka (1. . c) gdje su:
1 : opis trake
o : tekuce stanje
c Z : broj celije nad kojom se nalazi glava
Naredba Tjuringove maine ` = (o.
0
.
z
. . o) je cetvorka (
i
. :. o.
j
) gdje je o (
i
. :) =
(o.
j
). Preslikavanje o se naziva program. Pri tome vazi

i
=
0
i
. : = :
0
= o (
i
. :) = o (
0
i
. :
0
)
Racunski korak Tjuringove maine ` = (o.
0
.
z
. . o) za naredbu 1 = (
i
. :. o.
j
) je
svaki par konguracija ((1
0
.
0
. c
0
) . (1
00
.
00
. :
00
)) za koje vazi:

i
=
0
1
0
(c
0
) = :

j
=
00
Ako je operacija o = 1 vazi :
- c
0
= c
00
- 1
0
i 1
00
se poklapaju osim u c
00
gdje je 1
00
(c
00
) = 1
Ako je operacija o = 0 vazi
- c
0
= c
00
- 1
0
i 1
00
se poklapaju osim u c
00
gdje je 1
00
(c
00
) = 0
59
Ako je operacija o = 1 vazi
- c
0
1 = c
00
- 1
0
i 1
00
se poklapaju
Ako je operacija o = 1 vazi
- c
0
+ 1 = c
00
- 1
0
i 1
00
se poklapaju
Da je ((1
0
.
0
. c
0
) . (1
00
.
00
. :
00
)) racunski korak naredbe 1 oznacava se sa (1
0
.
0
. c
0
)
I
(1
00
.
00
. c
00
).
Izracunavanje za Tjuringovu mainu ` = (o.
0
.
z
. . o) i program 1 opisan funkcijom
o je niz konguracija (1
0
.
0
. c
0
), (1
1
.
1
. c
1
), ... , (1
m
.
m
. c
m
) tako da :
(1
0
.
0
. c
0
)
I
1
(1
1
.
1
. c
1
) za neku naredbu 1
1
(programa 1) i stanje
0
=
0
(\/ N) (0 < / < :1)
__
1
k1
.
k1
. c
k1
_

I
k
_
1
k
.
k
. c
k
__
(1
m1
.
m1
. c
m1
)
I
m
(1
m
.
m
. c
m
), za
m
=
m

_
\/ = 1. :1
_ _

k
,=
z
_
c
0
= 0. (\i < 0) (1
0
(i) = 0)
(: 0) (/
1
. .... /
n
) (c
0
_ /
1
< /
2
< ... < /
n
) tako da vazi
- (\i. c
0
_ i _ /
1
) (1
0
(i) = 1. 1
0
(/
1
+ 1) = 0)
- (\i. /
1
+ 1 _ i _ /
2
) (1
0
(i) = 1. 1
0
(/
2
+ 1) = 0)
- ...
- (\i. ) (/
n1
+ 1 _ i _ /
n
) (1
0
(i) = 1)
- (\i. /
n
< i) (1
0
(i) = 0)
1
m
(c
m
) = 1, i (\i < c
m
) (1
m
(i) = 0)
/ _ c
m
:
- (\i. c
m
_ i _ /) (1
m
(i) = 1)
- (\, /) (1
m
(,) = 0)
Varijante Tjuringove maine su :
TM sa bogatijim alfabetom
TM sa vie zavrnih stanja (u kojem svako od njih simbolizuje rezultat rjeavanja
problema)
TM sa lijevo ogranicenom trakom
TM sa vie traka i glavom za svaku od njih
TM sa jednom trakom i vie glava nad njima
60
TM sa 2D trakom koja je beskonacna po obje dimenzije
TM koje dozvoljavaju u istoj naredbi upis u celiju i pomjeranje glave
Nedeterministicke TM (o je relacija a ne funkcija tj. moze postojati vie naredbi
za isto stanje i sadrzaj celije)
Nijedna od ovih varijanti ne proiruje klasu Tjuring izracunljivih funkcija (mogu izracu-
nati samo ono to moze i osnovna verzija TM)
Izracunljiva funkcija je samo ona koja je Tjuring izracunljiva.
9.6 Modeli izracunljivost
U ovom dijelu su tekstovi o modelima izracunljivosti koje su napisali studenti II godine
matematike na PMF u Tuzli kao svoje seminarske radove.
9.6.1 Nedetrministicka Tjuringova maina
Varijante Tjuringove maine. Posmatraju se Tjuringove maine u kojima:
alfabet kojim se zapisuje sadrzaj celija trake ne mora biti unarni,
pored zavrnog stanja
z
uvode se i neka specijalna zavrna stanja, recimo
da
i

ne
koja, intuitivno, znace pozitivan, odnosno, negativan odgovor na postavljeni
problem,
dozvoljena je traka koja je beskonacna samo na jednu stranu, tj. postoji krajnja
lijeva celija, dok se na desno traka pruza neograniceno,
umjesto samo jedne postoji vie traka, a za svaku traku postoji posebna glava,
nad jednom trakom postoji vie glava umesto samo jedne,
traka je dvodimenzionalna, a ne jednodimenzionalna, tj. traka podsjeca na beskon-
acnu ahovsku plocu,
u jednoj naredbi maine moguce je i upisati znak u celiju i pomjerati
glavu,
ne vazi zahtev za determinisanocu, tj. dozvoljeno je da postoje naredbe koje
odgovaraju istom stanju i znaku uceliji nad kojom se nalazi glava, a koje se razlikuju
po dejstvu (operaciji koja se izvrava i/ili stanju u koje se prelazi) itd.
Zanimljivo je da u smislu izracunljivosti gotovo sve od ovih varijanti Tjuringove maine
odgovaraju istoj klasi funkcija, tj. klasi Tjuring-izracunljivih funkcija, kao i osnovna
verzija maine. Izuzetak predstavljaju neki slabiji, restriktivni slucajevi: recimo, maina
cija traka je ogranicena sa jedne strane i koristi unarni alfabet ili maina koja ima samo
dva stanja i koristi alfabet od dva znaka. Ekvivalencija varijanti Tjuringove maine se
dokazuje tako to se pokaze da za svaki program P za neku od varijanti Tjuringove
61
maine postoje programi za preostale varijante koji simuliraju izvrenje programa 1 i
izracunavaju istu funkciju. Izbor varijante Tjuringove maine zavisi od primjene kojom
se bavimo.
Recimo, u analizi slozenosti algoritama se koristi vie varijanti maina zavisno od klase
slozenosti koja se proucava.
Nedeterministicka Tjuringova maina. Kod nedeterministicke Tjuringove maine
zahtjev da za svaku kombinaciju tekuceg stanja i znaka bude predviena samo jedna
akcija ne postoji, odnosno za tekuce stanje i simbol u celiji iznad koje se nalazi glava
maine, moze postojati vie razlicitih operacija i/ili stanja u koja maina prelazi nakon
izvravanja naredbe programa.
U izvravanju nedeterministicke Tjuringove maine postoji svojevrsna mogucnost izbora:
u slucaju da za neko stanje q neki znak s postoji vie mogucih naredbi treba izabrati
neku od njih i nastaviti izvravanje, to je ematski prikazano kao dio jednog drveta.
Grananje u drvetu je konacno, to znaci da u svakom koraku izvravanja postoji samo
konacno mnogo opcija za izbor, dok grane predstavljaju moguce redoslijede izvravanja
programa. Nedeterministicke maine su pre svega pogodne za davanje odgovora da ili
ne na pitanja oblika da li za ulazne podatke vazi . . . ? Imajuci u vidu ideju o uvoenju
novih stanja
da
i
ne
zaustavljanje u nekom od ovih stanja ima znacenje pozitivnog,
odnosno negativnog, odgovora. Snaga, odnosno na jeziku savremenih racunara - brzina,
nedeterministickih Tjuringovih maina je posledica sledece asimetricne konvencije:
maina potvrdno odgovara na pitanje ako se bar jedno od mogucih izracunavanja
zavrava u stanju
da
, dok jedino okoncanje svih mogucih izracunavanja u stanju

ne
znaci da je odgovor ne i
ako ni jedno izracunavanje ne dovodi do stanja
da
i bar jedno izracunavanje ne
dovodi ni do kog zavrnog stanja, nedeterministicka maina divergira.
Na osnovu ovog dogovora, nedeterministicka maina se moze zamisliti kao vieproce-
sorski sistem koji se ponaa na sljedeci nacin. U svakom koraku svaki od procesora
kreira onoliko novih procesora koliko ima razlicitih konguracija u koje taj procesor moze
preci izvravanjem tekuce naredbe. Ako mu u nastavku izvravanja bilo koji od njegovih
potomaka vrati informaciju o potvrdnom odgovoru, procesor tu informaciju prosleuje
svom neposrednom pretku. Negativan odgovor se prosleuje samo ako je dobijen od svih
neposrednih potomaka. Zapravo, svaki procesor izracunava disjunkciju odgovora svojih
potomaka. Ovakav model maine je pogodan za rjeavanje nekih slozenih problema.
Na primer, pretpostavimo da zelimo ispitati da li je neki prirodan broj : slozen ili prost.
Obicnom Tjuringovom mainom problem bi se mogao rijeiti na sljedeci nacin: dijelili
bismo broj svim prirodnim brojevima izmeu 2 i :,2 i na osnovu toga dali odgovor. U
slucaju nedeterministicke Tjuringove maine na jednom mestu bismo imali mogucnost
izbora broja kojim dijelimo broj : pa ako je : slozen, a izabrani broj djelilac, mogli
bismo dati odgovor u jednom koraku, to bi bio znacajan dobitak u odnosu na determin-
isticki postupak. Lako je uociti da ovaj postupak nije realan, u smislu da izbor djelioca
podrazumeva da mi vec znamo da je : slozen, tj. da nam je poznat bar jedan njegov
62
cinilac. Meutim, i pored toga, nedeterministicka Tjuringova maina se moze simuli-
rati deterministickom mainom, tako da se izrazajnost u smislu onoga ta maina moze
odgovoriti ne mijenja.
Pretpostavimo da je `
1
nedeterministicka Tjuringova maina. Odgovarajuca determin-
isticka Tjuringova maina `
2
ce sistematski prelaziti sve moguce redoslijede izvravanja
maine `
1
, najprije duzine 1, pa duzine 2 itd. Ovo obezbjeuje da ni jedno moguce
konacno izvravanje nece biti preskoceno. Zato, ako bi se maina `
1
u nekom trenutku
izvravanja nala u stanju
da
to isto ce prije ili poslije biti slucaj i sa mainom `
2
. Ako
svi moguci redoslijedi izvravanja maine `
1
dovode do stanja
ne
i maina `
2
ce se
naci u tom stanju kada iscrpi sve mogucnosti. Konacno ako maina `
1
divergira za date
ulazne podatke x i maina M2 se nece zaustaviti.
Deterministicka maina `
2
ce imati tri trake: prva traka uvijek sadrzi ulazni podatak i
nikada se ne mijenja, na drugoj traci ce se simulirati izvravanje maine `
1
, a na trecoj ce
se, kao na nekom steku, pamtiti niz brojeva koji predstavljaju prikaz izabranih pravaca
u svim mogucim trenucima izbora naredbe koja se izvrava. Na pocetku izvravanja
maine `
2
ulazni podatak se nalazi na prvoj traci, dok su preostale dvije trake prazne.
U osnovnom ciklusu rada maina kopira sadrzaj prve na drugu traku i koristeci sadrzaj
trece trake, kao uputstvo za redosled koraka, simulira jedan deterministicki redoslijed
izvravanja maine M1.
Ocigledno je da deterministicka maina `
2
u najgorem slucaju bar jednom posjecuje svaki
cvor drveta koje prikazuje izvravanje nedeterministicke maine `
1
. Ovih cvorova moze
biti eksponencijalno vie nego to je duzina najkraceg moguceg izracunavanja maine `
1
koje dovodi do stanja
da
, ako takvo uopte postoji.
Teorema. Za datu nedeterministicku Tjuringovu mainu `
1
sa /-traka moze se konstru-
isati deterministicka Tjuringova maina `
2
sa jednom trakom koja simulira rad maine
`
1
. Duzina rada maine `
2
je ogranicena eksponencijalnom funkcijom duzine rada
maine `
1
.
Primjeri:
Zadatak 1:
Dat je skup o = c
1
. c
2
. .... c
n
. Odrediti postoji li skup 1 _ o takav da

a
i
2T
c
i
=

a
i
2SnT
c
i
Rjeenje: Prvo postavljamo problem u obliku koji Tjunringova maina moze razumjeti.
Za to postavljamo jezik
1 =
_
_
_
c
1
#c
2
#...#c
n
: 1 _ o .

a
i
2T
c
i
=

a
i
2SnT
c
i
_
_
_
Sada pretpostavimo da imamo 2 deterministricke Tjuringove maine
C kopir maina koja kopira odreeni string na odreeno mjesto
S maina sumiranja koja sumira odreene brojeve.
63
NDTM sa jezikom L:
1. Stavi S na traku
2. Sumiraj brojeve u ulazu; Rezultat cemo nazvat
1
3. Dodaj na kraj $
4. Prilikom pomjeranja s lijeva prema $
nedeterministicki kopiraj sve c
i
1
dodaj na kraj #
5. Sumiraj sve kopirane brojeve; Rezultat cemo nazvat
2
6. Zavri ako je
1
= 2
1
Zadatak 2:
Dat je graf (G = (\. 1)) i prirodan broj / 0. Odrediti postoji li C _ \ tako da je:
[C[ _ /
svaka dva vrha su susjedna
Rjeenje:
Probem se prezetira preko jezika
1 = (G. /) : G ima clicque velicine q _ /
Pretpostavimo da ` _ o, tako da se za svaka 2 vrha kaze da li su susjedni ili ne.
NDTM sa jezikom L:
1. Postavi (G,k) na traku
2. Na kraju dodaj $
3. Pomjerajuci se s lijeva prema $
Nedeterministicki izabrati neke vrhove
i
\ (G)
4. Provjerit da li je selektirani broj vrhova _ /
5. Za svaka 2 vrha ispitati da li su susjedna
6. Zavriti ako su svi vrhovi susjedni.
Tekst uradio : Admir Junuzovic
64
9.6.2 Neogranicena registarska maina
Neogranicena registarska (URM) maina opisana je 60-ih godina dvadesetog stoljeca. Za
razliku od Turingove maine, bliza je konceptu na kojem se danas zasnivaju racunari. U
sutini, registarska maina predstavlja model onoga to se u racunarstvu naziva procesor,
a instrukcije odgovaraju mainskom jeziku tog procesora.
URM se sastoji od beskonacne trake podijeljene u registre ili celije numerisane prirodnim
brojevima. Svaki registar ima svoju adresu. Registri mogu sadrzavati prirodne brojeve i
nulu.
Maina radi u skladu s programom koji predstavlja ureeni skup instrukcija. Program
zapocinje od prve naredbe nastavljajuci rad redom, osim u slucaju posebne naredbe kada
moze doci do skoka. Prekida se prelaskom na nepostojecu naredbu.
Najceci razmatrani model maine je onaj koji raspoznaje cetiri tipa instrukcija.
Z(m) (ili CLR (eng. clear)) postavlja nulu u registar m;
S(m) ( ili INC (eng. increment)) uvecava sadrzaj registra m za 1;
T(m,n) (ili TR (eng. transfer)) u registar n upisuje sadrzaj registra m;
J(m,n,q) (ili JNE (eng. jump if not equal) u slucaju da su sadrzaji registra m i n
razliciti prelazi na q-tu naredbu (ova instrukcija je zasluzna za mogucnost pravljenja
petlji);
Primjer 1.
Napisati program koji u registar R1 upisuje vrijednost 3.
1. Z(1)
2. S(1)
3. S(1)
4. S(1)
Objanjenje: U prvom koraku u registar R1 upisujemo nulu,a zatim s instrukcijom S(1)
povecavamo tri puta sadrzaj registra R1.
Primjer 2.
Napisati program koji sabira sadrzaj dva registra R1 i R2 i upisuje rjeenje u R1.
1. Z(3)
2. S(1)
3. S(3)
4. J(3,2,2)
Objanjenje: U ovom slucaju R3 ima ulogu brojaca.U prvom koraku njega stavljamo na
nulu, zatim u narednim koracima registrima R1 i R3 povecavamo sadrzaj za jedan sve
dok registri R3 i R2 ne budu imali isti sadrzaj, prilikom cega se program zaustavlja.
Primjer 3.
Napisati program koji sabira sadrzaj dva registra R1 i R2 i upisuje rjeenje u R3.
1. T(1,3)
2. Z(4)
3. S(3)
4. S(4)
5. J(4,2,3)
65
Objanjenje: Prvo kopiramo sadrzaj iz R1 u R3. R4 igra ulogu brojaca pa ga postavljamo
na nulu. Peti korak pomaze da uvecamo sadrzaj registra R3 onoliko puta koliko iznosi
R2.
Tekst pripremila : Bojana Stojanovic
9.6.3 While i for petlje (dijagrami toka)
Denicija: Dijagram toka je slikovni prikaz algoritma ili proces, koji je razvijen od strane
Herman Goldstine i John von Neumann u 1940. Drugim rijecima, dijagram je formaliziran
gracki prikaz u logickom slijedu, rad ili proizvodni proces, ustrojna shema, struktura ili
sl. Protok-karte se vrlo lako razumiju. Dakle, oni su korisni alati za komunikaciju kako
procesi rade i za dokumentiranje jasno kako odreeni posao je obavljen. Rekli smo vec
da se algoritmi najcece zapisuju kao pseudokod i dijagram toka. Takav nacin zapisivanja
ima nekoliko prednosti pred pseudokodom. Zapisivanje se vri meunarodno dogovorenim
simbolima i ne ovisi o govornom jeziku onoga koji sastavlja algoritam. Gracki prikaz je
jednostavan, pregledan, lako se pronalaze greke. Nadalje, problem se moze jednostavno
analizirati, usporediti s nekim drugim problemom, skratiti vrijeme pronalazenja rjeenja.
Ovaj gracki prikaz moze dati korak-po-korak rjeenje za odreeni problem.
Dijagram toka se moze koristiti za sljedece svrhe:
Denirati i analizirati procese
Graditi korak-po-korak sliku procesa analize, rasprave, ili komunikacije
Denirati, standardizirati ili pronaci podrucja za poboljanje u procesu
Prednosti koritenja dijagrama toka su:
Komunikacija: dijagram toka na bolji nacin prikazuje logiku sistema za sve zain-
teresirane
Ucinkovita analiza: Uz pomoc dijagrama toka, problem se moze analizirati na
ucinkovitiji nacin
Dokumentacija uredna: Program dijagrama toka moze posluziti kao dobar nacin
dokumentacije koja je potrebna za razne svrhe
Ucinkovito kodiranje: dijagram toka djeluje kao vodic ili nacrt tokom sistema anal-
ize i programa razvojnoj fazi
Pravilno otklanjanje gresaka: dijagram pomaze u procesu otklanjanja gresaka
Osnovni simboli dijagrama toka :
Bez obzira koji programski jezik koristimo, analizom razlicitih algoritama dolo se do
zakljucka da za predstavljanje algoritma moramo koristiti slijedece semanticke strukture:
- za ponavljanje iste vrste aktivnosti dok se ne postigne zadani uvjet
66
while (uvjet) do (aktivnost)
to je ponekad zgodnije izraziti tzv. for petljom ako je unaprijed poznat broj pon-
avljanja
for (pocetak-kraj) do (aktivnost)
While petlja
U vecini racunarskih programskih jezika, while petlja je naredba upravljanja tokom koja
doputa ponovno izvrsavanje koda u ovisnosti o danom bulovskom uvjetu. While petlja
se moze shvatiti kao ponavljajuca if naredba.
While petlja se sastoji od bloka koda i uvjeta. Uvjet je prvo evaluiran - ako je uvjet
logicka istina, kod se unutar bloka izvrava. Ovo se ponavlja sve dok uvjet ne postane
lazan. S obzirom da while petlja provjerava uvjet prije izvrenja bloka koda, upravljacka
je struktura cesto poznata kao pred-test petlja. While petlja se rijetko koristi u slucaju
kada je broj ponavljanja petlje unaprijed poznat (kao u primjeru 1. ).Tada je pogodnija
for petlja. Petlju while cemo najcece koristiti kada se broj ponavljanja ne moze unaprijed
znati,
For petlja
U racunarstvu, for petlja je naredba programskog jezika koja doputa ponovno izvravanje
koda. For petlja se klasicira kao iterativna naredba. Za razliku od drugih petlji, poput
while petlje, for petlja se razlikuje postojanjem eksplicitnog brojaca petlje ili varijable
petlje. Ovo doputa tijelu petlje (kodu koji se ponovno izvrava) svjesnost o sekvenciranju
svakog ponavljanja. For petlje se tipicno koriste kad je broj ponavljanja poznat prije
ulaska u petlju. Ime "for petlja" dolazi od engl. rijeci for koja se koristi kao kljucna rijec
u vecini programskih jezika.
Svaka while petlja se moze pretvoriti u for i obratno.To cemo pokazati na sljedecem
primjeru .
Primjer 1.:Treba napisati program koji za proizvoljni broj : racuna sumu
67
n

k=1
1
/ (/ + 1)
i ispisuje rezultat.
Rjeenje:
Unesi n ,i
on:c 0
for (i = 1;i _ :;i = i + 1)
{
on:c on:c +
1
/ (/ + 1)
}
Izlaz : on:c
Naredba
for (i = 1;i _ :;i = i + 1)
{
...
}
je for petlja. Ona djeluje na sljedeci nacin. Prvo se varijabla i inicijalizira tako to joj
se pridruzi vrijednost 1 (i = 1). Inilizacija se izvri samo jednom. Zatim se testira izraz
i <= :. Ako je rezultat testa istinit izvravaju se naredbe iz tijela petlje (naredbe u
viticastim zagradama). Nakon toga se izvrava naredba i = i + 1; kontrola programa
se vraca na testiranje istinitosti izraza i <= :. Petlja zavrava kad izraz koji se testira
postane lazan. Program se tada nastavlja prvom naredbom iza tijela petlje.
For petlja iz naeg primjera moze se zapisati pomocu while-petlje na sljedeci nacin:
i 1
while(i <= :)
{
on:c on:c +
1
/ (/ + 1)
i i + 1
}
Tekst pripremila : Aida Salkic
9.6.4 Postova maina
Opis
Postova maina nije zaista postojeci ureaj. Postova, kao i njoj bliska Tjuringova maina
su imaginarni ureaji. To to ona ne postoji zapravo nema posljedica. Kao to mozemo
nauciti da racunamo na logaritmaru ili racunaru bez da ih imamo pred sobom, samo
koristeci njihov opis i zamiljajuci ih, tako cemo nauciti racunati i na Postovoj maini,
koristeci matu i opis. Postova maina se sastoji od beskonacne trake koja se sastoji
od kvadratica, koje nazivamo celijama jednake duzine, te kucice koja se pomjera duz te
trake (koja cita i snima). Svaka celija na traci moze ili biti prazna ili moze biti oznacena
68
pa je nazivamo oznacenom. Stanje trake zavisi od toga kako su oznake rasporeene po
celijama. Stanje se mijenja kako maina izvrava operaciju. Kada kucica maine stoji
ona je okrenuta jednoj celiji i samo nju ispituje. Informacija pregledanih celija govori o
unutranjem stanju maine. Kucica moze tampati ili brisati oznaku ispitane(pregledane)
celije i time priznati ili ne oznaku celije koja je ispitana.
Program za Postovu mainu
Operacija Postove maine se sastoji u tome da se kucica pomjera duz trake i tampa ili
brie oznaku. Operacija se obavlja posredstvom odreenih instrukcija koje se nazivaju
programom. Program se sastoji od sljedecih instrukcija:
Pomjeri se desno
i. = j.
Pomjeri se lijevo
i. <= j.
Instrukcija za tampanje oznake
i. V j.
Instrukcija za brisanje oznake
i. j.
Prenos kontrole
-j1
i. ?
-j2
Instrukcija zaustavljanja
i. stop
Broj i. prije instrukcije je nazvan brojem instrukcije. Broj ,. na kraju konstrukcije ili ,
1
i ,
2
kod prijenosa kontrole su nazvani skokom (,
1
-vii, ,
2
-nizi). Instrukcija zaustavljanja
nema skoka. Nazvat cemo konacnom nepraznom listom instrukcija one koje imaju sljedece
dvije osobine programa za Postovu mainu:
1. Instrukcija pod brojem 1. zauzima prvo mjesto, instrukcija pod brojem 2. zauzima
drugo mjesto,...
2. Skok bilo koje instrukcije u listi se podudara sa brojem instrukcije (iste ili bilo koje
druge u listi)
69
Sljedeca lista je primjer programa za Postovu mainu:
1. stop
- 4
2. ?
- 1
3. 3
4. stop
Sljedeca lista ne moze biti program:
- 4
2. ?
- 1
1. stop
3. 3
4. stop
Broj instrukcija u programu je nazvan duzinom programa.
Funkcioniranje Postove maine
Za pokretanje ove maine je potrebno:
a) postaviti program
b) postaviti mainu na odreeno unutranje stanje tj. odrediti oznake celije i postaviti
kucicu na odreenu celiju.
Program je osnova za pokretanje maine. Sve instrukcije se izvravaju u jednom koraku,
dok iduci od izvravanja jedne do druge instrukcije drzimo se sljedeceg pravila: pustimo
/-ti korak instrukcije sa brojem i. da bude izvren, onda ako ova instrukcija ima jedan
skok, u (/ + 1) koraku se izvrava instrukcija sa brojem ,.; ako ova instrukcija ima dva
skoka ,
1
i ,
2
, onda se u (/ + 1) koraku izvrava jedna od ove dvije instrukcije; konacno,
ako instrukcija izvrena na /-tom mjestu nema skoka, onda u (/+1) i narednim koracima
nijedna vie instrukcija se ne izvrava i maina staje. Izvrenje instrukcije pomjeri se
desno se sastoji u tome da se kucica maine pomjeri desno jednu celiju, analogno sa
instrukcijom pomjeri se lijevo.
Kod naredbe oznacavanja celije, kucica oznacava ispitanu celije. Ova naredba je izvriva
jedino pod uslovom da je ispitana celija prije izvrenja instrukcije prazna. Ako je, meu-
tim, celija bila oznacena, naredba se smatra neizvrivom. Kod brisanja oznake, kucica
brie oznaku celije nad kojom se nalazi. Ova naredba je izvriva jedino u slucaju da je
ispitana celija oznacena, inace je neizvriva. Naredba prijenosa kontrole ni u kom slucaju
ne mijenja unutranje stanje maine, nijedna oznaka se ne brie i ne stavlja, kucica stoji.
Ako je ispitana celija prije izvrenja bila prazna, sljedeca treba biti instrukcija sa bro-
jem ,
1
, a ako je oznacena, to treba biti instrukcija sa brojem ,
2
. Izvrenje instrukcije
zaustavljanja vodi ka zaustavljanju maine. Kada je maina u pokretu moze se desiti
da odmah na pocetku naie na neizvrivu instrukciju pa program staje. Ovo je tzv.
bezrezultujuce zaustavljanje. Moze se na pocetku naici na instrukciju zaustavljanja, to
je tzv. rezultat zaustavljanja. U krajnjem slucaju maina se ne suocava ni sa jednim
izvrenjem prethodnih instrukcija pa maina radi bez prestanka.
Primjer izvrenja programa
70
1. V 4
2. 3
3. <= 2
4. = 5
- 4
5. ?
- 3
Da vidimo kako maina funkcionira sa ovakvim programom:
Pocetno stanje maine je prikazano na slici 1. U prvom koraku instrukcija broj 1. ce biti
izvrena, poslije koje ce se pocetno stanje maine promijeniti, to je prikazano na slici 2.
Poslije izvrenja instrukcije broj 1., trebamo prijeci na izvrenje instrukcije ciji se broj
poklapa sa skokom instrukcije broj 1., a to je instrukcija broj 4. koja se izvrava u drugom
koraku i pocetno stanje maine je prikazano na slici 3. Sada treba biti izvrena naredba
broj 5. (jer je skok instrukcije broj 4. jednak broju 5.). Ova instrukcija se izvrava u
trecem koraku. Kao rezultat ovog koraka pocetno stanje maine se ne mijenja i ostaje kao
na slici 3. Kako je ispitana celija prazna, instrukcija koja treba biti izvrena je ona koja
71
je jednaka viem skoku tj. broj 4. Poslije instrukcije broj 4., koja je izvrena u cetvrtom
koraku, maina dolazi u pocetno stanje prikazano na slici 4. Sada ce u petom koraku
biti izvrena instrukcija broj 5. Ovaj put je ispitana celija oznacena, stoga je sljedeca
instrukcija koja treba biti izvrena ona koja je jednaka nizem skoku, tj. broj 3. Poslije
izvrenja instrukcije broj 3. u estom koraku maina dolazi u pocetno stanje prikazano
na slici broj 5. i u sedmom koraku se izvrava instrukcija broj 2. ali se ispostavlja da ne
moze biti izvrena jer zapovijeda brisanje prazne celije. Stoga imamo zaustavljanje bez
rezultata u sedmom koraku.
Razni programi zasnovani na istom pocetnom stanju daju razlicite rezultate. Ako imamo
isto pocetno stanje i sljedeci program:
1. = 2
2. = 3
3. V 1
maina ce izvesti prva dva koraka i dobit cemo bezrezultujuce zaustavljanje na trecem
koraku jer trebamo oznaciti vec oznacenu celiju to je neizvrivo. Sljedeci program se
odnosi na isto pocetno stanje:
1. = 2
2. = 3
3. stop
Imamo rezultat zaustavljanja na trecem koraku. Konacno, jo jedan program uz isto
pocetno stanje:
1. = 1
Maina ce izvravati operacije neprestano.
Posmatrajmo:
- 4
1. ?
- 1
2. 3
3. stop
4. = 2
Primjenimo ga na razlicita pocetna stanja A, B i C
A)
B)
72
C)
Za pocetno unutranje stanje A imamo rezultat zaustavljanja na cetvrtom koraku, za B
beskonacnu operaciju maine, za C bezrezultujuce zaustavljanje na trecem koraku.
Postovi sistemi zamjene (engl. rewriting systems) predstavljaju jo jedan konceptualno
razlicit nacin deniranja pojma izracunljivosti, bez pozivanja na koncept univerzalnih
racunskih maina, niti algoritama uopte. Formalno, Postov sistem zamjene zadan je
konacnim skupom aksioma i konacnim skupom pravila zamjene. Pojam izracunljivosti
denira se sada indirektno preko generiranja po Postu. Za neku funkciju , kazemo
da je izracunljiva po Postu ukoliko se njen graf (tj. skup svih ureenih parova oblika
(:. ,(:)) gdje : pripada domenu funkcije) moze generirati po Postu. Pokazuje se da se
skup moze generirati po Postu ako i samo ako je rekurzivno nabrojiv. Kao neposrednu
posljedicu ove cinjenice dobijamo da je koncept izracunljivosti po Postu ekvivalentan
svim drugim konceptima izracunljivosti. Postovi sistemi zamjene su imali veliki uticaj na
razvoj teorijskog racunarstva. Specijalan slucaj Postovih sistema zamjene predstavljaju
gramatike Chomskog, koje postavljaju izvjesne restrikcije na pravila zamjene sa ciljem
da ih ucine uvijek jednoznacno primjenljivim.
Tekst pripremile : Mirela Karic, Alisa Softic
9.7 Zadaci
Zadatak. Neka je na traci data samo jedna rijec sastavljena od jedinica (a sve ostale celije
sadrze znak 0); glava je nad krajnjim lijevim znakom. Napisati program koji dopisuje
dva znaka 1 sa desne strane rijeci a zatim se glava vraca ulijevo na pocetak rijeci i maina
staje.
Rjeenje. Osnovni koncept rjeavanja je da se na svakom koraku ispituje tekuci znak.
Ako je to 1 glava se pomice udesno; ako je to 0 znak se mijenja u 1 i glava ponovo pomice
udesno, znak se mijenja u 1; zatim se vri pomjeranje ulijevo sve dok se ne naie na 0;
tada se glava pomjeri jedno mjesto udesno i program zavrava.
Niz koji opisuje izvravanje ovog programa je dat u nastavku.

0
: 011000...

0
: 011000...

0
: 011000...

1
: 011100...
73
Naredba Akcija

0
1 1
0
glava se pomjera udesno na kraj rijeci

0
0 1
1
na mjestu prve 0 se upisuje 1 i prelazi se u stanje
1

1
1 1
2
glava se pomjera udesno

2
0 1
3
na mjestu druge 0 se upisuje 1 i prelazi u stanje
3

3
1 1
3
glava se pomjera ulijevo sve dok ima znakova 1

3
0 1
z
na prvoj 0 glava ide udesno i zaustavlja se
Table 9: Primjer Tjuringove masine

2
: 011100...

3
: 011110...

3
: 011110...

3
: 011110...

3
: 011110...

3
: 011110...

z
: 011110...
U svakom redu je navedeno stanje a podvucena je pozicija koja odgovara tom stanju.
Ovo se kompaktnije opisuje tabelom.
Stanje 1 0

0

0
1 1
0

0
0 1
1

1

1
1 1
2

2

2
0 1
3

3

3
1 1
3

3
0 1
z
Table 10: Tabelarni opis Tjuringove masine
Zadatak. Napraviti program za Tjuringovu mainu koja izracunava funkciju , (r) = 0.
Rjeenje. Zadatak se rjeava tako da se u svakom koraku znak 1 mijenja sa 0. Kraj se
detektuje tako da se ova zamjena izvrava u okviru jednog stanja i da se u okviru istog
stanja ispituje da li je tekuci znak 0.
Stanje 1 0

0

0
1 0
1

0
0 0
z

1

1
0 1
0
Table 11: Racunanje f(x)
Zadatak. Napraviti program za Tjuringovu mainu koja racuna nasljednika prirodnog
broja :.
Rjeenje. Nasljednik prirodnog broja je broj koji je za 1 veci od datog broja. Zadatak se
rjeava tako da se glava pomakne jedno mjesto ulijevo, upie znak 1 i zavri posao.
Zadatak. Napraviti program za Tjuringovu mainu koja racuna vrijednost funkcije
, (:) = 2:.
74
Stanje 1 0

0

0
1 1
1

1

1
0 1
z
Table 12: Nasljednik prirodnog broja
Rjeenje. Zadatak se rjeava tako da se tekuci znak 1 zamijeni sa 0, prou svi znaci 1 u
toj rijeci, proe i jedan znak 0 iza te rijeci, prou sve jedinice ako ih eventualno ima iza
te nule, dodaju dva znaka 1, glava vrati preko svih jedinica ulijevo, zatim pree preko
znaka 0 koji razdvaja dvije rijeci, prou sve jedinice pocetne rijeci i doe do prvog znaka
1 te rijeci. Kriterij zaustavljanja je da posljednje stanje, zaduzeno za detekciju jedinica
u prvoj rijeci, detektuje znak 0.
Stanje 1 0

0
0 1
1
0 1
z

1
1 1
1
0 1
2

2
1 1
2
1 1
3

3
1 1
4

4
1 1
4
0 1
5

5
1 1
5
0 1
0
Table 13: Mnozenje sa 2
Svaka celija se ovdje cita po sljedecem redu : novi simbol na tekucoj lokaciji (0,1), akcija
(L, R) i novo stanje.
Ilustracija zadatka za mnozenje sa 2
U narednim primjerima Tjuringova maina je data estorkom Q. . . o.
0
. 1 gdje je:
Q : konacan skup stanja
75
: skup ulaznih simbola (alfabet)
: skup simbola na traci ukljucujuci i simbol # za prazno
o : tranzicijska funkcija o : Q Q 1. 1

0
: inicijalno stanje
1 : skup konacnih stanja
Zadatak. Zadata je Tjuringova maina
1` = (
1
.
2
.
3
. 0. 1 . 0. 1. # . o.
0
.
z
)
Maina cita niz znakova i krajnji desni mijenja simbolom #.
Rjeenje. Dijagram za ovaj program je u nastavku.

Citanje niza simbola i ispravka krajnjeg desnog simbola


Ovdje se " 1. 1. 1" cita : Ako je
0
= 1 upisati 1 (1 ostaje 1) i idi desno u stanje
1
" itd.
Program je dat u obliku tabele.
Stanje 1 0 #

0
0. 1.
1
1. 1.
1

1
0. 1.
1
1. 1.
1
#. 1.
2

2
#. 1.
3
#. 1.
3

3
0. 1.
3
1. 1.
3
#. 1.
z
Table 14: Citanje niza znakova i ispravka krajnjeg desnog simbola
Niz kojim se ilustruje rad ovog programa je u nastavku.

0
: #1110#

1
: #1110#

1
: #1110#

1
: #1110#

1
: #1110#

2
: #1110#

3
: #111##

3
: #111##

3
: #111##

3
: #111##
76

z
: ##111##
Zadatak. Napraviti program koji cita niz nula i jedinica i daje broj jedinica u nizu. Izlaz
je 0 ako je broj jedinica u nizu paran a 1 ako je broj jedinica neparan.
Rjeenje. Akcije koje se obavljaju su :
Trazenje jedinica slijeva udesno
Simboli 0 se citaju ali se ignoriu
Odrzava se brojac ako se naie na simbol 1 u skladu sa tim da li je broj jedinica
paran ili neparan
Kad se naie na znak # izlaz se pie na tekucu poziciju
Skup stanja je sljedeci :

0
indicira da li je broj simbola 1 paran

1
indicira da li je broj simbola 1 neparan
Dijagram za ovaj program je u nastavku.
Brojac pariteta broja jedinica u nizu
Program je dat sljedecoj na tabeli.
Stanje 1 0 #

0
1 1
1
0 1
0
0 1
z

1
1 1
0
0 1
1
1 1
z
Table 15: Utvrdjivanje pariteta
Rad je ilustrovan na sljedecem primjeru.

0
: 1011010#

1
: 1011010#

1
: 1011010#

0
: 1011010#

1
: 1011010#

1
: 1011010#
77

0
: 1011010#

0
: 1011010#

z
: 10110100
Zadatak. Zadata je Tjuringova maina
1` = (
1
.
2
.
3
. 0. 1 . 0. 1. # . o.
0
.
z
)
Prethodni primjer modikovati na nacin da se izlaz stavlja nakon simbola # tako da se
dopie jo jedan takav simbol. Drugim rijecima ako je string 01# tada je izlaz u obliku
01#1# a izlaz iz stringa iz prethodnog primjera bi trebao biti 1011010#0#.
Rjeenje. Ovdje je potrebna dodatna akcija za trazenje simbola # i stavljanje izlaza iza
njega. Dijagram za ovaj program je u nastavku.
Modikacija programa za odreivanje pariteta
Program je dat na narednoj tabeli.
Stanje 1 0 #

0
1 1
1
0 1
0
# 1
2

1
1 1
0
0 1
1
# 1
3

2
0 1
z

3
1 1
z
Table 16: Modikacija programa za odredjivanje pariteta
Rad je ilustrovan na sljedecem primjeru.

0
: 1011010##

1
: 1011010##

1
: 1011010##

0
: 1011010##

1
: 1011010##

1
: 1011010##

0
: 1011010##

0
: 1011010##

2
: 1011010##
78
Figure 1: Dodavanje jedinice na binarni zapis broja
Stanje 1 0 #

0
1 1
0
0 1
0
# 1
1

1
0 1
1
1 1
z
1 1
z

2
0 1
2
1 1
2
# 1
z
Table 17: Dodavanje jedinice na binarni zapis

z
: 1011010#0
Zadatak. Zadata je Tjuringova maina
1` = (
1
.
2
.
3
. 0. 1 . 0. 1. # . o.
0
.
z
)
Napraviti program koji dodaje 1 broju koji je predstavljen binarno, sa mogucim vodecim
nulama.
Rjeenje. Aktivnosti koje se obavljaju su:
Trazenje posljednje znacajne cifre
Kretanje ulijevo i praviti prenos. Ako je pronaena 0 mijenja se jedinicom i posao
se zaustavlja; Ako je pronaena 1 mijenja se sa 0 i nastavlja sa kontrolom prenosa
Dijagram za ovaj program je u nastavku.
Program je dat na sljedecoj tabeli.
Rad programa je ilustrovan na sljedeca dva primjera.
Primjer 1.

0
: #110#

0
: #110#

0
: #110#

0
: #110#

1
: #110#

z
: #111#
Primjer 2.

0
: #11#

0
: #11#

0
: #11#
79

1
: #11#

1
: #10#

1
: #00#

z
: #100#
Zadatak. Data je Tjuringova maina
1` = (
1
.
2
.
3
.
4
.
5
.
6
. 0. 1. . # . 0. 1. . #. A . o.
0
.
z
)
Napraviti program koji za data dva broja : i : racuna vrijednost max :. :. Svaki broj
je predstavljen nizom jedinica. Pri tome je po jedan simbol postavljen jednu poziciju
ulijevo od kranje lijeve pozicije prvog broja i jednu poziciju desno od krajnje desne pozicije
drugog broja; brojevi su odvojeni jednim znakom # to je i inicijalna pozicija.
Rjeenje. Koncept rjeavanja problema je sljedeci:
pocev od inicijalne pozicije na svakom koraku se po jedna jedinica sa svake strane
zamjenjuje simbolom A
ako se pri kretanju naie na simbol tada se svi znaci A sa te strane znaka #
mijenjaju sa 0, znak # se mijenja u znak svi znaci A sa druge strane znaka #
mijenjaju sa 1
Rezultat je broj koji je maksimalni od dva data broja. Navedeni program je dat u obliku
naredne tabe.
# 1 A

0
#. 1.
1

1
A. 1.
3
A. 1.
1
0. 1.
5

2
A. 1.
4
A. 1.
2
0. 1.
6

3
#. 1.
2
A. 1.
3

4
#. 1.
1
A. 1.
4

5
. 1.
5
1. 1.
5
0. 1.
5
. 1.
z

6
. 1.
6
1. 1.
6
0. 1.
6
. 1.
z
Table 18: Nalazenje maksimalnog broja
80
10 Sortiranja
10.1 Uvod
Algoritmi sortiranja su primjer matematickih algoritama koji se rjeavaju putem mnogih
drugih razlicitih metoda.
U optem slucaju, sortiranje se shvata kao proces pregrupisavanja datog skupa objekata u
nekom odreenom redoslijedu. Cilj sortiranja je olakati pretrazivanje elemenata u tako
sortiranom skupu. To je skoro univerzalni, fundamentalni zadatak. U svakodnevnom
zivotu se srecemo sa puno primjera kao to su telefonski imenici, rijecnici i slicno.
Izbor algoritama za rjeavanje bilo kog problema zavisi od strukture podataka, to je
skoro zakon, a u slucaju sortiranja takva zakonitost je toliko duboka da se odgovarajuce
metode dijele na dvije klase, sortiranje nizova i sortiranje fajlova. Nekada se nazivaju
unutranje i vanjsko sortiranje, s obzirom da se nizovi pohranjuju u brzo internoj memoriji
dok su fajlovi pohranjeni na spoljnim, sporijim ureajima (diskovi,...). Ovo je moguce
ilustrovati na primjeru sortiranja igracih karata. Ako se karte posmatraju u obliku niza
onda su poslozene na stolu i onaj ko ih sortira vidi ih sve pojedinacno i ima neposredan
pristup svakoj od njih. Ako karte obrazuju fajl to podrazumijeva da je vidljiva samo ona
na vrhu svake gomile. Ovakvo ogranicenje ima ozbiljan uticaj na metod sortiranja.
Ako su dati elementi c
1
. c
2
. .... c
n
. ... tada je sortiranje permutacija tih elemenata u niz
c
k
1
. c
k
2
. .... c
k
n
. ... u kojem, po osnovu neke funkcije poretka , vrijedi , (c
k
1
) _ , (c
k
2
) _
... _ , (c
k
n
) _ .... Funkcija poretka se obicno ne racuna po nekom pravilu vec se cuva
kao sastavni dio (polje) svakog elementa. Znacenje te funkcije se naziva kljuc (key).
Metod sortiranja je lokalan (in-place) ako ne koristi dodatne memorijske resurse za sor-
tiranje i stoga je moguce sortirati veoma velike liste bez potrebe alokacije (dodjeljivanja)
dodatnog memorijskog prostora.
Metod sortiranja je stabilan ako se u procesu sortiranja odgovarajuci odnos elemenata sa
jednakim kljucevima ne mijenja. Ovo je cesto pozeljna osobina ako se radi o elementima
koji su vec sortirani nekim metodom koji nema uticaja na kljuc.
10.2 Sortiranje nizova - osnovne metode
Osnovni uslov je da odabrani metod sortiranja nizova ekonomicno koristi dostupnu mem-
oriju. To podrazumijeva da se permutacije kojima se elementi stavljaju u odgovarajuci
poredak obavljaju na tom istom mjestu. Drugim rijecima, metode koje podrazumijevaju
da se elementi niza c premjetaju u niz / predstavljaju bitno manji interes. Zbog ovakvih
ogranicenja algoritmi se klasiciraju po osnovu ekonomicnosti odnosno vremenu rada.
Dobra mjera ekasnosti moze biti C, broj neophodnih uporeivanja kljuceva i `, broj
premjetanja (permutacija) elemenata. Ovi brojevi su funkcija od :, dimenzije niza koji
se sortira.
Mada dobri algoritmi sortiranja trebaju :log : uporeivanja, analiza pocinje od prostijih
i ociglednih algoritama koji se nekada nazivaju direktni. Motiv za ovakav izbor moze biti:
Direktne metode su posebne pogodne za objanjenje karakteristika osnovnih prin-
cipa obima sortiranja
81
Postupci tih metoda se lako pamte i kratki su. Ne treba zaboraviti da i programi
zauzimaju memoriju
Usloznjavanje metoda trebaju manji broj operacija koje su same po sebi dosta
slozene pa su za male : direktne metode brze mada ih ne treba koristiti za velike :
Metode sortiranja na tekucoj poziciji se dijele na :
Sortiranja putem ukljucivanja (insertion)
Sortiranja putem podjele (selection)
Sortiranja putem zamjene (exchange)
Napomena. U narednom izlaganju se koristi tzv. relativno indeksiranje nizova koje
sastoji u tome da prvi clan niza ima indeks 0 a da svi ostali imaju indeks koji odgovara
broju pozicija nakon tog elementa. U takvoj notaciji je c
4
je peti element niza jer je
4 pozicije u odnosu na c
0
. Iz tog razloga je vazno razumjeti da npr. 1n.i:c [c] 1
oznacava, ustvari, indeks posljedneg a ne pretposljednjeg clana niza.
U tzv. apsolutnom indeksiranju clanovi niza imaju indeks koji odgovara njihovoj stvarnoj
poziciji (c
1
. c
2
. .... c
n
. ...). Pomocu jednostavne transformacije je moguce pretvoriti jednu
notaciju u drugu.
10.2.1 Sortiranje putem umetanja (Insertion sort)
Algoritam sortiranja umetanjem (Insertion sort) se temelji na meusobnom uporeivanju
vrijednosti kljuceva pri cemu se u svakoj iteraciji odrzavaju sortirani i nesortirani dio niza.
U svakom sljedecem koraku se iz nesortiranog dijela uzima jedan element i taj element se
umece na odgovarajuce mjesto u sortiranom dijelu. Prema tome, svakim novim korakom
sortiranja nesortirani dio niza se smanjuje, dok se sortirani dio niza postepeno povecava.
Insertion sort ce biti objanjen na primjeru sortiranja niza = c
0
. c
1
. .... c
n1
u ras-
tucem poretku. Na pocetku algoritma sortirani dio se sastoji samo od prvog elementa c
0
dok svi ostali elementi cine nesortirani dio niza. U prvom koraku se porede elementi c
1
i
c
0
(drugi i prvi element u nizu) . Ako je element c
0
veci od elementa c
1
tada se element
c
1
pohranjuje u privremenu lokaciju j:i, element c
0
se pomjera na drugo mjesto (i = 1)
te se na prvo mjesto u nizu s indeksom i = 0 pohranjuje element c
1
iz privremene lokacije
j:i. U ovom trenutku sortirani dio niza sadrzi dva elementa (c
0
i c
1
) a nesortirani dio
sadrzi : 2 elemenata (c
2
, c
3
,...c
n1
).
Pretpostavimo da je algoritam doao do nekog i-tog koraka. Poslije prethodnog (i 1)-og
koraka u sortiranom dijelu se nalaze elementi c
1
, c
2
,..., c
i1
. Zatim se u i-tom koraku
iz nesortiranog dijela uzima element c
i
, nakon cega se prema kraju niza pomjeraju svi
elementi iz sortiranog dijela niza koji su veci od elementa c
i
da bi se oslobodio prostor za
pohranjivanje tog elementa na odgovarajuce mjesto u nizu. Na taj nacin se velicina sorti-
ranog dijela niza povecava sa i 1 na i. Sortiranje se zavrava kada u nesortiranom dijelu
niza nema vie elemenata odnosno kada zadnji element c
n1
zauzme svoju odgovarajucu
poziciju. Algoritam je ilustrovan na primjeru u tabeli 1.
82
0 1 2 3 4 5 j:i
4 11 2 9 3 10
4 11 2 9 3 10
4 11 9 3 10 2
4 11 9 3 10 2
4 11 9 3 10 2
2 4 11 9 3 10
2 4 11 9 3 10
2 4 11 3 10 9
2 4 11 3 10 9
2 4 9 11 3 10 9
2 4 9 11 3 10
2 4 9 11 10 3
2 4 9 11 10 3
2 4 9 11 10 3
2 4 9 11 10 3
2 3 4 9 11 10
2 3 4 9 11 10
2 3 4 9 11 10
2 3 4 9 11 10
2 3 4 9 10 11
Table 19: Tabela 1. Insertion sort
Na tabeli su naglaeni elementi koji u tom algoritmu imaju indeks i. Pseudo kod kojim
se opisuje ovaj algoritam je u nastavku.
Proces trazenja se moze zavriti u jednom od dva slucaja :
Naen je element c
j
sa kljucem koji je manji od kljuca za r
Dostignut je lijevi kraj sortiranog dijela niza
Ovakav tipican slucaj ponavljajuceg procesa sa dva uslova zavretka dozvoljava koritenje
granicnika (sentinel). U ovom slucaju to moze biti element c
0
(to znaci da je dovoljno
raspon indeksa proiriti indeksom 0). Analiza slozenosti ove metode je data dijelom na
tabeli 2.
Najbolji slucaj se pojavljuje u situaciji kada je niz vec sortiran pa je za pozicioniranje
svakog elementa potrebna samo jedna operacija poreenja. Tom operacijom se zapravo
samo utvruje da je prethodnik svakog elementa manji od tog elementa, te svi elementi
ostaju na svojim mjestima. To znaci da je u najboljem slucaju ukupan broj operacija
poreenja 1
c
(:) :
1
c
(:) = : 1
Prema tome, vremenska slozenost za najbolji slucaj je O(:).
Najgori slucaj se pojavljuje u situaciji kada je za umetanje svakog elementa iz nesortiranog
dijela niza potrebno porediti taj element sa svim elementima u sortiranom dijelu niza.
83
Procedura InsertionSortDirektni
Ulaz : :. c
n

Inicirati i. ,. j:i
// Pocetak od prve pozicije
i 1
Za (i _ 1n.i:c [c] 1) raditi
{
// Element ide na rezervnu lokaciju
j:i c [i]
// Umetanje elementa c [i] u sortirani niz c [1. ... , 1]
, i 1
DokVrijedi (, _ 0 & c [,] j:i) raditi
{
// Element se stavi jednu poziciju desno
c [, + 1] c [,]
// Pomjeramo se za jedno mjesto ulijevo
, , 1
}
// Element sa privremene lokacije se smjeta na svoje mjesto
c [, + 1] j:i
}
Izlaz : Sortirani niz c
n

Drugim rijecima, najgori slucaj je kada se svaki element trenutno pozicionira na pocetak
sortiranog dijela niza. To se dogaa kada je niz sortiran u obrnutom poretku. Tada je
ukupni broj operacija usporedbi 1
c
(:) :
1
c
(:) =
n

i=1
i =
:(: 1)
2
Na taj nacin se dobija da ovaj algoritam ima kvadratnu zavisnost od velicine niza odnosno
njegova brzina se izrazava sa O(:
2
).
Analiza ove metode putem broja poreenja i premjetanja pokazuje da broj poreenja
kljuceva (C
i
) u i-tom koraku moze biti najvie i 1, najmanje 1 a u prosjeku i,2,
pod pretpostavkom da su sve permutacije od : elemenata jednako vjerovatne. Broj
premjetanja `
i
je jednak C
i
+2 (ukljucujuci barijeru, sentinel). Na tabeli 3. su procjene
brzine ovog algoritma.
Minimalne ocjene se mogu desiti kod vec sortiranih nizova a najgore kada je niz sortiran
opadajucim redoslijedom.
Poboljanja
Kod ovog algoritma se obavlja pretrazivanje sortiranog dijela niza da bi se odredila pozi-
cija umetanja prvog elementa iz nesortiranog dijela niza. Upravo na svojstvu da je prvi dio
niza sortiran temelji se poboljanje ekasnosti kod kojeg se pozicija umetanja pronalazi
binarnim umjesto sekvencijalnim pretrazivanjem, kao to je to slucaj u osnovnoj vari-
janti algoritma. U toj poboljanoj varijanti prosjecan broj operacija poreenja u svakoj
84
Korak Dinamika
0 1 i 1
1 DokVrijedi (i < 1n .i:c [c]) raditi { :
2 j:i c [i] : 1
3 , i 1 : 1
4 DokVrijedi (, _ 0 & c [,] j:i) raditi {
5 c [, + 1] c [,]
6 , , 1
7 }
8 c [i + 1] j:i : 1
9 , , + 1 : 1
10 }
Table 20: Insertion sort - Analiza slozenosti
C `
min : 1 3 (: 1)
prosjek
:
2
+: 2
4
:
2
+ 9: 10
4
max
:
2
+: 4
4
:
2
+ 3: 4
4
Table 21: Procjena brzine Insertion sort
iteraciji se smanjuje sa i,2 na priblizno 1 + log
2
i. To znaci da je u poboljanoj varijanti
vremenska slozenost za operacije poreenja reda O(:log :) to je znatno poboljanje, ali
samo za te operacije. Meutim, ekasnim pronalazenjem mjesta umetanja ne smanjuje
se i broj potrebnih operacija premjetanja koji zapravo ostaje isti kao i u osnovnoj vari-
janti. Taj broj operacija je dominantan u odnosu na broj operacija u poreenju za velike
vrijednosti : pa ukupna vremenska slozenost algoritma ostaje O(:
2
). Pseudo kod za ovu
varijantu algoritma sortiranja je u nastavku.
10.2.2 Shell sort
U osnovnoj varijanti algoritma sortiranja umetanjem elementi se pomjeraju za samo
jednu poziciju, to za posljedicu ima veliki broj premjetanja. Ekasnost algoritma se
moze poboljati na nacin da se porede elementi koji su odvojeni nekim razmakom te da
se umetanje elemenata obavlja tako da se prave premjetanja elemenata sa skokovima
vecim od jednog mjesta razmaka. Neka je, na primjer, u nizu element koji ima neku
malu vrijednost koja se prije sortiranja nalazi pri kraju niza i da niz treba sortirati
niz u rastucem poretku. Koristeci osnovnu varijantu algoritma sortiranja umetanjem
bio bi potreban veliki broj operacija poreenja i premjetanja dok taj element ne bi bio
umetnut na odgovarajucu poziciju. Ekasnost se moze poboljati tako da se elementi prvo
pomjeraju prema konacnoj poziciji koristeci velike skokove, tako da bi se, na primjer,
element koji ima malu vrijednost pomjerio prema konacnoj poziciji uz samo nekoliko
operacija poreenja i premjetanja. Poboljanje koje se temelji na prethodno opisanoj
strategiji je predlozio Donald Shell, po kojem je algoritam nazvan Shell sort.
Prethodno je receno da je osnovna varijanta algoritma umetanjem ekasna ako ulazni
85
Procedura BinaryInsertion
Ulaz : :. c
n

Izlaz : Sortirani niz c


n

Inicirati i. ,. :. 1. 1. r
Za svaki i = 1. 1n.i:c [c] 1. 1
{
//Uzeti element niza
r c [i]
1 1; 1 1
// Odrediti lijeve i desne granice
DokVrijedi 1 < 1 raditi
{
: = (1 +1) ,2|
Ako je c [:] < r
{
1 :+ 1
}
Inace
{
1 :
}
}
//Pretraziti sortirani niz
Za svaki , = i. 1 + 1. 1
{
c [,] c [, 1]
}
c [1] r
}
niz vec ima visok stepen ureenosti. Algoritam Shell sort razdvaja pocetni niz na grupe
tako to se u svakoj grupi nalaze elementi koji su odvojeni jednakim razmakom, koji ce
biti oznacen sa /
1
. Zatim se svaka grupa sortira posebno primjenom osnovne varijante
sortiranja umetanjem, nakon cega se dobija niz sa vecim stepenom ureenosti u odnosu
na pocetni niz. U sljedecem koraku se uzima razmak /
2
koji je manji od razmaka /
1
. U
ovom koraku je smanjen broj grupa, ali svaka grupa ima veci broj elemenata. Grupe se
ponovo posebno sortiraju primjenom osnovne varijante algoritma sortiranja umetanjem
pa se dobija jo veci stepen ureenosti ulaznog niza. U sljedecim koracima se biraju
sve manji i manji razmaci, a postupak zavrava primjenom zavrnog razmaka /
t
= 1
to zapravo znaci da se u zadnjoj fazi svi elementi tretiraju kao jedna grupa. Drugim
rijecima, u zadnjem koraku, kada je ulazni niz vec gotovo sortiran, primjenjuje se
osnovna varijanta metoda umetanjem. U opisanim fazama algoritma sortiranja Shell sort
koristi niz razmaka / = [/
1
. /
2
. .... /
t1
] pri cemu je /
i
/
i+1
, i = 1. .... t 2.
Za razumljiviji opis ovog algoritma ce biti koriten konkretan primjer. Neka je zadatak
sortirati sljedeci niz brojeva:
28. 17. 10. 79. 13. 67. 23. 33. 12. 5. 9. 80. 86. 15. 59. 49. 64. 54. 36. 29
86
Poto algoritam Shell sort poredi brojeve iz niza uzimajuci neki razmak, neka je u prvoj
fazi taj razmak 7. To znaci da ce se porediti i meusobno eventualno razmjenjivati
mjesta, na primjer, sljedeci brojevi: 28, 33 i 59 (jer su razmaknuti za 7 mjesta). Isto
tako, poredice se i eventualno meusobno razmjenjivati mjesta brojevi 17,12 i 49 (jer
su takoer razmaknuti za 7 mjesta). Da bi ovaj proces bio jasnije prikazan, moze se
koristiti drugaciji nacin prikaza. Naime, ako je odabran razmak 7 onda se gornji pocetni
niz brojeva moze prikazati sljedecom tabelom koja ima 7 kolona, pri cemu svaka kolona
sadrzi elemente pojedine grupe koji se posebno sortiraju:
28 17 10 79 13 67 23
33 12 5 9 80 86 15
59 49 64 54 36 29
Table 22: Shell sort - prvo grupisanje
Ovakav prikaz je napravljen samo u cilju vizueliziranja procesa poreenja i sortiranja
pojedinih grupa, koji se obavljaju u pojedinim fazama primjene algoritma Shell sort.
Sada se sortira svaka kolona (grupa) posebno. Rezultirajuca tabela je:
28 12 5 9 13 29 15
33 17 10 54 36 67 23
59 49 64 79 80 86
Table 23: Shell sort - prvo sortiranje
Ova tabela se sada moze prikazati u obliku jednodimenzionalnog niza, to zapravo i
odgovara stvarnom rasporedu elemenata u memoriji:
28. 12. 5. 9. 13. 29. 15. 33. 17. 10. 54. 36. 67. 23. 59. 49. 64. 79. 80. 86
Moze se primijetiti da rezultirajuci niz u trenutnoj fazi sortiranja, kada je uzet razmak 7,
ima veci stepn ureenosti od pocetnog niza. Vidljivo je pomjeranje elemenata sa vecim
vrijednostima prema kraju niza i elemenata sa manjim vrijednostima prema pocetku niza.
Na primjer, element 29 sa zadnje pozicije se pomjerio na esto mjesto, dok se, na primjer,
element 36 sa predzadnje pozicije pomjerio na dvanaesto mjesto.
Postupak primjene algoritma Shell sort se nastavlja tako to se sada uzme, na primjer,
razmak /
2
= 3. To znaci da se ulazni niz u drugoj fazi za potrebe vizualizacije elemenata
koji se tretiraju kao posebne grupe moze prikazati u obliku sljedece tabele sa 3 kolone:
Opet se grupe (kolone) sortiraju posebno primjenom osnovne varijante sortiranja umetan-
jem te se dobija sljedeca tabela :
Gornja tabela zapravo prikazuje sljedeci niz:
9. 12. 5. 10. 13. 17. 15. 23. 29. 28. 33. 36. 49. 54. 59. 67. 64. 79. 80. 86
87
28 12 5
9 13 29
15 33 17
10 54 36
67 23 59
49 64 79
80 86
Table 24: Shell sort - Novo grupisanje
9 12 5
10 13 17
15 23 29
28 33 36
49 54 59
67 64 79
80 86
Table 25: Shell sort - Drugo sortiranje
Rezultujuci niz ima jo veci stepen ureenosti u odnosu na niz u prethodnoj fazi. Naime,
dolo je do daljnjeg pomjeranja vecih brojeva prema kraju niza i manjih brojeva prema
pocetku niza. Rezultujuci niz ipak jo nije sortiran, te je ostalo da se napravi jo jedna faza
nakon cegace niz biti konacno sortiran. Poto je trenutni niz skoro sortiran, razumno je
zapravo uzeti razmak /
3
= 1 a to znaci primijeniti osnovnu varijantu algoritma sortiranja
umetanjem, jer ce biti potreban mali broj poreenja i premjetanja s obzirom da je niz vec
skoro sortiran. Dakle, primjenom algoritma sortiranja umetanjem s razmakom /
3
= 1,
dobija se rezultirajuci sortirani niz:
5. 9. 10. 12. 13. 15. 17. 23. 28. 29. 33. 36. 49. 54. 59. 64. 67. 79. 80. 86
Algoritam za Shell Sort je u nastavku. U njemu je H niz razmaka koji se uzimaju na
svakom koraku.
Analiza ShellSort algoritma je postavila nekoliko veoma tekih matematickih problema
od kojih neki jo nisu rijeeni. Kao najbitnije, nije pokazano koja rastojanja daju najbolji
rezultat. Postoji zacuujuca cinjenica : rastojanja ne smiju biti meusobni mnozitelji.
Ovo dozvoljava da se izbjegne pojava da se formiraju podnizovi koji se ne presijecaju.
Stoga je interakcija dva niza pozeljna to je vie moguce.
Do sortiranog niza ce dovesti primjena bilo kojeg niza razmaka H = /
0
. /
1
. .... /
t1

takvih da je :
/
i
/
i+1
, i = 0. 1. 2. .... t 2
/
t1
= 1
Knut je predlozio niz 1. 4. 13. 40. ... gdje je /
k1
= 3 /
k
+ 1, /
t
= 1, t = log
3
:| 1.
Drugi prijedlog je niz 1. 3. 7. 15. ... gdje je /
k1
= 2 /
k
+ 1, /
t
= 1, t = log
2
:| 1.
Analiza pokazuje da su u posljednjem slucaju rezultati proporcionalni sa :
1:2
. Mada je
ova vrijednost bitno bolja od :
2
to ne znaci da se ne mogu praviti nova poboljanja.
88
// Ulaz : Niz c, H
// Niz H je niz koraka za koje se obavlja sortiranje
Za i = 0 do 1n.i:c [/] 1 Raditi
{
/ H [i]
Za , / do 1n.i:c [c] 1 Raditi
{
j:i c [,]
/ , /
SveDokJe (/ _ 0) & (c [/] j:i) Raditi
{
c [/ +/] c [/]
/ / /
}
c [/ +/] j:i
}
}
10.2.3 Sortiranje putem direktne podjele (Selection sort)
Jedan od nedostataka algoritma Insertion sort je to to zahtijeva veliki broj operacija
pomjeranja unutar sekvence. Primjer jednostavnog algoritma sortiranja koji je oblikovan
tako da se bitno smanjuje broj premjetanja je Selection sort (sortiranje selekcijom) al-
goritam. Kod ovog algoritma se pomjeranje podataka pri sortiranju obavlja direktno na
njihovu konacnu poziciju u sortiranom nizu.
Slicno kao i kod algoritma Insertion sort, i kod algoritma Selection sort se u procesu
sortiranja razlikuju sortirani i nesortirani dio niza. Na pocetku svi elementi niza
= c
0
. c
1
. ...c
i
. c
i+1
. .... c
n1

pripadaju nesortiranom dijelu, a zatim se sekvencijalnim pretrazivanjem pronalazi na-


jmanji element, koji se zatim premjeta na prvu poziciju, dok se prethodni element s
prve pozicije premjeta na poziciju pronaenog minimalnog elementa. Na taj nacin je
u prvom koraku oblikovan sortirani dio niza koji cini element c
0
dok ostali elementi
niza c
1
. c
2
. .... c
n1
cine nesortirani dio niza. Poslije nekog (i 1)-og koraka u sorti-
ranom dijelu niza su elementi c
0
. c
1
. .... c
i2
dok su u nesortiranom dijelu niza elementi
c
i1
. c
i
. .... c
n1
. U sljedecem i-tom koraku se u nesortiranom dijelu niza pronalazi naj-
manji element pa se taj element pozicionira na prvo mjesto u neureenom dijelu niza a
to je pozicija i 1. U tom trenutku sortirani dio niza je c
0
. c
1
. .... c
i1
a nesortirani dio
niza je c
i
. c
i+1
. .... c
n1
. Postupak sortiranja se zavrava kada u nesortiranom dijelu na
poziciji : 1 ostane samo jedan element, koji zapravo ostaje na toj poziciji.
Vazno je primijetiti da se poreenje elemenata kod sortiranja selekcijom obavlja nad
elementima nesortiranog dijela niza, za razliku od sortiranja umetanjem, kod kojeg se
usporedba elemenata obavlja nad elementima sortiranog dijela niza. Ova razlika ima za
posljedicu da postupak sortiranja selekcijom ne moze zapoceti sve dok nisu prisutni svi
elementi koji se trebaju sortirati, to nije slucaj kod sortiranja umetanjem, kod kojeg
elementi koji se sortiraju mogu pristizati jedan za drugim.
89
0 1 2 3 4 5
4 11 2 9 3 10
2 11 4 9 3 10
2 11 4 9 3 10
2 3 4 9 11 10
2 3 4 9 11 10
2 3 4 9 11 10
2 3 4 9 11 10
2 3 4 9 11 10
2 3 4 9 11 10
2 3 4 9 10 11
Table 26: Ilustracija algoritma
Algoritam za sortiranje selekcijom je ilustriran na narednoj slici za niz od 6 elemenata.
Duplim linijama su istaknute pozicije niza za koje se u procesu sortiranja u pojedinim
fazama selekcionira minimalni element iz nesortiranog dijela niza, dok je zaokruzena
pozicija na kojoj je pronaen minimalni element, takoe u nesortiranom dijelu niza. U
prvom koraku je oznacena prva pozicija sa indeksom 0 na kojoj se nalazi element 4 te
je pronaen minimalni element 2 na poziciji s indeksom 2. U sljedecem koraku elementi
4 i 2 mijenjaju pozicije te se u nizu razlikuju sortirani dio niza koji se sastoji samo od
elementa 2 i nesortirani dio niza koji ukljucuje sve ostale elemente. U sljedecem koraku
je oznacena pozicija s indeksom 1 na kojoj se nalazi element 11 i pronaen je minimalni
element 3 u nesortiranom dijelu niza, pa elementi 11 i 3 mijenjaju pozicije u nizu. U tom
trenutku sortirani dio niza cine elementi 2 i 3 a elementi 4, 9, 11 i 10 cine nesortirani dio
niza.
Ovaj postupak se ponavlja za sve ostale pozicije i (i = 2. 3. .... : 2), sve dok se na
pretposljednje mjesto u nizu ne umetne element 10. Zadnji preostali element 11 zauzima
jedinu mogucu (zadnju) poziciju, pa se postupak zavrava selekcioniranjem elementa za
poziciju i = : 2.
Algoritam za sortiranje selekcijom je opisan procedurom na narednom dijagramu. Ulazni
argument u proceduru je niz c koji se sortira. Vanjska for petlja omogucuje ponavl-
janje postupka pronalazenja minimalnog elementa u nesortiranom dijelu niza za svaku
od lokacija i = 0. 1. 2. .... 1n.i:c [c] 2. Za zadnju lokaciju 1n.i:c[c] 1 nije potrebno
ponavljati postupak, jer se u tom slucaju nesortirani dio niza sastoji samo od jednog ele-
menta, pa je taj podniz sortiran sam po sebi. U svakoj i-toj iteraciji se prvo inicijaliziraju
vrijednosti privremeno minimalnog elementa :c,: i indeksa njegove pozicije j:c,: a
zatim se u sklopu unutarnje for petlje izvode iteracije kojima se u
nekom ,-tom prolazu u nesortiranom dijelu niza c, kojeg cine elementi na pozicijama i
do 1n.i:c[c] 1 pronalazi minimalni element. Na kraju svake i-te iteracije vanjske for
petlje element na poziciji j:c,: i prvi element c[i] iz nesortiranog dijela niza izmjenjuju
svoje pozicije.
Algoritam sortiranja selekcijom je specican po tome to je i broj pridruzivanja i broj
poreenja uvijek isti, bez obzira na duzinu niza. Algoritam se izvrava u : 1 prolaza
kroz nesortirani dio niza, a svaki prolaz ima jednu zamjenu pozicija koja ukljucuje 3
operacije pridruzivanja. To znaci da je ukupan broj operacija pridruzivanja :
90
// Algoritam : Selection sort
Za i 0 do 1n.i:c [c] 2 raditi
{
:c,: c [i]
j:c,: i
Za , i + 1 do 1n.i:c [c] 1 Raditi
{
AkoJe (c [,] < :c,:) tada
{
:c,: c [,]
j:c,: ,
}
}
c [j:c,:] c [i]
c [i] :c,:
}
1
a
(:) = 3 (: 1)
Dakle, operacije pridruzivanja kod algoritma sortiranja selekcijom imaju slozenost O(:),
to je znatno poboljanje u odnosu na algoritam sortiranja umetanjem kada su u pitanju
operacije pridruzivanja. U prvom prolazu ima : 1 operacija poreenja, u drugom
prolazu ih ima : 2 a u nekom i-tom prolazu broj poreenja je : i. Dakle, ukupan
broj poreenja je:
1
c
(:) =
n1

i=1
(: i) =
:(: 1)
2
Broj zamjena je minimalno `
min
= 3 (: 1) u slucaju da su kljucevi odmah sortirani
a maksimalno `
max
= (:
2
,4) + 3 (: 1) ako su pocetni kljucevi poredani opadajucim
redom.
Za proracun prosjecnog vremena trajanja uzima se da je ocekivani broj premjetanja
jednak sumi H
n
= 1 + 1,: + 1,2 + ... + 1,:. Pri tome su 1,i vjerovatnoce da je i-ti
element manji od prethodnih i 1 elemenata. Ova vrijednost se moze iskazati i sa
H
n
= ln : +q + 1,2: 1,12:
2
+...
gdje je q = 0. 577216... Eulerova konstanta. Za dovoljno veliko : se mogu zanemariti
razlomci u nastavku pa je prosjecan broj premjetanja na i-tom koraku jednak 1
i
=
ln i +q + 1. Prosjecan broj premjetanja, u oznaci `
avg
, je suma svih 1
i
odnosno
`
avg
= : (q + 1) +
n

i=1
ln i
Ova se suma aproksimira integralom
n
_
1
ln rdr = r (ln r 1)[
n
1
= : (ln : 1) : + 1
91
to na kraju daje `
avg
= : (:ln +q). Odavdje se izvodi zakljucak da je ovaj algoritam
preporucljiviji u odnosu na sortiranje umetanjem. Ako su kljucevi sortirani ili skoro
sortirani insertovanje je neto bolji algoritam.
10.2.4 Sortiranje putem zamjene (Bubble sort)
Ovaj algoritam se zasniva na poreenju i zamjeni mjesta parova susjednih elemenata i
obavljanja ovog postupka dok se ne sortiraju svi elementi. Kao i u metodi selekcije pro-
lazi po nizu se ponavljaju pri cemu se svaki put najmanji element preostalog dijela niza
premjeta na lijevi kraj niza. Ako se nizovi posmatraju vertikalno a ne horizontalno ele-
mente je moguce interpretirati kao mjehure, pri cemu "tezina" svakog elementa odgovara
njegovom kljucu. Na taj nacin se svaki element poput mjehura podize do pozicije koja
mu pripada. Ovaj metod je stoga poznat pod nazivom BubbleSort.
Bubble sort je jedan od najjednostavnijih algoritama sortiranja. Ovaj algoritam radi tako
da vie puta sekvencijalno prolazi kroz niz, pri cemu se pri svakom prolazu uporeuje svaki
element sa elementom koji se nalazi neposredno iza njega. Ako se nakon poreenja utvrdi
da susjedni elementi nisu u zeljenom poretku, onda elementi meusobno izmjenjuju svoje
pozicije, to ima za posljedicu da se prema kraju niza postepeno pomjeraju elementi sa
vecim vrijednostima ako je zeljeni poredak sortiranja rastuci, ili da se prema kraju niza
postepeno pomjeraju elementi sa manjim vrijednostima ako je zeljeni poredak sortiranja
opadajuci.
U prvom prolazu kroz niz na zadnjem mjestuce se sigurno pozicionirati najveci (najmanji)
element. Na taj nacin sortirani dio niza cini element c [: 1] a nesortirani dio niza cine
elementi
c [0] . c [1] . .... c [: 2]
U sljedecem, drugom prolazu, porede se elementi na pozicijama 0 do :2, te ce se nakon
tog prolaza na poziciju s indeksom :2 sigurno pozicionirati najveci element iz trenutno
nesortiranog dijela niza c[0..:2]. Opcenito, prije nekog i-tog prolaza, za i 1, sortirani
dio niza cine elementi c [: i + 1] . c [: i + 2] . .... c [: 1] dok nesortirani dio niza cine
elementi c[0]. c[1]. . . . . c[: i]. U nekom i-tom prolazu poreenja i izmjene pozicija
susjednih elemenata ce na (: i)-tu poziciju doci najveci element iz nesortiranog dijela
niza c[0..: i]. Sekvencijalni prolazi kroz niz se nastavljaju sve (: 1)-og prolaza kroz
niz odnosno sve dok se na drugu poziciju u nizu s indeksom 1 ne pozicionira odgovarajuci
element. Naime, :-ti prolaz kroz niz nije ni potreban jer je ostao samo jedan element i
samo jedna dostupna pozicija s indeksom 0 pa je prakticno niz nakon (: 1)-og prolaza
vec sortiran.
Algoritam Bubble sort je ilustriran po koracima na slici za jedan primjer pocetnog ne-
sortiranog niza od 6 elemenata. Algoritam ukljucuje : 1 prolaza kroz nesortirani dio
niza, pri cemu svaki prolaz osigurava smjetanje najveceg elementa iz nesortiranog dijela
na zadnju poziciju tog dijela niza. Ta pozicija je na slici za svaki prolaz istaknuta linijom
s donje strane. Okvirom su oznaceni elementi koji se nalaze u sortiranom dijelu niza,
odnosno, elementi koji se nalaze na svojim konacnim pozicijama. U prvom koraku su
oznacene prva pozicija sa indeksom 0 na kojoj se nalazi element 10 i druga pozicija sa
indeksom 1 na kojoj se nalazi element 11. Poto su elementi 10 i 11 u zeljenom poretku,
ne dolazi do zamjene njihovih pozicija. U sljedecem koraku se porede elementi 11 i 3.
92
Buduci da se ovi elementi ne nalaze u zeljenom poretku, dolazi do zamjene njihovih pozi-
cija. Prvi prolaz kroz niz se nastavlja sve dok varijabla , ne dostigne vrijednost , = 5.
Nakon prvog prolaza ce se najveci element 11 nalaziti na svojoj konacnoj poziciji s in-
deksom i = 5. U ovom trenutku sortirani dio niza cini jedino element 11 dok svi ostali
elementi predstavljaju nesortirani dio niza.
U drugom prolazu kroz niz (i = 4) na poziciju s indeksom 4 ce se pozicionirati najveci
element iz nesortiranog dijela niza a to je element 10. Nakon drugog prolaza sortirani
dio niza cine elementi 10 i 11, a nesortirani dio niza cine elementi 3, 4, 9 i 2. Opisani
postupak se ponavlja za sve ostale vrijednosti varijable i (i = 3. 2. 1), sve dok se na drugo
mjesto u nizu ne umetne element 3. Jedini preostali element u nesortiranom dijelu niza
je element 2, koji na kraju zauzima jedinu slobodnu poziciju s indeksom 0. Svi koraci
algoritma Bubble sort za ovaj primjer su takoer ilustrirani na slici.
0 1 2 3 4 5
10 11 3 4 9 2 c
10 11 3 4 9 2 /
10 3 11 4 9 2 c
10 3 4 11 9 2 d
10 3 4 9 11 2 c
10 3 4 9 2 11 ,
10 3 4 9 2 11 q
3 10 4 9 2 11 /
3 4 10 9 2 11 i
3 4 9 10 2 11 ,
3 4 9 2 10 11 /
3 4 9 2 10 11 |
3 4 9 2 10 11 :
3 4 2 9 10 11 :
3 4 2 9 10 11 o
3 2 4 9 10 11 j
2 3 4 9 10 11
Table 27: Bubble sort - Ilustracija
Ovaj algoritam je prikazan u obliku procedure u nastavku. Ulaz u proceduru je niz c koji
se sortira. Vanjskom for petljom se implementira 1n.i:c[c] 1 prolaza kroz nesortirani
dio niza, cime se osigurava smjetanje najveceg elementa na zadnju poziciju tog dijela
niza. Unutarnjom for petljom se implementira jedan prolaz u kojem se nakon poreenja
susjednih elemenata i utvrivanja da nisu u zeljenom poretku izmjenjuju njihove pozicije.
Pretpostavimo da je ulazni niz c vec sortiran. U toj situaciji ce broj potrebnih operacija
ostati opet isti, bez obzira na pocetnu ureenost niza. Meutim, da bi se u odreenoj
mjeri povecala ekasnost, moguce je oblikovati takvu varijantu algoritma Bubble sort
koja ce detektirati prolaz kroz niz u kojem nije dolo ni do jedne zamjene pozicija, to
je zapravo znak da je niz vec sortiran. Nakon takve detekcije proces sortiranja se moze
prekinuti da bi se izbjegle nepotrebne operacije poreenja. Postoji mogucnost da je samo
jedan dio niza vec sortiran pa se ekasnost moze povecati i tako to ce se identicirati
93
Za 1 1n.i:c [c] 1 do 1 raditi
{
Za , 1 do i raditi
{
AkoJe (c [, 1] c [,]) tada
{
c [, 1] c [,]
}
}
}
taj dio niza kojeg u sljedecoj iteraciji nece biti potrebno prolaziti. Detekciju prolaza kroz
niz u kojem nije dolo ni do jedne zamjene pozicija, a isto tako i identiciranje dijela
niza koji je vec sortiran, moze se napraviti tako da se u svakom prolazu kroz niz zapamti
pozicija sa najvecim indeksom , na kojoj je izvrena zamjena. Neka se, na primjer, sortira
niz koji ima : = 9 elemenata, te da je nakon treceg prolaza raspored elemenata kao na
slici.
0 1 2 3 4 5 6 7 8
i = 5. , = 1. j = 1 27 24 17 28 31 33 35 38 43 a
i = 5. , = 2. j = 2 24 27 17 28 31 33 35 38 43 b
i = 5. , = 3. j = 2 24 17 27 28 31 33 35 38 43 c
i = 5. , = 4. j = 2 24 17 27 28 31 33 35 38 43 d
i = 5. , = 5. j = 2 24 17 27 28 31 33 35 38 43 e
Table 28: Bubble sort - iteracija
U cetvrtom prolazu varijabla i ima vrijednost 5 dok se vrijednost varijable , mijenja od
1 do 5. U ovom cetvrtom prolazu zadnja izmjena je izvrena kada je vrijednost varijable
, bila 2 to zapravo znaci da su elementi na pozicijama s indeksom 2, 3, 4 i 5 vec u
pravilnom poretku. Pozicija zadnje zamjene je zapamcena u varijabli j. Nadalje, to znaci
da u sljedecem prolazu nece biti potrebno porediti elemente koji se nalaze na pozicijama
s indeksom vecim ili jednakim od j = 2 pa se zapravo nakon cetvrtog prolaza na svojim
konacnim pozicijama ne nalaze samo 4 vec 7 elemenata. Ako je nakon nekog od prolaza
kroz niz vrijednost varijable j = 0, to je znak da je citav preostali dio niza zapravo vec
sortiran, pa se proces sortiranja moze prekinuti.
Prethodno opisana mogucnost poboljanja je data u narednom algoritmu. Varijabla j se
koristi da se zapamti pozicija iza koje u nekom prolazu kroz niz nije bilo izmjene pozicija.
Prolazi se izvode u sklopu repeat-until petlje, te pri svakom novom prolazu se vrijednost
varijable j postavlja na nulu. Ako se dogodi da u nekom prolazu vec postoji sortiran
poredak elemenata tada ce i na kraju prolaza biti j = 0 pa ce algoritam zavriti svoj
rad. Unutarnjom for petljom ostvaruje se jedan prolaz kroz nesortirani dio niza ali samo
do pozicije i = j 1 jer na pozicijama iznad j nije bilo izmjena, pa je taj dio niza vec
sortiran.
Treca mogucnost poboljanja je da se premjetanje vri naizmjenicno u oba pravca tako
da se u jednom smjeru premjetaju elementi na "lake" pozicije a u obratnom na "teze"
94
j 1n.i:c [c]
Ponavljati
{
i j 1
j 0
Za , 1 do i raditi
{
AkoJe (c [, 1] c [,]) tada
{
c [, 1] c [,]
j
}
}
}
SveDokNije(j = 0)
pozicije. Ilustracija ovog algoritma, pod nazivom ShakerSort je na tabeli 11.
1 2 3 3 4 4
1 8 8 7 7 4
Smjer | |
44 06 06 06 06
55 44 44 12 12
12 55 12 44 18
42 12 42 18 42
94 42 55 42 44
18 94 18 55 55
06 18 67 67 67
67 67 94 94 94
Table 29: Shaker Sort - ilustracija
Pseudokod za ShakerSort algoritam je dat na narednom algoritmu.
Analiza BubbleSort algoritma pokazuje da je u osnovnoj verziji broj poreenja jednak
C = (:
2
:) ,2
dok je minimalni, prosjecni i maksimalni broj zamjena (premjetanja) jednak
`
min
= 0. `
avg
= 3 (:
2
:) ,2. `
max
= 3 (:
2
:) ,4
Analiza poboljanih verzija, posebno ShakerSort-a, je dosta slozena. Minimalni broj
poreenja je C
m
= :1. Knuth smatra da je prosjecan broj prolaza u poboljanom Bub-
bleSort algoritmu proporcionalan sa :/
1
_
: a prosjecan broj poreenja proporcionalan
sa (1,2) (:
2
:(/
2
+ ln :)). Predlozena poboljanja ne uticu na broj premjetanja, oni
jedino skracuju nepotrebna binarna poreenja. Nazalost, zamjena dva elementa je mnogo
ceca operacija tako da se ne dobiju ocekivana poboljanja. Pokazuje se da je BubbleSort
95
Procedura ShakerSort
Ulaz : Niz c
n

Izlaz : Sortiran niz c


n

Inicirati ,. /. 1. 1. r
1 2; 1 :; / :
Ponavljati
{
Za , = 1. 1. 1
{
Ako je c [, 1] c [,] tada
{
r c [, 1] ; i:
c [, 1] c [,]
c [,] r
/ 1
}
}
1 / + 1
Za , = 1. 1. 1
{
Ako je c [, 1] c [,] tada
{
r c [, 1] ;
c [, 1] c [,]
c [,] r
/ 1
}
}
1 / 1
}
SveDok vrijedi 1 1
po karakteristikama negdje izmeu sortiranja umetanjem i sortiranja zamjenom. Fak-
ticki, BubbleSort ne donosi nita novo osim privlacnog naziva. ShakerSort se uspjeno
koristi u slucajevima kada je niz dosta sortiran, to se u praksi dosta rijetko deava.
Moguce je pokazati da je prosjecno rastojanje za koje se pojedini element pomjera jed-
nako :,3 "mjesta". Svi strogi nacini sortiranja fakticki element na pojedinom koraku
pomjeraju za jednu poziciju to je razlog da trebaju C(:
2
) takvih prolaza. U skladu sa
tim, poboljanja se mogu uvesti ako se usvoji princip da se vri razmjena elemenata na
vecem rastojanju.
U nastavku je pregled poboljanja svake od navedene stroge metode sortiranja.
96
10.3 Poboljane metode (slozenost :log :)
10.3.1 Merge sort
Algoritam Merge sort koristi strategiju podijeli-pa-vladaj kod koje se do rjeenja nekog
problema dolazi smanjivanjem na manje dijelove sve dok se on ne reducira na tzv. os-
novni slucaj koji se moze rijeiti direktno. Ovaj algoritam se temelji na ideji da se iz
sortiranih podnizova na ekasan nacin mogu spajanjem tih podnizova dobiti novi sorti-
rani podnizovi. Prije faze spajanja sortiranih podnizova, koja zapravo predstavlja drugu
fazu algoritma, Merge sort u svojoj prvoj fazi dijeli pocetni nesortirani niz na manje i
manje podnizove. Minimalni niz je niz sa samo jednim elementom, pa je takav niz sam
po sebi vec sortiran. Zato algoritam Merge sort dijeli pocetni nesortirani niz na manje i
manje dijelove, sve dok se ne dobiju nizovi sa samo jednim elementom. Nakon te prve faze
dijeljenja, slijedi druga faza spajanja sortiranih podnizova u kojoj se od manjih sortiranih
podnizova njihovim objedinjavanjem stvaraju sve veci i veci sortirani podnizovi, sve dok
se na kraju ove faze ne kreira cijeli sortirani niz.
Merge sort se moze realizovati kao rekurzivni algoritam, pri cemu se na svakom nivou
rekurzije obavljaju sljedeci koraci:
dijeljenje pocetnog nesortiranog niza na dva podniza od kojih svaki ima po :,2
elemenata;
rekurzivno sortiranje dobijena dva podniza koristeci Merge sort;
spajanje sortiranih podnizova.
U nastavku je procedura `c:qcoo:t koja predstavlja rekurzivnu implementaciju algo-
ritma.
// Procedura Merge Sort
`c:qcoo:t(c. |. n)
AkoJe (n |) tada
{
j (| +n 1) ,2|
j + 1
`c:qcoo:t (c. |. j)
`c:qcoo:t (c. . n)
`c:qc (c. |. j. . n)
}
Ulazni argument c predstavlja niz koji se treba sortirati. Argument | oznacava indeks
prve pozicije a argument n oznacava indeks zadnje pozicije podniza c [|..n] koji se sor-
tira. Postupak sortiranja se ostvaruje tako to se ulazni podniz c [|..n] dijeli na dva
podniza a zatim se proces nastavlja rekurzivnim pozivima procedure `c:qcoo:t koji
kao ulazne nizove imaju podnizove nastale dijeljenjem. Dijeljenje ulaznog niza na dva
podniza se ostvaruje izracunavanjem vrijednosti varijabli j i . Varijabla j predstavlja
indeks zadnje pozicije prvog podniza, a vrijednost varijable oznacava prvu poziciju dru-
gog podniza. Na taj nacin ulazni niz c [|..n] je podijeljen na podnizove c [|..j] i c [..n].
97
U proceduri `c:qcoo:t se nalaze dva rekurzivna poziva ove procedure. Prvim pozivom
`c:qcoo:t (c. |. j) proces se nastavlja nad prvom polovinom podijeljenog niza, dok se
pozivom `c:qcoo:t (c. . n) proces nastavlja nad drugom polovinom podijeljenog niza.
Nesortirani niz se rekurzivno dijeli na podnizove, sve dok se ne dobiju podnizovi koji
sadrze samo jedan element, tj. dok vrijedi n |. Nakon povratka iz obje ove proce-
dure na svakom nivou rekurzije se pozivom procedure `c:qc obavlja spajanje sortiranih
podnizova. Taj postupak, opisan procedurom `c:qc, je dat kasnije. Na primjer, nakon
povratka iz obje procedure `c:qcoo:t na zadnjem nivou rekurzije, kada podnizovi nastali
dijeljenjem imaju velicine 1 poziva se procedura `c:qc za spajanje tih podnizova da bi
se kreirao niz velicine 2. Na sljedecem, viem nivou, su dva sortirana niza velicine 2 koji
ce se spojiti u sortirani podniz velicine 4. Ovaj proces se nastavlja sve dok se ne doe do
prvog poziva, koji spaja dva sortirana podniza koji sadrze po pola elemenata pocetnog
nesortiranog niza.
Merge Sort - ilustracija
Na slici je ilustriran proces sortiranja algoritmom Merge sort za niz sa 13 elemenata. Al-
goritam u prvoj fazi dijeli pocetni niz na polovine rekurzivnim procesom sve dok rezultira-
juci podnizovi ne sadrze samo jedan element. Nakon toga se prelazi u drugu fazu, u kojoj
nakon zavravanja rekurzivnih poziva procedure `c:qcoo:t na svakom nivou rekurzije
imamo procese spajanja podnizova. Kretanjem prema prvom rekurzivnom pozivu pod-
nizovi se spajaju, te se oblikuju sve veci i veci sortirani podnizovi.
Kljucni koraci u algoritmu Merge sort su koraci spajanja dva sortirana podniza. Neka su
nizovi / [0..5] i / [6..12] sortirani, naprimjer, u rastucem poretku. Da bi ta dva sortirana
podniza bila spojena u jedan sortirani niz c prvo treba odrediti najmanji element iz oba
podniza. Sigurno je da je najmanji element ili / [0] ili / [6]. Isto tako, najveci element je
ili / [5] ili / [12]. Operacija spajanja pocinje tako da se u c [0] smjesti manji od elemenata
/ [0] ili [6]. Neka je / [0] < / [6] pa je tada c [0] = / [0]. Nisu rasporeeni elementi / [1..5] i
/ [6..12]. Uc [1] se treba smjestiti manji od elemenata na prvim pozicijama nerasporeenih
dijelova podnizova / [1..5] i / [6..12]. Dakle, u c [1] se treba smjestiti manji od elemenata:
98
/ [1] ili / [6]. Neka je manji element / [1] pa je c [1] = / [1]. Sada su nerasporeeni elementi
/ [2..5] i / [6..12].
// Procedura Merge
`c:qc (c. |. j. . n)
i 0
, |
/ |
Za (: 0) do n | raditi
{
/ [:] c [| +:]
}
SveDokJe (i _ j |&, _ n |) raditi
{
AkoJe (/ [i] < / [,]) tada
{
c [/] / [i]
i i + 1
}
Inace
{
c [/] [,]
, , + 1
}
/ / + 1
}
SveDokJe (i _ j 1) raditi
{
c [/] / [i]
/ / + 1
i i + 1
}
SveDokJe (, _ n |) raditi
{
c [/] / [,]
/ / + 1
, , + 1
}
Moze se zakljuciti da za formiranje sortiranog niza c treba mehanizam koji ce omoguciti
oznacavanje rasporeenih i nerasporeenih elemenata iz podnizova / [0..5] i / [6..12]. Ovaj
mehanizam pracenja se realizuje uvoenjem dva indeksa za spomenute podnizove, koji
ce oznacavati poziciju u oba podniza na kojoj se trenutno nalaze kandidati za minimalni
element od preostalih nerasporeenih elemenata. Neka je i indeks za pracenje podniza
/ [0..5] a , indeks za pracenje podniza / [6..12]. Svakim odreivanjem minimalnog ele-
menta taj element se smjeta u niz c a indeks pridruzen podnizu koji je u tom koraku
sadrzavao minimalni element se povecava za 1. Dakle, preostali nerasporeeni elementi u
99
podnizu / [0..5] ce biti elementi / [i..5] a u podnizu / [6..12] ce biti nerasporeeni elementi
/ [,..5]. U jednom trenutku ce se rasporediti svi elementi iz jednog od podnizova pa ce se
preostali elementi iz podniza u kojem je ostalo jo nerasporeenih elemenata jednostavno
nadovezati na spojeni niz. Postupak spajanja je opisan procedurom `c:qc.
Ulazni argument c oznacava niz u kojem su smjeteni podnizovi. Argumenti | i oz-
nacavaju indekse pocetnih pozicija prvog i drugog podniza, respektivno. Argumenti j
i n oznacavaju indekse zadnjih pozicija prvog i drugog podniza, respektivno. Varijabla
i u proceduri `c:qc je varijabla pridruzena prvom podnizu i oznacava indeks pozicije
iznad koje su jo nerasporeeni elementi iz prvog podniza. Varijabla , je pridruzena
drugom podnizu i oznacava indeks pozicije iznad koje su jo nerasporeeni elementi iz
drugog podniza. U proceduri `c:qc se koristi i privremeni niz / u kojem se privremeno
smjetaju sortirani podnizovi koji se trebaju spojiti. Varijabla / oznacava indeks pozicije
u rezultirajucem nizu c na koju ce se smjestiti trenutno odreeni minimalni element iz
sortiranih podnizova.
Iz algoritma se vidi da je na prvom nivou rekurzije za oblikovanje konacnog sortiranog
niza potrebno jo spojiti podnizove / [0..6] i / [6..12]. Algoritam spajanja `c:qc ce biti
ilustrovan za slucaj spajanja na prvom nivou rekurzije, na tabeli 12.
0 1 2 3 4 5 6 7 8 9 10 11 12
Niz B 4 11 16 18 20 25 5 7 10 14 28 32 35 a
i = 0. , = 6. / = 0 4 b
i = 1. , = 7. / = 1 4 5 c
i = 1. , = 7. / = 2 4 5 7 d
i = 1. , = 8. / = 3 4 5 7 10 e
i = 1. , = 9. / = 4 4 5 7 10 11 f
i = 2. , = 9. / = 5 4 5 7 10 11 14 g
i = 2. , = 10. / = 6 4 5 7 10 11 14 16 h
i = 3. , = 10. / = 7 4 5 7 10 11 14 16 18 i
i = 4. , = 10. / = 8 4 5 7 10 11 14 16 18 20 j
i = 5. , = 10. / = 9 4 5 7 10 11 14 16 18 20 25 k
i = 5. , = 10. / = 10 4 5 7 10 11 14 16 18 20 25 28 l
i = 5. , = 11. / = 11 4 5 7 10 11 14 16 18 20 25 28 32 m
i = 5. , = 12. / = 12 4 5 7 10 11 14 16 18 20 25 28 32 35 n
Table 30: Merge Sort
Varijabla i = 0 na pocetku procesa predstavlja indeks pozicije od koje pocinje prvi
podniz a varijabla , = 6 oznacava indeks pozicije od koje pocinje drugi podniz. Varijabla
/ oznacava poziciju u rezultirajucem nizu c na koju se u nekom od pojedinih koraka
spajanja treba smjestiti manji od elemenata / [i] ili / [,]. Ako je manji element / [i] tada
se u rezultirajuci niz c na poziciju / smjeta taj element a indeks i povecava. Tada podniz
[i..5] predstavlja trenutno nerasporeene elemente iz prvog podniza.
Ako se utvrdi da je manji element / [,] tada se u rezultirajuci niz c na poziciju / smjeta taj
element pa se povecava indeks ,. Tada podniz / [,..12] predstavlja trenutno nerasporeene
elemente iz drugog podniza. Nakon svakog smjetanja elementa u rezultirajuci niz c,
100
inkrementira se varijabla /. Varijable i i , inicijalno imaju vrijednosti i = 0, , = 6,
/ = 0 (b). Poreenjem elemenata / [0] i / [6] vidi se da je manji element / [0] = 4 pa
se taj element u nizu c smjeta na poziciju / = 0, c[0] = 4. Poto je u ovom koraku
izabran element iz prve polovine, inkrementira se varijabla i kao i varijabla /, koja se
inkrementira u svakom pojedinom koraku smjetanja elemenata u rezultirajuci niz c. U
ovom trenutku vrijednosti varijabli su: i = 1, , = 6, / = 1. U sljedecem koraku se izabire
manji od elemenata / [1] i / [6]; vidi se da je manji element / [6] = 5 pa se taj element u
nizu c smjeta na poziciju / = 1, c [1] = 5 (c). Na tabeli su ilustrovani i ostali koraci
spajanja podnizova. U koraku k svi elementi iz prvog podniza (/[0..5]) su vec rasporeeni
u rezultirajuci niz c pa je u nastavku algoritamskog procesa potrebno samo da se preostali
elementi (/[10..12]) jednostavno dodaju u rezultirajuci niz c (l do n).
10.3.2 Quick sort
Ovaj sort radi rekurzivno tako da se iz niza najprije selektira "pivot vrijednost". Zatim
se niz dijeli na elemente koji su manji i koji su veci od pivota a zatim se rekurzivno
sortira svaki od dijelova. Za QuickSort se, generalno, smatra da je najbrzi od algoritama
sortiranja (na modernim mainama). Jedno od objanjenja je da unutranja petlja poredi
elemente sa jednom vrijednosti pivota koja je pohranjena u registru za brz pristup. Drugi
algoritmi porede dva elementa niza. Ovo se naziva algoritmom lokalnog sortiranja jer ne
koristi drugi niz za pohranu. Nije stabilan. Postoji stabilna verzija QuickSort algoritma
ali ona nije lokalna. Ovaj algoritam je (:log :) u ocekivanom i (:
2
) u najgorem
slucaju. Ako je implementiran prikladno, vjerovatnoca dace algoritam trajati asimptotski
duze (pod pretpostavkom da je pivot odabran slucajno) je ekstremno mala za veliko :.
Algoritam Quick sort takoer koristi strategiju podijeli, pa vladaj. Ulazni niz se dijeli
na dva dijela tako to se taj niz reorganizira tako da su svi elementi u prvom donjem
dijelu manji od svih elemenata u drugom gornjem dijelu niza. Ta dva dijela nakon
reorganizacije su nesortirana i razdvojena su elementom koji se naziva pivot i koji se
nalazi na nekoj poziciji ,. Dakle, donji dio cine elementi koji imaju vrijednost manju ili
jednaku vrijednosti pivota (c [i] _ jiot, i = 0. 1. . . . . , 1) a gornji dio cine elementi koji
imaju vrijednost vecu ili jednaku vrijednosti pivota (c[i] _ jiot, i = ,+1. ,+2. . . . . :1).
Moguci su razliciti nacini izbora pivota. Na primjer, pivot se moze napraviti tako da se
uzme prvi element niza koji se dijeli, mada postoje i ekasniji nacini. Idealno, pivot
element bi trebao dijeliti niz na dva podniza sa jednakim brojem elemenata. Zbog nacina
na koji je ulazni niz reorganiziran moze se zakljuciti da je pivot element pozicioniran na
svoju konacnu poziciju , te se u daljnjem postupku vie nece pomjerati. Nadalje, moze
se zakljuciti da se sortiranje moze nastaviti tako da se isti algoritam rekurzivno primijeni
na dobivena dva dijela ulaznog niza. Rekurzivni postupak se nastavlja sve dok se ne
postigne da rezultirajuci dijelovi imaju samo jedan element. Zavretkom rekurzivnog
postupka dobiva se sortirani niz.
Kljucni dio u algoritmu Quick sort je nacin reorganizacije niza na dvije particije odvojene
pivotom, bez koritenja dodatnog pomocnog memorijskog prostora. Taj nacin je opisan
funkcijom 1c:tici,c u tabeli. Funkcija 1c:tici,c vraca indeks pozicije na kojoj je sm-
jeten pivot. Neka se kao pivot koristi prvi element u nizu. U primjeru na tabeli za pivot
se uzima element 42 (oznacen tankom donjom crtom). Funkcijom 1c:tici,c potrebno je
reorganizirati niz tako da se pronae odgovarajuca pozicija za pivota te da svi elementi
manji od njega budu na pozicijama ispred njega a svi veci elementi da budu na pozicijama
101
iza njega. Na tabeli j oznacava poziciju elemenata koji se trenutno porede sa pivotom.
Kada se pronae prvi element veci od pivota, tada se za oznacavanje pozicija elemenata
koji se trenutno porede sa pivotom koristi oznaka i. Te pozicije su na tabeli istaknute
donjom podebljanom crtom. Pocevi od drugog elementa u nizu zapocinje pronalazenje
prvog elementa koji je veci ili jednak pivotu (42) te na poziciji s indeksom 3 pronalazimo
prvi takav element a to je 54. Pronaena pozicija j = 3 se oznacava kao privremeni poce-
tak druge particije (koja ce se nalaziti iza pivota) to je oznaceno osjencenom pozicijom.
Postupak se nastavlja poreenjem pivota i elemenata iz niza (i = j + 1. j + 2. . . . . : 1)
koji se nalaze iza oznacene pozicije. Kada se pronae element koji je veci ili jednak piv-
otu, taj element se ostavlja na svojoj poziciji, te se nastavlja proces poreenja pivota i
elemenata na preostalim pozicijama. Na primjer, na tabeli na poziciji i = 4 je element 49
pa taj element ostaje na svojoj poziciji. Kada se pronae element koji je manji od pivota,
tada taj element i element na poziciji j razmjenjuju pozicije, te se oznaka j povecava za
1 tako da oznaka j pokazuje na novi pocetak druge particije. Na primjer, na poziciji s
indeksom i = 5 se nalazi element 22 koji je manji od pivota (42), pa element 22 razm-
jenjuje poziciju s elementom na poziciji j a to je 54. Istovremeno, privremena vrijednost
indeksa j za pocetak druge particije se povecava za 1 pa sada ima vrijednost j = 4. Ovaj
proces se nastavlja sve dok se ne doe do kraja niza. Svi ostali koraci u reorganizaciji
niza s ciljem njegovog particioniranja su takoer ilustrirani na tabeli.
Pri kraju procesa, kada indeks i dostigne vrijednost 9 (i = :1) pivot se jo uvijek nalazi
na prvoj poziciji. Meutim, niz je prethodno reorganiziran tako da su svi elementi od
pozicije 1 do pozicije 4 (j1) manji od pivota, dok su elementi na pozicijama 5 do 9 (j do
:1) veci od pivota. Poto je cilj da pivot dijeli te dvije grupe elemenata, potrebno je jo
razmjeniti pozicije pivota i elementa na poziciji 4 (j1), cime se zavrava particioniranje
niza. Dakle, na kraju opisanog procesa, pivot element 42 se nalazi na poziciji 4. Svi
elementi na pozicijama s indeksima 0 do 3 su manji od pivot elementa 42 dok su svi
elementi na pozicijama 5 do 9 veci od pivot elementa.
0 1 2 3 4 5 6 7 8 9
j = 1 42 36 17 54 49 22 63 57 20 46
j = 2 42 36 17 54 49 22 63 57 20 46
j = 3 42 36 17 54 49 22 63 57 20 46
j = 3. i = 4 42 36 17 54 49 22 63 57 20 46
j = 3. i = 5 42 36 17 54 49 22 63 57 20 46
j = 4. i = 5 42 36 17 22 49 54 63 57 20 46
j = 4. i = 6 42 36 17 22 49 54 63 57 20 46
j = 4. i = 7 42 36 17 22 49 54 63 57 20 46
j = 4. i = 8 42 36 17 22 49 54 63 57 20 46
j = 5. i = 8 42 36 17 22 20 54 63 57 49 46
j = 5. i = 9 42 36 17 22 20 54 63 57 49 46
, = 4. j = 5 20 36 17 22 42 54 63 57 49 46
Table 31: Tabela 8. Quick Sort - ilustracija
Zamjena pozicija pivot elementa i elementa na poziciji j1 mijenja poredak elemenata u
donjoj particiji. Na primjer, na tabeli je nakon izmjene poredak elemenata koji pripadaju
donjoj particiji (36. 17. 22. 20) promijenjen u poredak (20. 36. 17. 22). To, naravno, utice
102
na izbor pivota u sljedecim fazama algoritma, s tim da u prosjecnom slucaju to ne utice na
ekasnost algoritma. Algoritam kojim se na prethodno opisani nacin moze particionirati
niz dat je u nastavku.
// Procedura Particija
1c:tici,c (c. j:i. .cd:,i)
jiot c [j:i]
j j:i + 1
SveDokJe (j _ .cd:,i&c [j] < jiot) raditi
{
j j + 1
}
ZaSve (i j + 1) do .cd:,i raditi
{
AkoJe (c [i] < jiot) tada
{
c [i] c [j]
j j + 1
}
}
c [j:i] c [j 1]
Vrati j 1
Nakon opisa postupka particioniranja nizova moguce je opisati rekurzivnu implementaciju.
Algoritam je opisan procedurom QuickSort u nastavku. Poto na pocetku citav niz
predstavlja jednu particiju, algoritam se poziva sa pocetnim argumentima j:i = 0 i
.cd:,i = : 1.
// Procedura Quick sort
Qnic/oo:t (c. j:i. .cd:,i)
AkoJe (j:i < .cd:,i) tada
{
, 1c:tici,c (c. j:i. .cd:,i)
Qnic/oo:t (c. j:i. , 1)
Qnic/oo:t (c. , + 1. .cd:,i)
}
Mehanizam rada procedure Quick Sort je ilustrovan na slici u nastavku.
103
Inicijalni raspored elemenata niza je prikazan prvim rasporedom na tabeli 13 (na kojoj
je ilustrovan postupak particije) a na slici je raspored elemenata u nizu nakon prve par-
ticije. Izabrani pivot u pojedinim fazama je oznacen pojacno a elementi koji su zauzeli
svoje konacne pozicije su uokvireni obicnom linijom. Isprekidanim linijama su uokvireni
elementi koji u pojedinim fazama izvravanja algoritma cine podnizove koji u nastavku
algoritma ulaze u proces particije. U sljedecem koraku kao pivot se uzima element 20, a
proces particije se nastavlja sa podnizom koji cine elementi koji se nalaze na pozicijama
0 do 3. Rezultat particije je prikazan u liniji c. Pivot element 20 je zauzeo svoje konacno
mjesto na poziciji s indeksom 1, donju particiju cini samo jedan element (17), dok gornju
particiju cine dva elementa (36 i 22). Na linijama d do h su ilustrirane i ostale faze u
radu algoritma.
104
11 Slucajni brojevi
11.1 Uvod
Postoje dva osnovna pitanja kada su u pitanju slucajni brojevi : njihova denicija i nacin
njihovog koritenja. Jednu od poznatijih denicija slucajnih brojeva dao je prof. D. H.
Lehmer (1951), pionir racunarske tehnologije i racunarske teorije brojeva :
Slucajni brojevi su nejasna notacija u kojoj je svaki clan nepredvidiv u odnosu na
inicijalne velicine i cije cifre prolaze odreen broj testova koji se tradicionalno koriste od
strane statisticara.
Slucajni brojevi se koriste u jako puno podrucja nauke i prakse. Jedno od najbitnijih po-
drucja njihovog koritenja je modeliranje procesa na nacin da se u poznati ili pretpostavl-
jeni model prirodnog ili nekog drugog procesa unose slucajni brojevi kojima se simuliraju
stvarne situacije i vri analiza. Jasno je da je ovo najceci a u nekim situacijama i jedini
nacin da se neki sistem modelira, planira ili analizira, posebno u situacijama kada ulazni
podaci u bilo kom smislu mogu imati slucajnu prirodu. Jedan od najpoznatijih metoda
je tzv. Monte Carlo metoda. Slucajni brojevi su ekstremno vazni u kriptograji i ovaj
aspekt je imao odlucujuci uticaj na razvoj metoda generisanja slucajnih brojeva. U tim
situacijama se mora osigurati izvor slucajnih brojeva.
Mnoge primjene slucajnosti su dovele do razvoja vie razlicitih metoda generisanja sluca-
jnih podataka. Mnoge od njih postoje od antickih vremena ukljucujuci kockicu, bacanje
novcica, mijeanje karata i mnoge druge tehnike. Zbog mehanicke prirode ovih tehnika
generisanje velikog broja dovoljno slucajnih brojeva, to je vazno sa stanovita statistike
i prakitcne primjene, iziskuje puno napora i/ili vremena. Stoga se rezultati nekada priku-
pljaju i distribuiraju u obliku tablica slucajnih brojeva. Nakon renesanse kompjuterski
podrzanih generatora slucajnih brojeva, sve je veci broj zvanicnih lutrija i igara na srecu
koje koriste generatore umjesto tradicionalnih metoda izvlacenja. Ovi generatori se danas
koriste kako bi se ustanovili eventualni nedostaci modernih slot maina.
Generator slucajnih brojeva (engl. krat. RNG random number generator) je ureaj
ili algoritam koji kao izlaz vraca statisticki potpuno nezavisne i nepredvidljive vrijed-
nosti u obliku brojevnog niza. U svrhu generiranja (pravih) slucajnih brojeva potrebno
je promatranje i biljezenje neke nepredvidljive prirodne pojave. Za generisanje stvarno
slucajnih brojeva koriste se hardverski ureaji, u dananje vrijeme razni dodaci na per-
sonalni racunar. Tada su slucajni brojevi rezultat zickih procesa unutar ureaja.
Sklopovski generatori slucajnih brojeva koriste nepredvidljivost koja se pojalvjuje kod
nekih zikalnih pojava kao to su:
termicki um poluvodicke diode ili elektrickog otpornika
vrijeme izmeu dviju cesticnih emisija tijekom radioaktivnog raspadanja
nestabilnost frekvencija slobodnog oscilatora
naboj kondenzatora nakon zadanog perioda punjenja
promjene latentnog vremena citanja uzrokovane zracnim turbulencijama unutar
kucita cvrstog diska
105
zvuk iz mikrofona ili slika iz kamere
Procesi na kojima se mogu bazirati programski generatori slucajnih brojeva su:
ocitavanje sistemskog sata
vremenski interval izmeu dva pritiska na tastaturu i/ili mi
sadrzaj ulazno/izlaznih bafera pojedinih racunarskih komponenti (tastatura, disk,
...)
sadrzaj radne memorije
sadrzaj procesorskih registara
stanje operativnog sistema kao to je opterecenje mreze i/ili procesora
Nedostatak ove vrste generatora slucajnih brojeva je njihova neponovljivost i sporost.
Zbog deterministicke prirode racunara, naziv za generisanje slucajnih brojeva obicno
dobija preks "pseudo" (lat. laz). Racunarski algoritmi, ma koliko dobri, ne mogu
generisati potpuno slucajne brojeve vec brojeve koji u vecoj ili manjoj mjeri simuliraju
slucajnost izbora pa se stoga zovu pseudoslucajni brojevi. Generator pseudoslucajnih
brojeva (PRNG engl. krat. za Pseudo Random Number Generator) je deterministicki
algoritam koji za datu slucajnu vrijednost velicine / bitova, vraca brojni niz velicine |
/ koji se ponaa kao da je slucajan. Ulazna vrijednost se obicno naziva "sjeme" (engl.
seed), dok se izlazni niz naziva pseudoslucajni brojevni niz (engl. pseudorandom number
sequence). Jedna od dobrih svojstava ove vrste generatora je ponovljivost rezultata,
odnosno, za jednake vrijednosti sjemena dobivaju se identicni izlazni nizovi, to nam
omogucuje ponavljanje simulacija.
S obzirom da je generator pseudoslucajnih brojeva deterministicki algoritam nizovi bro-
jeva koji on generie imaju jedno nezeljeno svojstvo : periodicnost (engl. periodicity).
Ovo je, ipak, ogranicen problem. Ocekivani period se udvostrucuje svakim dodatnim
bitom koritene memorije.
U primjeni, mnogi cesto koriteni generatori pseudoslucajnih brojeva u nizovima koje
generiu sadrze nepozeljne smetnje koje mogu uzrokovati pad na nekim statistickim
testovima slucajnosti. U njih se mogu ubrojati :
period koji je manji od ocekivanog
slaba dimenzionalnost
zavisnost susjednih elemenata niza
neki nizovi bitova su manje slucajni od drugih
nedostatak uniformnosti
106
RANDU algoritam je jedan najozloglaenijih ikad koritenih. Koriten je decenijama na
mainframe racunarima. Zbog njegovih loih osobina znacajan dio istrazivackog rada tog
doba koji se oslanjao na njega smatra se manje pouzdanim.
Jedan od interesantnijih brojeva je 0.95012928514718. Ovo je prvi broj koji se producira
od strane generatora slucajnih brojeva koji je ugraen u Matlab. Svi korisnici Matlaba
na bilo kom racunaru dobijaju ovaj broj kao slucajni. Ocigledno je da ovo nije slucajni
broj u smislu u kojem se to moze ocekivati prema intuitivnom shvatanju ovog pojma.
Ako racunar nema pristupa nekom eksternom ureaju kao to je brojac gama zraka ili
sat onda brojevi koje producira ne mogu biti stvarni slucajni brojevi.
Na osnovu metoda koji koriste, softveri za generisanje pseudoslucajnih brojeva se mogu
podijeliti na:
Linearni kongruentni generator- linearni generator slucajnih brojeva
Fibonacijevog generator- dobili su ime zbog slicnosti formule koju koriste sa formu-
lom koja se koristi za dobijanje Fibonacijevog niza
Generator linearno pomjerajuceg registra - brojevi se ne dobijaju aritmetickim vec
logickim operacijama
11.2 Uniformna raspodjela
Uniformna raspodjela je drugi nacin da se kaze da svi dogaaji iz pretpostavljenog skupa
dogaaja imaju istu vjerovatnocu. Naprimjer, prilikom bacanja novcica smatra se da
svaka od strana ima jednaku ansu odnosno jednaku vjerovatnocu. Ista je situacija sa
bacanjem kockice, izvlacenjem karte iz pila i slicno. Jedna od najpoznatijih primjera ove
vrste su igre na srecu u kojima se izvlace kuglice numerisane u odreenom rasponu. U
svim tim slucajevima se polazi od premise da pojedini dogaaji imaju jednaku vjerovat-
nocu.
Za razliku od navedenih tzv. diskretnih dogaaja odnosno dogaaja cija realizacija moze
biti element nekog konacnog ili prebrojivog skupa, moguce je govoriti i o neprekidnom
slucaju uniformne distribucije a to je vjerovatnoca da se odabere tacka sa intervala [c. /].
Vjerovatnoca izbora svake od tacaka sa tog intervala je
1
/ c
. Najcece se uzima interval
[0. 1] pa se odgovarajucim transformacijama dobijaju brojevi iz zeljenog intervala. Kako
izgledaju te transformacije ?
Ovdje je pogodno objasniti na koji nacin se uniformno distribuirani podaci mogu koris-
titi za simulacije jednako vjerovatnih dogaaja. Pretpostavimo da je potrebno racunarski
simulirati bacanje kockice. Najprije se izgenerie slucajni broj iz intervala [0. 1], naprim-
jer r. Nakon toga se ispituje kojem od intervala [0. 1,6], [1,6. 2,6], ..., [5,6. 1] odnosno
c
k
=
_
/ 1
6
.
/
6
_
, / = 1. .... 6, pripada dobijeni broj i prema tome se kaze da je simuliranim
"bacanjem" dobijen broj /. U slucaju "bacanja novcica" intervali su ocito c
1
= [0. 1,2]
i c
2
= [1,2. 1] a svakoj "realizaciji" se prethodno dodijeli znacenje Pismo ili Glava. Ako
postoji potreba da se simulira izvlacenje karte iz pila tada se interval dijeli na 52 pod-
intervala a svakoj "karti" se dodijeli redni broj; realizacija slucajnog broja iz pojedinog
intervala odreuje koja je karta "izvucena". Analogno se postupa i u drugim slucajevima.
107
Ovdje je veoma vazno napomenuti da slucajni brojevi iz uniformne raspodjele mogu biti,
odgovarajucim transformacijama, interpretirani kao brojevi iz zeljene raspodjele. Ovo je
razlog ekstremne vaznosti algoritama za generisanje pseudoslucajnih brojeva iz uniformne
raspodjele.
Ako se traze brojevi iz uniformne raspodjele algoritam mora obezbijediti jednaku ansu za
svaki od brojeva iz datog intervala. U nastavku je razrada nekih najznacajnijih algoritama
ovog tipa.
11.2.1 Linearni kongruenti generator
Lehmer je osmislio multiplikativni kongruentni algoritam koji je osnova mnogih dananjih
generatora slucajnih brojeva. Lehmerovi generatori ukljucuju tri parametra, c. c i : i
inicijalnu vrijednost r
0
koja se zove sjeme (seed). Prema njegovoj deniciji, niz slucajnih
brojeva je denisan izrazom
r
k+1
= (c r
k
+c) mod :
Za c = 13, c = 0, : = 31, r
0
= 1 dobija se sekvenca
1. 13. 14. 27. 10. 6. 16. 22. 7. 29. 5. 3. ...
Prvih 30 clanova ovog niza je permutacija brojeva od 1 do 30 a zatim se sekvenca ponavlja.
Stoga se kaze da ovakav niz ima period :1. Ako se niz pseudoslucajnih cijelih brojeva
podijeli sa : dobijaju se uniformno distribuirani brojevi u pokretnom zarezu iz intervala
[0; 1]. U prethodnom primjeru to je niz
0.0323. 0.4194. 0.4516. 0.8710. 0.3226. 0.1935. 0.5161. ...
U 1960-im Scientic Subroutine Package (SSP) na IBM mainframe racunarima je ukljuci-
vao generator slucajnih brojeva koji se zvao RND ili RANDU. To je bio multiplikativno
kongruentalni algoritam sa parametrima c = 65539, c = 0 i : = 2
31
. Sa internim ob-
likom pohrane (32 bita) aritmetika mod 2
31
se lako izvrava. S obzirom da je c = 2
16
+3
mnozenje se izvravalo pomjeranjem (shift) i dodavanjem. Ovakve pretpostavke su bile
vazne za racunare tog doba ali je dobijena sekvenca veoma nepozeljnih svojstava. Postoje
sljedece relacije:
r
k+2
= (2
16
+ 3) r
k+1
= (2
16
+ 3)
2
r
k
= (2
32
+ 6 2
16
+ 9) r
k
= [6 (2
16
+ 3) 9] r
k
Stoga je
r
k+2
= 6 r
k+1
9 r
k
Rezultat je ekstremno velika korelacija izmeu tri sukcesivna slucajna broja.
Dugo godina je generator uniformno distribuiranih slucajnih brojeva bio multiplikativni
kongruentalni generator sa parametrima c = 7
5
, c = 0, : = 2
31
1 = 2147483647. Ove
vrijednosti su bile preporucene od strane Park i Miller (1988). Starije verzije programa
Matlab generiu slucajne brojeve u obliku /,: za / = 1. .... : 1. Najmanji broj je
108
0.00000000046566 a najveci je 0.99999999953434. Sekvenca se ponavlja nakon neto vie
od dva miliona brojeva. Do prije nekoliko godina ovo je smatrano kako sasvim dovoljno.
Meutim, dananji racunari ovo urade za manje od pola sata.
Generalno gledano, koritenjemosobina kongruentnih brojeva moguce je denisati sljedece
vrste linearnih kongruentnih generatora (LCG) pseudoslucajnih brojeva sa uniformnom
raspodjelom:
Multiplikativni : 2
i
= (2
i1
c) mod :
Mjeoviti : 2
i
= (2
i1
c +/) mod :
Aditivni : 2
i
= (2
i1
c +2
ik
c) mod :
gdje su 2
i
pseudoslucajni brojevi, 2
0
pocetna vrijednost ili sjeme generatora, c multip-
likator, /, c konstante, : modul.
Najceca koritena varijanta je generator oblika
2
i
= (2
i1
c +/) mod :. : = 2
b1
Ovdje je / broj bitova cjelobrojne promjenljive u racunaru. Dokazuje se da je maksimalna
moguca duzina niza generisanih brojeva bez ponavljanja `
max
= :1. Da bi se postiglo
maksimalno moguce `
max
parametri c i 2
0
trebaju zadovoljavati sljedece uslove
c = 8 , 3. , = 1. 2. 3. ...
2
0
= 1. 3. 5. 7. ...
U tom slucaju je :,4 _ `
max
_ :1.
Generatori sa vecim periodima i boljim statistickim svojstvima su mnogo pozeljniji.
Jedna od mogucih alternativa LCG generatorima su rekurzivni generatori vieg reda
(engl. MRG - Multiple Recursive Generator) koji su bazirani na rekurziji vieg reda:
r
n
= (c
1
r
n1
+... +c
k
r
nk
) mod :
Za razliku od LCG generatora sa periodom :, MRG generatori mogu imati periodu
duzine :
k
1 pa u praksi pokazuju mnogo bolja svojstva.
11.2.2 Algoritam Marsaglia
Godine 1995. Matlab je uveo potpuno novu vrstu generatora slucajnih brojeva. Algori-
tam je zasnovan na radu George Marsaglia, profesora na Florida State University i autora
klasicne analize generatora slucajnih brojeva pod nazivom "Random numbers fall mainly
in the planes". Osmislio je nekoliko algoritama za pseudoslucajne brojeve kao to su
Multiply-with-carry, Subtract-with-borrow, Xorshift i neke druge
Metod multiply-with-carry (MWC) je metod zasnovan na inicijalnom setu od dvije do
nekoliko hiljada slucajno odabranih inicijalnih vrijednosti (seed). Glavna prednost MWC
algoritma je koritenje jednostavne cjelobrojne aritmetike pa je rezulutat veoma brzo
109
generisanje brojeva sa periodima od 260 do 22.000.000. Kao i kod svih generatora
pseudoslucajnih brojeva, rezultat su funkcije slucajno odabranih inicijalnih vrijednosti.
MWC niz je zasnovan na aritmetici po modulu / obicnoo / = 2
32
jer je aritmetika po
ovom modulu automatska u vecini racunara. Meutim, nekad se koriste i baze kao to je
/ = 2
32
1 s obzirom da aritmetika po modulu 2
23
1 zahtijeva jednostavne dorade u
odnosu na onu za / = 2
23
a teorija MWC nizova za modul 2
32
ima neke pratece tekoce
koje se izbjegavaju ako se koristi / = 2
32
1.
U najoptijem obliku, ovaj generator zahtijeva bazu /, multiplikator c, inicijalni "prenos"
(carry) c
r1
< c, skup od : + 1 slucajnih inicijalnih vrijednosti koje se sastoje od :
ostataka od / (r
0
. r
1
. .... r
r
). Tada MWC daje niz parova (r
n
. c
n
) koji se odreuju na
sljedeci nacin
r
n
= (cr
nr
+c
n1
) mod /. c
n
=
_
cr
nr
+c
n1
/
_
. : _ :
Period za MWC je reda / u multiplikativnoj grupi c/
r
1. Uobicajeno je da se c-ovi
izaberu tako da c/
r
1 bude prost broj za koji se red / moze odrediti. S obzirom da je 2
kvadratni ostatak (quadratic residue) brojeva 8/1 broj /
32
ne moze biti primitivni kori-
jen za c/
r
1. Stoga nema MWC generatora koji za bazu / = 2
32
koji imaju maksimalni
moguci period to je razlog koritenja / = 2
32
1 kojim se to izbjegava.
Teorijski problem sa MWC generatorima je to su znacajniji bitovi (bitovi sa pocetka,
vodeci bitovi) dosta pristrasni odnosno meusobno zavisni; komplementarni generatori
tipa multiply-with-carry nemaju ovaj nedostatak. Ovi algoritmi zahtijevaju neto slozenije
racunanje po iteraciji ali to je cijena koja se placa za izbjegavanje tekoca ovog tipa.
Xorshift algoritam generie naredni broj ponovljanjem operacije ekskluzivne disjunkcije
na broj koji se dobije kad se bitovi broja pomjere za jednu ili vie pozicija. Ovo odgovara
operaciji mnozenja (pomjeranje udesno) odosno dijeljenja (pomjeranje ulijevo) binarnog
broja sa stepenom broja 2. Rezultat su ekstremno brzi algoritmi. Da bi se postigla
maksimalna ekasnost potreban je pazljiv izbor parametara, posebno kada je u pitanju
koritenje u kriptograji.
uint32_t xor128(void) {
// Znak ^ oznacava XOR operaciju
// Znak << odnosno oznacava pomjeranje (shift)
static uint32_t x = 123456789;
static uint32_t y = 362436069;
static uint32_t z = 521288629;
static uint32_t w = 88675123;
uint32_t t;
t = x ^(x << 11);
x = y; y = z; z = w;
return w = w ^(w 19) ^(t ^(t 8));
}
Prilozeni algoritam (napisan za C programski jezik) ilustruje njegovu jedostavnost. Ovaj
algoritam ima period 2
128
1.
110
Generator subtract-with-borrow (oduzimanje-sa-pozajmljivanjem) ne koristi kongruen-
talni algoritam. U sutini, uopte nema mnozenja i dijeljenja. Dizajniran je na nacin
da generie brojeve u pokretnom zarezu. Umjesto jednog sjemena novi generator ima 35
rijeci interne memorije ili stanja. Trideset i dvije od tih rijeci formiraju ke za brojeve
u pokretnom zarezu, ., u intervalu [0; 1]. Preostale tri rijeci sadrze indeks i koji se mi-
jenja od 0 do 31, jednog cijelog broja , i aga za "pozajmljivanje" /. Cjelokupan vektor
stanja se gradi po jedan bit u periodu inicijalizacije. Razlicite vrijednosti , daju razlicita
inicijalna stanja.
Generisanje i-tog broja u pokretnom zarezu ukljucuje korak "oduzimanja-sa-pozajmljivanjem"
gdje se broj u keu mijenja sa razlikom druga dva
.
i
= .
i+20
.
i+5
/
Tri velicine i. i +20 i i +5 se interpretiraju po modulu 32 (koritenjem njihovih 5 zadnjih
bitova). Velicina / se dobija iz prethodnog koraka; ona je ili nula ili mali pozitivni broj.
Ako je .
i
pozitivan tada je / = 0 za naredni korak; ako je .
i
negativan dodavanjem
velicine 1.0 se pretvara u pozitivan prije nego se sacuna i / se postavlja na vrijednost 2
53
za naredni korak. Velicina 2
53
, koja je polovina Matlabove velicine eps, se zove ulp jer
je "unit in the last place" za brojeve u pokretnom zarezu malo manja od 1.
Marsaglia je pokazao da niz ima period skoro 2
1430
vrijednosti prije ponavljanja. Meutim,
algoritam ima nedostatak. Svi brojevi su rezultati sabiranja i oduzimanja brojeva u
inicijalnom keu tako da su svi oni multiplikandi od 2
53
. U skladu sa tim, mnogi brojevi
iz intervala [0; 1] se ne dobijaju kao rezultat ovog algoritma.
Brojevi u pokretnom zarezu izmeu 1,2 i 1 su jednako rasporeeni sa korakom od jedan
ulp i generator oduzimanja-sa-pozajmljivanjem ce generisati skoro sve od njih. Brojevi
manji od 1,2 su manje blisko razdvojeni i generator ce propustiti vecinu tih brojeva. On
generie samo polovinu mogucih brojeva iz intervala [1,4; 1,2], samo cetvrtinu brojeva iz
intervala [1,8; 1,4] itd. To je mjesto na kojem se pokazuje uticaj velicine ,. Na razlomljeni
dio u pokretnom zarezu za svaki .
i
se koristi XOR operacija sa , kako bi se dobio rezultat
koji vraca generator. Ovo smanjuje razmake meu brojevima koji su manji od 1,2. Na
taj nacin je teorijski moguce generisati sve brojeve u pokretnom zarezu izmeu 2
53
i
1 2
53
. Nije sigurno da li se oni stvarno generiu ali za sada nema razloga protiv da
tako neto bude.
11.2.3 Lagged-Fibonacci
Ovaj algoritam se zasniva na relaciji
r
n
= (r
nr
r
nk
) (mod :)
Moze se pokazati da vektori (r
n
. r
n+kr
. r
n+k
) leze u dvije ravni. Stoga je, i bez dodatnih
testova, jasno da ovi brojevi ne mogu biti smatrani kao slucajni. U praksi se mogu
postaviti razni uslovi za koecijente
111
11.2.4 Mersenov tvister
Mersenov tvister je generator pseudoslucajnih brojeva razvijen 1997. godine od strane
Makoto Matsumoto i Takuji Nishimura. Zasnovan je na matricno linearnoj rekurziji nad
konacnim binarnim poljem1
2
. Ostvaruje brzo generisanje visoko kvalitetnih pseudosluca-
jnih brojeva i dizajniran je da ispravi mnoge nedostatke drugih algoritama.
Ime je izvedeno iz cinjenice da je duzina perioda izabrana da bude Mersenov prosti broj.
Postoje dvije varijante algoritma koje se razlikuju jedino u velicini Mersenovog prostog
broja koji se koristi. Jedan od najnovijih je MT 19937 koji koristi 32-bitne rijeci. Postoji
i varijanta sa 64-bitnim rijecima koji generie drugacije nizove. Za rijeci duzine / generie
brojeve koji su gotovo uniformno distribuirani u opsegu
_
0. 2
k
1

Cesto koritena varijanta koja daje nizove 32-bitnih cijelih brojeva ima sljedeca pozeljna
svojstva:
ima veoma dugacak period od 2
19937
1. Mada dugacak period ne garantuje kvalitet
generatora slucajnih brojeva, kratki periodi mogu biti jako problematicni
brojevi su /-distribuirani sa 32-bitnim nivoom preciznosti za svako 1 _ / _ 623
proao je brojne testove statisticke slucajnosti
Niz pseudoslucajnih brojeva r
i
od n-bitnih cijelih brojeva perioda 1 je /-distribuiran sa
-bitnim nivoom tacnosti ako vrijedi sljedece:
Neka t:n:c
v
(r) oznacava broj koji se dobija od vodecih bitova broja r i neka je dato
1 /-bitnih vektora
(t:n:c
v
(r
i
) . t:n:c
v
(r
i+1
) . .... t:n:c
v
(r
i+k1
))
Tada se svaka od 2
kv
mogucih kombinacija bitova pojavljuje jednak broj puta u periodu
osim kombinacije "sve-nule" koja se pojavljuje jednom manje.
U nastavku je pseudokod ovog algoritma.
Algoritam Mersenovog tvistera je predmet nekih kritika od strane racunarskih strucnjaka,
posebno od strane George Marsaglia. Kritike se odnose na to da, iako je algoritam dobar
u pogledu generisanja slucajnih brojeva, nije elegantan i, generalno gledano, tezak je za
implementaciju. Marsaglia je dao nekoliko primjera generatora slucajnih brojeva koji su
manje kompleksni i koji opet daju znacajno vece periode. Naprimjer, jednostavan kom-
plementarni generator mnozenja-sa-prenosom (MWC - multiply-with-carry) moze imati
periodu od 1.033.000 i da je uz to znacajno brzi i odrzava bolju ili jednak nivo slucajnosti.
11.3 Normalna distribucija
Skoro svi algoritmi koji generiu normlano distribuirane slucajne brojeve su bazirani na
transformaciji uniformne distribucije.
112
// Create a length 624 array to store the state of the generator
int[0..623] MT
int index = 0
// Initialize the generator from a seed
function initialize_generator(int seed) {
MT[0] := seed
for i from 1 to 623 { // loop over each other element
MT[i] := last 32 bits of(1812433253 * (MT[i-1] xor (right shift by 30 bits(MT[i-
1]))) + i) // 0x6c078965
}
}
// Extract a tempered pseudorandom number based on the index-th value,
// calling generate_numbers() every 624 numbers
function extract_number() {
if index == 0 {
generate_numbers()
}
int y := MT[index]
y := y xor (right shift by 11 bits(y))
y := y xor (left shift by 7 bits(y) and (2636928640)) // 0x9d2c5680
y := y xor (left shift by 15 bits(y) and (4022730752)) // 0xefc60000
y := y xor (right shift by 18 bits(y))
index := (index + 1) mod 624
return y
}
// Generate an array of 624 untempered numbers
function generate_numbers() {
for i from 0 to 623 {
int y := 32nd bit of(MT[i]) + last 31 bits of(MT[(i+1) mod 624])
MT[i] := MT[(i + 397) mod 624] xor (right shift by 1 bit(y))
if (y mod 2) != 0 { // y is odd
MT[i] := MT[i] xor (2567483615) // 0x9908b0df
}
}
}
113
Starije verzije Matlab-a koriste polarni algoritam koji generie dvije vrijednosti istovre-
meno. Zasniva se na nalazenju slucajne tacke u jedinicnom krugu putem generisanja uni-
formno distribuiranih tacaka u kvadratu [1; 1] [1; 1] i odbacivanja svega van kruga.
Tacke unutar kruga su predstavljene putem vektora sa dvije komponente.
Pocev od Matlaba 5 generator slucajnih brojeva u normalnoj distribuciji koristi sosti-
cirani algoritam trazenja u tabeli koji je razvio, takoe, George Marsaglia. Nazvan je
ziggurat algoritam.
Funkcija gustine vjerovatnoca normalne distribucije je tzv. zvonasta kriva
, (r) = c c
x
2
=2
gdje je c = 1,
_
2: normalizacijska konstanta koja se u ovom slucaju moze ignorisati.
Ako se generiu slucajne tacke (r; ) uniformno distribuirane u ravni i ako se odbaci bilo
koja od njih koja nije ispod krive, preostale vrijednosti r formiraju zeljenu normalnu
distribuciju. Ziggurat algoritam obuhvata prostor ispod funkcije gustine sa neto vecom
povrinom sa : sekcija.
Slika pokazuje slucaj za : = 8; stvarni kod koristi : = 128. Gornjih : 1 sekcija su
pravougaonici. Donja sekcija je pravougaonik zajedno sa beskonacnim repom ispod grafa
, (r). Desne ivice pravougaonika su u tackama .
k
, / = 1. .... : oznacene kruzicima. Sa
, (.
1
) = 1 i , (.
n+1
) = 0 visina /-te sekcije je , (.
k
) , (.
k+1
). Kljucna ideja je da
se izaberu .
k
tako da sve sekcije, ukljucujuci neogranicenu na dnu grafa, imaju jednake
povrine. Postoje drugi algoritmi koji aproksimiraju prostor ispod funkcije gustine sa
pravougaonicima. Svojstva koja izdvajaju Marsaglia-ov algoritam su cinjenice da su
pravougaonici horizontalni i da imaju jednake povrine.
Za specicirani broj : sekcija moguce je rijeiti transcedentnu jednadzbu kako bi se nalo
.
n
, tacka u kojoj beskonacni rep sijece prvu pravougaonu sekciju. Na slici sa : = 8 se
dobija da je .
n
= 2.34. U stvarnom kodu sa : = 128 je .
n
= 3.4426. Jednom kad se
dobije .
n
lako je izracunati zajednicke povrine i druge tacke .
n
sa desne strane. Takoe
je moguce izracunati o
k
= .
k1
,.
k
koji pokazuje koji dio svake sekcije lezi ispod naredne
sekcije koja je iznad i ovo se zove core. Na slici je oznacen crtanim linijama. Racunanje
velicina .
k
i o
k
se obavlja prilikom inicijalizacije koja se obavlja samo jednom.
Nakon koraka inicijalizacije normalno distribuirani slucajni brojevi se brzo racunaju.
Kljucni dio koda racuna jedan slucajni cijeli broj , izmeu 1 i : i jedan uniformno
distribuiran slucajni broj n izmeu 1 i 1. Nakon toga se pravi provjera da li n pada
ispod funkcije gustine a njegova vrijednost se vraca kao uzorak iz normalne distribucije.
Vazno je napomenuti da, mada ziggurat step funkcija samo aproksimira funkciju gustine,
rezultujuca distribucija je tacno normalna. Smanjenje velicine : smanjuje potrebu za
prostorom koji je potreban za tabele i povecava vrijeme dodatnih racunanja ali nema
uticaja na tacnost. Sa ovim algoritmom Matlab na racunaru od 800 Mhz moze generisati
preko 10 miliona slucajnih brojeva u manje od jedne sekunde.
Jednostavna rucna metoda generisanja slucajnih brojeva je tzv. metoda sredine kvadrata,
koja je sugerisana od strane Von Neumana. Mada jednostavna za implementaciju rezultat
je veoma lo kvalitet.
114
Ilustracija metoda ce biti napravljena tako da se odabere cetvorocifren broj npr. : =
6729. Taj broj se kvadrira pa se dobije 6279
2
= 39425841; iz njega se izdvoje srednje
cetiri cifre : = 4258 i to je naredni clan niza itd. U matematickom smislu, generisanje se
odvija po rekurentnom izrazu [r
2
k
,100] = r
k+1
(mod 10000)
11.4 Testiranje slucajnosti
Jedan od problema generisanja pseudoslucajnih brojeva je utvrivanje u kojoj mjeri su
slucajni. Za ovo se standardno koriste statisticki testovi. Meutim, za takav nacin rada
potrebno je znati ili pretpostaviti distribuciju pod kojom se brojevi generiu. U nekim
slucajevima to je veliki operativni problem jer nekada distribuciju, naprosto, nije moguce
pretpostaviti odnosno utvrditi.
Jedan od nacina da se utvrdi u kojoj mjeri su brojevi slucajni je Benfordov zakon. Ovaj
zakon izrazava distribuciju vodecih cifara. Vjerovatnoca da ce cifra d biti vodeca je
log (1 + 1,d). Pritom se pretpostavlja da skup brojeva zadovoljava jedan broj uslova.
Ovaj zakon je prvi formulisao ali ne i dokazao Simon Newcomb (1881), americki astronom.
Primijetio je da su logaritamske tablice pohabanije na pocetku, na osnovu cega je zakljucio
da je to posljedica navike da se vie koriste brojevi koji pocinju sa 1 ili 2. Isti zakon je
ponovo otkrio Frank Albert Benford (1938), inzinjer u laboratorijama General Electrica.
On je otiako korak dalje i svoje nalaze potvrdio uzimanjem uzoraka iz najrazlicitijih
izvora (berzanski indeksi, kucne adrese, brojevi sa novinskih stranica, povrine jezera,
duzine rijeka itd).
Jedno od objanjenja ovog fenomena je u cinjenici da su mantise logaritama brojeva
uniformno distribuirane tako da su brojevi distribuirani logaritamski. Iz tog razloga se
ovaj zakon objanjava pomocu kongruencije po modulu 1.
Slide rule, ilustracija Benfordovog zakona
Na slici je tzv. slide rule (kolo srece). Unutranja skala ilustruje distribuciju mantisa dok
spoljna skala ilustruje distribuciju njima pripadajucih brojeva.
Bitno svojstvo koje se koristi za testiranje slucajnosti je tzv. mjerna invarijantnost. Ona
se ocituje u tome da se dinamika vodecih cifara zadrzava ako se svaki clan uzorka pomnozi
istim brojem.
115
Test slucajnosti koritenjem Benfordovog zakona
Ako se cijeli uzorak 232 puta pomnozi sa 1.01 tada to odgovara mnozenju sa 10 odnosno
pomjeranju zareza za jedno mjesto udesno (1.01
232
- 10). Isti efekat vrijedi ako se
obavlja dijeljenje. U svakom od mnozenja se biljezi dinamika odabrane vodece cifre.
Na slici je ilustracija ovog postupka na uzorku regularnih podataka, koji su uzeti iz
procesa koji se odvija bez spoljnih uticaja (npr. nansijske transakcije, mjerenja i slicno)
i uzorku slucajnih brojeva. Ako su brojevi slucajni tada se dobija valovita kriva (desno);
za podatke iz regularnih procesa dobija se kriva bez valova (lijevo). Najvaznija osobina
ovog nacina testiranja je to za njegovo provoenje nije potrebno poznavati distribuciju
podataka.
116
12 Grafovski algoritmi
12.1 Uvod
U cilju potpunog razumijevanja grafovskih algoritama potrebno je denisati odgovarajuce
pojmove i utvrditi konvencije.
Predmet analize su samo prosti grafovi, koji nemaju petlje u pojedinim cvorovima
i nemaju ponavljajucih ivica
Sa : = [\ [ i : = [1[ se oznacava broj cvorova (tjemena, V) i grana (linija, E)
respektivno; svaki cvor je obiljezen brojem od 1 do : osim ako nije potrebno izbjeci
konfuziju
Jedan od prvih problema koji se rjeava kada se racunarski simuliraju grafovski algoritmi
je predstavljanje odnosno na koji nacin tu informaciju prenijeti racunaru. Postoje tri
nacina:
Lista cvorova (edge list) : formira se jednostavna numerisana lista koja u nekim
slucajevima moze biti sortirana
Matrica povezanosti (adjacency matrix) : matrica : : koja se sastoji od 1 i 0 u
zavisnosti od toga da li su dva cvora povezana (1) ili ne (0). Primjer je
=
_
_
_
_
0 1 1 1
1 0 0 0
1 0 0 1
1 0 1 0
_
_
_
_
U ovoj listi vrijedi da je c
ij
= c
ji
to znaci da je graf neusmjeren. U slucaju da je c
ij
,= c
ji
radi se o usmjerenom grafu.
Lista povezanosti (adjacency list) : lista od : elemenata u kojoj je svaki element
lista cvorova koji su povezani sa tim cvorom. Ako se radi o usmjerenom grafu tada
su elementi liste ureeni parovi
Ne postoji "najbolja" grafovska prezentacija jer to bitno zavisi od informacija koje se
prezentiraju putem grafa. Prezentacija je diktirana, prije svega, brojem veza a zatim
ostalim elementima.
Ako se svakoj grani dodijeli neka vrijednost tada se govori tezinskom grafu (ponderisani
graf, weighted graph, ...). "Tezina" je u tom slucaju velicina koja je od interesa kao
npr. rastojanje, cijena, vjerovatnoca i slicno. Namjena ovog teksta nije da se bavi inter-
nom prezentacijom. U tom smislu ce za svaki tip problema biti koritena odgovarajuca
notacija.
117
12.2 Algoritmi pretrazivanja
Problem pretrazivanja se formulie na sljedeci nacin : Ako su data dva cvora . n \ (G)
da li postoji putanja iz do n ? Ako postoji, da li je ta putanja najkraca ?
Podrazumijeva se da je graf G neusmjeren.
Intuitivno, to se radi tako da se graf G pretrazi po svakoj ivici od kako bi se vidjelo da
li se moze doci do n. Ako se radi na taj nacin potrebno je cuvati informaciju o tome koji
cvorovi su posjeceni kako bi se izbjegle beskonacne petlje.
Ideja je da se cvorovi koji jo nisu pretrazeni obiljeze Bijelo a pretrazeni Crno. Kad se
pretrazuju child cvorovi mora se osigurati da se ne obrauju ponovo pa se oznacavaju
kao Sivi. Inicijalno, svi cvorovi su oznaceni Bijelo.
Genericki (opti) algoritam pretrazivanja je u nastavku.
Oznaciti sve cvorove bijelo
Odabrati pocetni cvor i obojiti ga u Sivo
SveDok( postoji Sivi cvor )
{
Odaberi cvor i
Oznaci Bijele susjede Sivo
Obraditi cvor i
Oznaciti ga Crno
}
Kako bi se pokazala korektnost treba primijetiti da se kretanje odvija po principu
BijeloSivoCrno
i svaka iteracija petlje mijenja boju barem jednog cvora tako da se ne pojavljuje beskon-
acna petlja. Algoritam se zavrava samo ako su svi cvorovi oznaceni Bijelo ili Crno. Bilo
koji cvor koji je oznacen Bijelo ne moze biti susjed cvora koji je povezan sa startnim
cvorom (jer bi inace bio oznacen kao Sivo). Bilo koji cvor koji je oznacen Crno mora
biti povezan sa pocetnim cvorom. Stoga, putanja od cvora : do cvora : postoji ako i
samo ako je n oznacen kao Crno na kraju algoritma. U sutini, ovo je nacin da se nau
povezane komponente, zasebne cjeline grafa koje nisu povezane ivicama.
Na taj nacin je prezentiran prvi dio rjeenja problema.
Kad se ovaj algoritam zavri velicina :n:CC sadrzi ukupan broj povezanih komponenti
a cc [i] daje oznaku komponente koja je povezana sa cvorom i. Korak "Uzmi Sivi cvor ,"
se moze raditi na dva nacina:
breadth-rst-search (BFS) : uzeti cvor koji je pronaen najranije. Ovo znaci da se
najprije obrauju svi cvorovi povezani sa startnim cvorom zatim cvorovi na distanci
2 itd.
depth-rst-search (DFS) : uzeti cvor koji je pronaen najkasnije. Ovo znaci da se
najprije istrazuju cvorovi koji su na dugackom lancu (sve dok se ne doe do kraja
lanca)
118
Denisati nizove cc [.] i /o,c [] duzine :
:n:CC 0
ZaSvaki (cvor i)
{
Obojiti Bijelo
}
ZaSvaki

Cvor i od 1 do :
{
AkoJe(/o,c [i]=Bijelo)
{
:n:CC :n:CC + 1
cc [i] :n:CC
/o,c [i] Sivo
SveDokJe (Postoji cvor Sivo)
{
Uzmi Sivi cvor ,
Obojiti sve njegove Bijele susjede Sivo
cc [,] :n:CC
/o,c [,] Crno
}
}
}
Ova dva pristupa se bitno razlikuju po slozenosti i dinamici pretrazivanja i oba pristupa
imaju puno prakticnih primjena.
Prvi od njih ima slozenost O(:
2
) jer se koristi kvadratna matrica. Svaka ivica (grana)
se pretrazuje najvie dva puta. Algoritam ima prednosti ako je ema "rijetka". Putanja
koja se formira zove se stablo. Ako je graf pritom povezan to stablo se zove minimalno
razapinjuce stablo.
Drugi algoritam koristi strukturu koja se zove stek (engl. stack). Realizuje se operacijama
"stavi" (engl. push), koja dodaje element na kraj niza (lanca koji se pretrazuje) i "uzmi"
(engl. pop), koji uklanja element sa kraja. Ovo je struktura podataka koja se zove LIFO
(Last-In-First-Out). Postoji i struktura FIFO (First-In-First-Out), koja se ne koristi u
ove svrhe. Kompleksnost ovog algoritma je O(: +:).
Primjena druge verzije ovog algoritma nije odmah ocigledna. Meutim, moze se razmil-
jati kao o skupu cvorova od kojih svaki ima nekoliko konekcija na sebe tako da svaki tako
stvoren lanac ima odreena svojstva "separabilnosti".
Primjer. Neka je data mreza racunara. Potrebno je naci sve kompjutere koji, ako se
uklone, cine da se mreza raspada.
12.3 Algoritmi najkraceg puta
Ocigledna generalizacija problema najkraceg puta ima izvor u cinjenici da grane (ivice)
imaju razlicite "tezine". Formalno, potrebno je imati nacin na koji se "tezine" dodjelju
ivicama. To se cini putem sljedece denicije.
119
Denicija. Tezinski graf je graf G = (\ ; 1) zajedno sa funkcijom n : 1 R. Kaze se
da je n(i. ,) = ako (i. ,) , 1.
Slicno se formalizuje problem "najkraceg puta".
Denicija. Putanja
r = r
0
. r
1
. .... r
m
=
je najkraci put od r do ako ta putanja minimizira
m1

i=0
n(r
i
. r
i+1
)
Duzina najkraceg puta od r do se oznacava sa d (r. ).
Sada se problem najkraceg puta lako formulie.
Problem. Za dati tezinski graf G i dva cvora r i naci d (r. ). Pretpostavka je
n(i. ,) 0.
12.3.1 Dijkstra algoritam
Ovaj algoritam je namijenjen trazenju najkraceg puta u usmjerenim grafovima. Pret-
postavlja se da ivice grafa imaju svoje vrijednosti i cilj je naci najkrace putanje iz jednog
cvora u sve cvorove grafa.
Distanca izmeu dva cvora n i , u oznaci o (n; ), je minimalna duzina putanje od n do
.
Problem najkraceg puta iz jednog cvora (single source shortest path) se denie na sljedeci
nacin. Dat je usmjeren graf sa nenegativnim tezinama ivica G = (\ ; 1) i izdvojenim
pocetnim cvorom : \ . Problem je odrediti distancu pocetnog cvora do svakog cvora u
grafu.
Moguce je imati grafove sa negativnim tezinama ivica ali kako bi najkraci putevi bili
dobro denisani potrebno je dodati zahtjev da uopte nema ciklusa cija je ukupna tezina
negativna (inace bi se mogao napraviti beskonacno kratak put kretanjem zauvijek u tom
ciklusu). Ovdje se naglaava posao racunanja minimalne distance od pocetnog cvora
do svakog cvora. Racunanje stvarne duzine je dosta lagano proirenje problema. Za
svaki cvor se formira pointer j:cd () koji ukazuje na prethodnika. Slijedeci pointere
prethodnika unazad od bilo kojeg cvora konstruie se reverzna slika najkraceg puta do .
Osnovna struktura Dijkstra algoritma je odrzavanje procjena najkraceg puta za svaki
cvor, u oznaci d []. Intuitivno gledano, d [] ce biti duzina najkraceg puta od : do koji
je poznat algoritmu. Ova vrijednosti je uvijek veca ili jednaka sa stvarno najkracim putem
od : do . Inicijalno, putevi su nepoznati tako da je d [] = . Inicijalno je d [:] = 0 a
svi ostali d [] su postavljeni na . Kako algoritam napreduje i kako se ukljucuje vie
cvorova azurira se d [] za svaki cvor u grafu sve ove vrijednosti ne konvergiraju ka stvarno
najkracoj distanci.
120
Proces kojim se vri azuriranje procjene se zove relaksacija. Intuitivno gledano, ako nije
postignuta optimalna vrijednost ona je bliza ka optimumu. Posebno, ako se otkrije put
od : do koji je kraci od d [] tada se vri azuriranje te vrijednosti. Ovaj metod je
zajednicki za veliki broj algoritama optimalizacije.
Posmatra se ivica od cvora n do cvora cija je tezina n(n; ). Pretpostavka je da postoje
procjene za d [n] i d []. Poznato je da postoji put od : do n sa tezinom d [n]. Ako se uzme
ta putanja i ako se slijedi ivica (n; ) dobija se putanja do duzine d [n] + n(n; ). Ako
je ta putanja bolja od postojeceg puta do duzine d [] tada se d [] azurira na vrijednost
d [n] +n(n; ). Potrebno je zapamtiti da najkraci put do prolazi kroz n to se cini tako
da se azurira pointer prethodnika za .
Treba primijetiti da kad god se d [] postavi na konacnu vrijednost uvijek postoji trag
o putanji te duzine. Stoga je d [] _ o (:; ). Ako je d [] = o (:; ) tada naknadne
relaksacije ne mogu promijeniti tu vrijednost.
Nije teko vidjeti da ako se relaksacija provede nad svim ivicama grafa vrijednosti d []
obavezno konvergiraju konacnoj stvarnoj vrijednosti iz :. Cilj svakog dobrog algoritma
nalazenja najkraceg puta je da se azuriranja obavljaju na pametan nacin kako bi konver-
gencija bila to je moguce brza. Posebno, najbolji nacin bi bio da se operacije relaksacije
poredaju na nacin da se relaksacija za svaku ivicu provede tacno jednom. Tacno ovo radi
Dijkstra algoritam.
Dijkstra algoritam je zasnovan na izvravanju ponovljenih relaksacija. On radi tako da
odrzava podskup cvorova, o _ \ , za koji se proglaava da "znamo" stvarnu distancu,
d [] = o (:; ). Inicijalno je o = , prazan skup i stavlja se d [:] = 0 a za sve ostale +.
Jedan po jedan cvor iz \ o se dodaje u o.
Skup o moze biti implementiran koritenjem niza boja koje su dodijeljene cvorovima.
Inicijalno su svi cvorovi bijeli a /o,c [:] = c::c kako bi se naznacilo da o.
Dijkstra je prepoznao da je najbolji nacin relaksacije povecanje poretka distance od izvora.
Na taj nacin, kad god se provodi relaksacija moguce je zakljuciti da rezultat relaksacije
daje konacnu vrijednost distance. Za implementaciju ovog koncepta za svaki cvor n
\ o se odrzava procjena distance d [n]. Pohlepni dio algoritma se odnosi na to da se
uzima cvor iz \ o za koji je d [] minimalno tj. uzima se neobraeni cvor koji je (prema
procjeni) najblizi ka :.
Kako bi se ova selekcija izvrila ekasno, cvorovi iz \ o se stavlja u red prioriteta (tj.
heap - gomila) gdje je kljucna vrijednost svakog cvora n jednaka d [n]. Primjetna je
slicnost sa Primovim algoritmom iako se koriste razlicite vrijednosti. Za svaki cvor je
poznata lokacija u redu prioriteta i svaka stavka u redu prioriteta "poznaje" koji cvor
prezentira.
Zbog slicnosti sa Primovim algoritmom vrijeme izvrenja je jednako, (1 log \ ).
Drugi algoritmi kojima se rjeava problem najkraceg puta su :
- Floyd Warshall-ov algoritam
- Algoritam mravlje kolonije
121
12.4 Pohlepni algoritmi na grafovima
Uobicajeni problem u komunikacionim mrezama i dizajnu elektricnih kola je povezivanje
skupa cvorova (komunikacionih cvorova ili elemenata elektricnog kola) pomocu najkrace
moguce mreze, lija je duzina suma duzina pojedinih veza. Pretpostavlja se da je mreza
neusmjerena. Kako bi se minimizirala duzina mreze ne smije se dopustiti postojanje petlji.
Rezultat je graf koji je povezan, neusmjeren i aciklican i kao takav se zove slobodno stablo.
Racunski problem se zove problem minimalno razapinjuceg stabla (Minimum Spanning
Tree, krace MST). Formalnije, za dati povezani neusmjereni graf G = (\ ; 1) razapinjuce
stablo je aciklicni skup ivica 1 _ 1 koje povezuju sve cvorove. Pretpostavlja se da svaka
ivica n(n; ) grafa G ima numericku tezinu ili cijenu (koja moze biti negativna ili nula)
cijena stabla 1 se denie kao suma ivica razapinjuceg stabla
n(1) =

(u;v)2T
n(n; )
Minimalno razapinjuce stablo je ono koje ima minimalnu tezinu. Ovo stablo ne mora biti
jedinstveno. Ako sve ivice imaju razlicitu tezinu tada su minimalna razapinjuca stabla
razlicita (ovo jo nije dokazano vec cinjenica koja se koristi.
Slika prikazuje tri razapinjuca stabla za isti graf. U sredini i desno su su dva minimalna
razapinjuca stabla.
Postoje dva pohlepna algoritma, Kruskalov i Primov, za nalazenje minimalnog razapin-
juceg stabla. Podsjetimo se da je pohlepni algoritam onaj koji rjeenje nalazi ponavljan-
jem selekcije najjetinije (ili generalno lokalno optimalnog izbora) od raspolozivih opcija
na svakoj etapi. Vazna karakteristika pohlepnih algoritama je da prave izbor koji ne
opozivaju. Prije prezentacije potrebne su neke bitne cinjenice o slobodnim stablima.
Lema.
Slobodno stablo sa : cvorova ima tacno : 1 ivica
Postoji jedinstveni put izmeu bilo koja dva cvora slobodnog stabla
Dodavanje bilo koje ivice kreira jedinstveni ciklus. Prekidanje bilo koje ivice tog
ciklusa obnavlja slobodno stablo
122
Neka je G = (\. 1) neusmjeren povezan graf cije ivice imaju numericke vrijednosti tezine
(pozitivne, negativne ili nula). Intuicija u pozadini pohlepnih MST algoritama je jednos-
tavna : odrzava se podskup ivica koji je inicijalno prazan i dodaje se jedna po jedna
ivica sve dok ne postane MST. Kaze se da je o _ 1 most (prelaz) ako je podskup ivica
nekog MST (ne moze se reci MST jer nije neophodno i jedinstven). Kaze se da je ivica
(n. ) 1 sigurna ako je ' (n. ) prelaz. Drugim rijecima, izbor (n. ) je siguran
izbor tako da jo uvijek moze formirati MST. Ako je prelaz ne moze sadrzavati
ciklus. Izvorni (genericki pohlepni algoritam radi tako da dodaje sigurne ivice na tekuce
razapinjuce stablo. Potrebno je voditi racuna da je prelaznost svojstvo podskupa ivica a
sigurnost svojstvo pojedine ivice.
Neka je o podskup cvorova o _ \ . Podjela (cut) (o. \ o) je particija cvorova u dva
disjunktna podskupa. Ivica (n; ) prelazi podjelu ako je jedna njena krajnja tacka u o a
druga u \ o. Za dati podskup ivica se kaze da podjela potuje ako ne postoje ivice
u koje prelaze podjelu. Nije teko vidjeti zato je potovanje podjele vazno za ovaj
problem. Ako je formiran djelimicni MST i ako se zeli znati koje ivice koje mogu biti
dodate i koje ne formiraju ciklus u tekucem MST, bilo koja ivica koja prelazi potujucu
podjelu je moguci kandidat.
Ivica u 1 je lagana ivica koja prelazi podjelu ako ima minimalnu duzinu od svih ivica
koje prelaze podjelu. Lagana ivica moze ne biti jedinstvena. Prema intuiciji, s obzirom
da sve ivice koje prelaze potujucu podjelu ne formiraju ciklus tada je lagana ivica koja
prelazi podjelu prirodan izbor.
MST Lema. Neka je G = (\. 1) povezan neusmjereni graf sa ivicama realnih vrijednosti.
Neka je prelazni podskup od 1 (odnosno podskup nekog MST) i neka je (o. \ o) bilo
koja podjela koja potuje i neka je (n; ) lagana ivica koja prelazi podjelu. Tada je
(n; ) sigurna za .
12.4.1 Kruskalov algoritam
Kruskalov algoritam radi tako da se ivice dodaju na u rastucem redoslijedu tezina
(najprije lake ivice). Ako naredna ivica ne formira ciklus unutar tekuceg skupa ivica
tada se dodaje u . Ako formira ciklus tada se ivica proputa i razmatra se sljedeca
ivica u poretku. Kako algoritam odmice formira se uma (stablo) u cvorovima. Tokom
algoritma ova stabla se udruzuju sve dok se ne dobije stablo koje sadrzi sve cvorove.
Ova strategija vodi ka korektnom algoritmu. Uzmimo npr. ivicu (n; ) koja se treba
dodati i pretpostavimo da ta ivica ne formira ciklus u . Neka je
0
stablo u umi
koje sadrzi cvor n. Posmatra se Podjela (
0
. \
0
). Svaka ivica koja prelazi podjelu nije
u tako da ta podjela potuje i (n; ) je lagana ivica preko podjele (jer su sve laganije
ivice iskoritene ranije u algoritmu). Stoga je (n; ) sigurna ivica.
Teki dio algoritma je kako ekasno detektovati da li dodavanje ivice kreira ciklus u .
Moze se provesti pretrazivanje podgrafa koji je kreiran ivicama iz skupa ali to uzima
jako puno vremena. Potreban je brz i pouzdan test koji nam daje odgovor na pitanje
da li je n ili u istom stablu . Ovo se moze uraditi putem strukture podataka koja
se zove Unija-Trazenje (Union-Find) dva disjunktna skupa. Ova struktura podrzava tri
operacije:
123
KreiratiSet(u) : Kreiranje skupa koji sadrzi stavku n.
NaciSet(u) : Nalazenje skupa koji sadrzi datu stavku n.
Union(u;v) : Spojiti skup koji sadrzi n i skup koji sadrzi u zajednicki skup.
Svaka od ovih operacija se izvrava u C(log :) vremenu na skupu velicine :. Ova struk-
tura je zanimljiva jer se niz od : operacija izvrava mnogo brze od O(:log :).
U ovom algoritmu cvorovi grafa su elementi pohranjeni u skupove a skupovi su cvorovi
u svakom stablu . Skup moze biti pohranjen kao jednostavna lista ivica. Primjer je
pokazan na narednoj slici.
Analiza. Koliko dugo traje Kruskalov algoritam ? Kao i obicno, neka je \ broj cvorova
i 1 broj ivica. S obzirom da je graf povezan moze se uzeti da je 1 _ \ 1. Za sortiranje
ivica potrebno je (1 log 1). Petlja se ponavlja 1 puta a svaka iteracija ukljucuje
konstantan broj pristupa Union-Find strukturi na skupu od \ stavki. Stoga, za svaki
pristup treba (\ ) vremena a skupa (1 log \ ). Stoga je ukupno vrijeme izvrenja
jednako njihovoj sumu koja je ((\ +1) log \ ). S obzirom da \ u asimptotskom smislu
nije vece od 1 slijedi da je vrijeme izvrenja (1 log \ ).
12.4.2 Primov algoritam
Primov algoritam je drugi pohlepni algoritam za minimalno razapinjuce stablo. Od
Kruskalovog algoritma se razlikuje samo u nacinu odabira naredne sigurne ivice koja
se dodaje na svakom koraku. Vrijeme izvrenja je potpuno jednako kao za Kruskalov
algoritam. Ovaj algoritam pokazuje da postoji vie od jednog nacina da se rijei ovaj
problem. Osim toga, veoma je slican drugom pohlepnom algoritmu, Dijkstra algoritmu,
kojim se rjeava potpuno druga vrsta problema : najkraci put u mrezi.
Kruskalov algoritam radi tako da sortira ivice i umece ih jednu po jednu u razapinjuce
stablo vodeci racuna da se nikada ne formira ciklus. Intuitivno gledano, Kruskalov algo-
ritam radi tako da spaja dva stabla ili ih razdvaja sve dok se sve ivice ne nau u istom
stablu.
Za razliku od njega, Prim-ov algoritam gradi stablo dodavanjem po jednog lista na tekuce
stablo. Startuje se sa korijenskim cvorom : koji moze biti bilo koji. U bilo koje vrijeme
podskup ivica formira jedno stablo (u Kruskalovom algoritmu se formira uma). Trazi
se dodavanje cvora kao lista na stablo. Proces je ilustrovan na narednoj slici.
Ako se posmatra skup cvorova o koji je dio stabla i njegov komplement tada postoji
podjela grafa i tekuci skup ivica potuje tu podjelu. MST lema kaze da je sigurno
dodavanje lagane ivice. Na slici to je ivica tezine 4 koja ide u cvor n. Stoga se n dodaje
u cvorove skupa o i dijeli izmjene. Treba primijetiti da neke ivice koje vie ne sijedu
podjelu koju su presijecale podjelu prije ovog koraka nestaju a javljaju se nove koje nisu
presijecale tu podjelu.
Lako je vidjeti da je za ekasnu implementaciju Prim-ovog algoritma kljucno ekasno
azuriranje podjele i brzo odreivanje lagane ivice. Da bi se to ucinilo koristi se struktura
podataka prioritetnog reda (priority queue) koja se koristi u Heap sortu. Ova struktura
cuva skup stavki u kojoj je svaka stavka povezana sa vrijednosti koja se zove kljuc.
Naredna slika ilustruje Prim-ov algoritam. Strelice indiciraju pointere (pokazivace) sljed-
nika a numericka vrijednost u svakom cvoru je vrijednost kljuca.
124
Za analizu Prim-ovog algoritma racuna se vrijeme potroeno na svakomcvoru nakon to se
preuzme iz reda prioriteta (priority queue). Ova aktivnost uzima O(log \ ) vremena. Za
svaku ivicu se potroi oko O(log \ ) vremena kako bi se smanjio kljuc susjednih cvorova pa
je vrijeme C(log \ + deg (n) log \ ). Ostali koraci azuriranja se obavljaju u konstantnom
vremenu. Na osnovu ovoga je
1 (\. 1) =

u2V
(log \ + deg (n) log \ ) =

u2V
(1 + deg (n)) log \
= log \

u2V
(1 + deg (n)) = (log \ ) (\ + 21) = ((\ +1) log \ )
S obzirom da je G povezan \ asimptotski nije veci od 1 tako da je rezultat (1 log \ ).
To je tacno jednako sa procjenom za Kruskalov algoritam.
125
12.5 Zadaci
Zadatak. Kruskalovim algoritmom naci minimalno razapinjuce stablo na sljedecem
grafu.
Rjeenje je dato na narednoj tabeli.
Korak Raspolozivo Uzeto
1 (c,d) (c,d)
2 (d,e), (c,e) (d,e)
3 (b,c) (b,c)
4 (a,d) (a,d)
Table 32: Graf 01
Dobijeno je stablo na narednoj slici.
Zadatak. Kruskalovim algoritmom naci minimalno razapinjuce stablo na sljedecem
grafu.
126
Rjeenje. Postupak rjeavanja je prikazan na narednoj tabeli.
Korak Raspolozivo Uzeto
1 (c,g), (e,i), (k,l) (c,g)
2 (e,i), (k,i) (e,i)
3 (k,l) (k,l)
4 (a,e), (b,c), (c,d), (d,g), (f,j), (j,k) (a,e)
5 (b,c), (c,d), (d,g), (f,j), (j,k) (b,c)
6 (c,d), (d,g), (f,j), (j,k) (c,d)
7 (f,j), (j,k) (f,j)
8 (j,k) (j,k)
9 (b,f), (e,j), (i,j) (b,f)
10 (e,j), (i,j) (e,j)
11 (h,l) (h,l)
Table 33: Graf 02
Dobijeno je stablo na narednoj slici.
Zadatak. Primovim algoritmom naci minimalno razapinjuce stablo na sljedecem grafu.
127
Rjeenje. Postupak rjeavanja je dat na narednoj tabeli.
Korak

Cvorovi Raspolozivo Uzeto
1 a (a,b), (a,e), (a,f) (a,e)
2 a, e (a,b), (a,f), (e,f), (e,i), (e,j) (e,i)
3 a, e, i (a,b), (a,f), (e,f), (e,j), (i,j) (e,j)
4 a, e, j (a,b), (a,f), (e,f), (j,f), (j,g), (j,k) (j,f)
5 a, f, j (a,b), (f,b), (f,c), (f,g), (j,g), (j,k) (j,k)
6 a, f, j, k (a,b), (f,b), (f,c), (f,g), (j,g), (k,g), (k,l) (k,l)
7 a, f, j, k, l (a,b), (f,b), (f,c), (f,g), (j,g), (k,g), (l,g), (l,h) (f,b)
8 b, f, j, k, l (b,c), (f,c), (f,g), (j,g), (k,g), (l,g), (l,h) (b,c)
9 c, f, j, k, l (c,d), (c,g), (f,g), (j,g), (k,g), (l,g), (l,h) (c,g)
10 c, g, l (c,d), (g,d), (g,h), (l,h) (c,d)
11 d, g,l (d,h), (g,h), (l,h) (l,h)
Table 34: Graf 02
Dobijeno je stablo na narednoj slici.
U ovom slucaju je dobijeno stablo identicno onome iz prethodnog zadatka. Ovo ne mora
uvijek biti slucaj.
Zadatak. Dijkstra algoritmom naci najkraci put u sljedecem grafu.
128
Rjeenje. Postupak je dat na sljedecoj tabeli.
Korak

Cvorovi Veze Uzeto
1 a b(10), e(2), f(8) (a,e)
2 a, e b(10), f(8), i(3), j(5) (e,i)
3 a, e, i b(10), f(8), j(5) (e,j)
4 a, e, j b(10), f(7), g(11), k(7) (f,j)
5 a, f, j b(10), c(12), g(10), k(7) (j,k)
6 a, f, k b(10), c(12), g(10), l(8) (k,l)
7 a, f, l b(10), c(12), g(10), h(13) (a,b)
8 b, f, l c(12), g(10),h(13) (f,g)
9 b, g, l c(11), d(12), h(13) (c,g)
10 c, g, l d(13), h(13) (d,g)
11 d, g,l i(22), h(8) (l,h)
Table 35: Graf 02
Dobijena je putanja na sljedecoj slici.
Zadatak. Dijkstra algoritmom naci najkraci put u sljedecem grafu.
129
Postupak je dat na sljedecoj tabeli.
Korak

Cvorovi Veze Uzeto
1 a b(10), d(5) (a,d)
2 a, d b(8), c(14), e(7) (d,e)
3 a, d, e b(8), c(13) (d,b)
4 b, d, e c(9) (b,c)
Table 36: Graf 02
Dobijena je putanja na sljedecoj slici.
12.6 Zadaci za samostalni rad
Na sljedecim grafovima odabranim algoritmom naci minimalno razapinjuce stablo i na-
jkraci put. Za pocetni uzimati cvor a.
130
131
132
133
134
.
135

Vous aimerez peut-être aussi