Upload
lekhuong
View
266
Download
12
Embed Size (px)
Citation preview
Algoritmi i strukture podataka — ispitna pitanja i odgovori
Nikola Ajzenhamer
26. maj 2015.
Greske posaljite na:[email protected]
Napomena za kodove:Neke od kodova nije potrebno uciti, vec su dodati naknadno, voljom autora. Na primer, za pitanja32, 33 i 37, dovoljno je objasniti ideju i/ili primer umesto pisanja pseudo koda.
1
Sadrzaj
1 Elementarne strukture podataka 4
2 Stek, red: osnovne operacije, realizacija pomocu niza 4
3 Dvostruko (jednostruko) povezane liste – trazenje, umetanje, brisanje elementa 6
4 Korenska stabla, predstava proizvoljnog korenskog stabla binarnim stablom 6
5 Binarna stabla: eksplicitno i implicitno predstavljanje 7
6 Hip – realizacija reda sa prioritetom – osnovne operacije 8
7 Binarno stablo pretrage – realizacija recnika – osnovne operacije (trazenje, umetanje,brisanje elementa) 9
8 Binarno stablo pretrage – prethodnik, sledbenik elementa 11
9 Hes tabele, hes funkcije, kolizije i njihova obrada 12
10 Grafovi – predstavljanje: matrica povezanosti, lista povezanosti 13
11 Sortiranje objedinjavanjem 14
12 Sortiranje pomocu hipa (hip sort) 16
13 Brzo sortiranje (kvik sort) 16
14 Sortiranje slozenosti O(n), donja granica slozenostisortiranja kad se koriste uporedivanja 17
15 Pretraga grafa u dubinu (dokaz ispravnosti, DFS stablo, numeracija cvorova, kom-ponente povezanosti) 19
16 Klasifikacija grana grafa u odnosu na DFS stablo, kriterijum za prepoznavanje po-vratne grane 20
17 Pretraga grafa u sirinu, BFS stablo, osobine 22
18 Analiza algoritama – osnovni pojmovi (aproksimativna asimptotska analiza najgoregslucaja; asimptotske oznake O, o, Ω, Θ; vremenska i prostorna slozenost algoritma) 23
19 Primeri sumiranja 24
20 Resavanje linearnih rekurentnih relacija 26
21 Rekurentna relacija T (n) = aT (n/b) + cnk koja opisuje algoritme zasnovane na razla-ganju (”divide-and-conquer”) 27
22 Rekurentne relacije sa potpunom istorijom;
primer T (n) = 2n
n∑i=1
T (i) + n− 1, T (1) = 0 (prosecna slozenost algoritma kvik sort) 27
23 Algoritmi grube sile (najveci clan niza, dve najblize tacke u ravni, problem trgovackogputnika) 29
24 Pohlepni (greedy) algoritmi: problem izbora aktivnosti 29
25 Pohlepni (greedy) algoritmi: razlomljeni problem ranca 30
2
26 Pohlepni (greedy) algoritmi: optimalni prefiksni (Hofmanov) kod 30
27 Resavanje problema razlaganjem (divide-and-conquer): binarna pretraga i varijante 32
28 Resavanje problema razlaganjem (divide-and-conquer): istovremeno trazenje najma-njeg i najveceg clana niza 34
29 Resavanje problema razlaganjem (divide-and-conquer): problem selekcije – nalazenjek-tog najmanjeg clana niza 35
30 Resavanje problema razlaganjem (divide-and-conquer): mnozenje polinoma, brojevaslozenosti O(nlog2 3) 35
31 Resavanje problema razlaganjem (divide-and-conquer): Strasenov algoritam za mnozenjematrica 36
32 Resavanje problema razlaganjem (divide-and-conquer): nalazenje dve najblize tackeu ravni 38
33 Pretraga (backtracking): problem 8 dama 40
34 Pretraga (backtracking): trazenje podskupa brojeva sa zadatim zbirom 41
35 Pretraga (backtracking): 3-bojenje 42
36 Ogranicavajuce funkcije za pretragu: bojenje grafa minimalnim brojem boja 43
37 Ogranicavajuce funkcije za pretragu: trazenje podskupa sa zadatom sumom, koriscenjerazlomljenog problema ranca 43
38 Trazenje uzorka u tekstu – naivni algoritam, algoritam KMP 45
39 Trazenje uzorka u tekstu – izracunavanje pomocnog niza za algoritam KMP 46
40 Numericki algoritmi: izracunavanje vrednosti polinoma (Hornerova sema) 47
41 Numericki algoritmi: Lagranzov interpolacioni polinom 47
42 Numericki algoritmi: priblizno resavanje jednacina (polovljenje intervala, metodsecice, metod tangente) 48
43 Svodenje rekurzije na iteraciju – repna rekuzija, n!, Fibonacijev niz 49
3
1 Elementarne strukture podataka
Pod pojmom element podrazumevamo podatak kome tip nije preciziran (na primer celi broj, skup celihbrojeva, fajl i slicno). Razlika izmedu algoritama je samo u realizaciji, a ideje na kojima se zasnivajualgoritmi su iste. Pretpostavka je da se sve operacije nad elementima izvode u jedinicnom vremenskomintervalu.
Vektor (niz) je niz elemenata istog tipa. Velicina vektora je broj elemenata u njemu i ona se moraunapred znati (odnosno fiksirana je) jer se pre samog koriscenja mora dodeliti odredeni memorijski pro-stor. Ako je prvi element na lokaciji x, a velicina elementa je a bajtova, onda je k-ti element vektorana lokaciji x+ (k − 1)a, sto se lako izracunava – nezavisno od rednog broja elementa. Ovo je efikasna izbog toga cesto koriscena struktura podataka. Njena osnovna osobina je da je jednako vreme pristupasvim elementima. Nedostaci ove strukture podataka su da su svi njeni elementi istog tipa i da se njenavelicina ne moze menjati dinamicki, u toku izvrsavanja algoritma.
Slog (rekord) je takode niz elemenata, koji medutim ne moraju biti istog tipa – jedino se fiksira kom-binacija tipova elemenata. Velicina sloga takode mora biti unapred definisana. Elementima sloga mozese kao i elementima vektora pristupiti za konstantno vreme: za ovu svrhu koristi se poseban vektor sapocetnim adresama elemenata sloga, duzine jednake broju elemenata sloga. Adrese ovog i ostalih eleme-nata prevodilac izracunava samo jednom, prilikom prolaska kroz definiciju sloga, i smesta ih u spomenutipomocni vektor.
Dinamicke strukture podataka se koriste kada je potrebno dinamicki menjati broj elemenata. Koddinamickih struktura podataka, elementi se cuvaju zasebno u memoriji i vezuju se pokazivacima cijavrednost predstavlja adresu sledeceg elementa. Primer dinamicke strukture podataka je povezana lista.Ako je cilj efikasno umetanje i izbacivanje elemenata, mora se napustiti sekvencijalni zapis koji karak-terise vektor – elementi se moraju zapisivati nezavisno, a medusobno se povezuju (nadovezuju) pomocupokazivaca.
2 Stek, red: osnovne operacije, realizacija pomocu niza
Preporucuje se ucenje kodova.
Stek i red su strukture podataka kojima su operacije INSERT i DELETE predefinisane. Stek funkcionisepo LIFO politici (last-in-first-out), dok red koristi FIFO (first-in-first-out) politiku.
Stek: INSERT operacija kod steka se obicno naziva PUSH, a DELETE se naziva POP. Stek odgo-vara primeru diskova koji su naslagani na stalak. Moze se pristupiti samo onom koji je na vrhu i da bise onaj na dnu izvadio moraju se skinuti svi koji se nalaze na njemu. Stek cuva atribut vrh koji nambez skidanja sa steka pokazuje element koji se nalazi na vrhu.Kod upotrebe operacija PUSH i POP razlikujemo dva stanja: potkoracenje i prekoracenje. Potkoracenjese desava kada pokusavamo da iskoristimo POP, a na steku nema nijednog elementa. Prekoracenje sedesava kada pokusavamo da iskoristimo PUSH, a stek nam je pun.
Pseudo kodovi za realizaciju steka pomocu niza:
Stek_pun(S, vrh)
begin
if vrh = MAX then
return TRUE
else
return FALSE
end
4
Stek_prazan(S, vrh)
begin
if vrh = 0 then
return TRUE
else
return FALSE
end
Push(S, vrh, x)
begin
if Stek_pun(S, vrh) then
ispis greske: prekoracenje steka
else
vrh = vrh + 1
S[vrh] = x
end
Pop(S, vrh)
begin
if Stek_prazan(S, vrh) then
ispis greske: potkoracenje steka
else
vrh = vrh - 1
return S[vrh+1]
end
Red: operaciju INSERT nazivamo ENQUEUE, a DELETE nazivamo DEQUEUE. Primer rada redamoze da predstavlja red u banci, gde prvi iz reda izlazi onaj koji je prvi dosao. Red sadrzi poc i kraj.Kada ubacujemo element u red on se ubaci na mesto kraj, a kada izbacujemo element, onda se izbacujepoc.Ako je poc = kraj, onda je red prazan. Ukoliko ,,red je pun” definisemo kao ,,ostalo je samo 1 pra-zno mesto”, onda ako je kraj < n i poc = kraj + 1 ili ako je kraj = n i poc = 1, onda je red pun, pricemu vazi da je inicijalna vrednost i poc i kraj jednaka 1. I ovde razlikujemo potkoracenje i prekoracenje.
Pseudo kodovi za realizaciju reda pomocu niza (bez obavestavanja o greski):
Enqueue(Q, poc, kraj, n, x)
begin
Q[kraj] = x
if kraj = n then
kraj = 1
else
kraj = kraj+1
end
Dequeue(Q, poc, kraj, n)
begin
x = Q[poc]
if poc = n then
poc = 1
else
poc = poc + 1
return x
end
5
3 Dvostruko (jednostruko) povezane liste – trazenje, umetanje,brisanje elementa
Preporucuje se ucenje kodova.
Povezana lista je dinamicka struktura podataka sto znaci da joj se broj elemenata moze dinamickipovecavati i smanjivati. Ona predstavlja vektor parova (element, pokazivac) gde pokazivac sadrzi adresunarednog para. Obilazak liste je moguc samo linearnim prolaskom, odnosno i-tom elementu se mozepristupiti samo prolaskom kroz njegove prethodnike. Prednost povezane liste je to sto se izbacivanje iubacivanje elemenata lako realizuje. Nedostatak je taj sto je potrebno vise prostora (svaki element moraimati i pokazivac na sledeci sto zauzima vise memorije).Postoje razlicite vrste povezanih listi: jednostruko povezana (struktura sadrzi element i pokazivac nasledeci element), dvostruko povezana (struktura sadrzi element i dva pokazivaca: jedan na prethodni, ajedan na sledeci element), ciklicno povezana (jednostruko povezana pri cemu poslednji element pokazujena prvi).
Pseudo kodovi za trazenje, umetanje i brisanje elemenata iz jednostruko povezane i dvostruko pove-zane liste:
Search(L, k)
begin
x = L
while x != NULL and x.kljuc != k do
x = x.nar
return x
end
Insert(L, x)
begin
x.nar = L
if L != NULL
L.pret = x
L = x
x.pret = NULL
end
Delete(L, x)
begin
if x.pret != NULL
x.pret.nar = x.nar
else
L = x.nar
if x.nar != NULL
x.nar.pret = x.pret
end
4 Korenska stabla, predstava proizvoljnog korenskog stabla bi-narnim stablom
Stablo (drvo) hijerarhijska je struktura, ali se moze koristiti i za izvodenje nekih operacija nad linearnimstrukturama.Korensko stablo cini skup cvorova i grana, koje povezuju cvorove na specijalan nacin. Jedan cvorje izdvojen, predstavlja vrh hijerarhije i zove se koren stabla. Cvorovi vezani sa korenom cine nivo 1hijerarhije; (novi) cvorovi vezani sa cvorovima nivoa 1 (sem korena) cine nivo 2 hijerarhije itd. Svakagrana u stablu povezuje neki cvor sa njegovim (jedinstvenim) prethodnikom (ocem); jedino koren nema
6
oca. Osnovna karakteristika stabla je da nema ciklusa (zatvorenih puteva), zbog cega izmedu svaka dvanjegova cvora postoji jedinstveni put. Cvor u stablu vezan je sa ocem i sa nekoliko sinova. Za cvorv koji se nalazi na putu od cvora u do korena kaze se da je predak cvora u; u tom slucaju je cvor upotomak cvora v. Maksimalni broj sinova cvora u grafu zove se stepen stabla. Stablo stepena dva zovese binarno stablo. Cvor u binarnom stablu moze da ima najvise dva sina, levog i desnog. Cvor bez decezove se list, a cvor koji nije list zove se unutrasnji cvor. Visina stabla je najveci nivo hijerarhije u njemu,tj. maksimalno rastojanje od korena do nekog cvora. Cvor ima kljuc iz nekog potpuno uredenog skupa(npr. celi ili realni broj). Svaki cvor moze da ima polje za podatak – sto zavisi od primene.
Slika 1: Primer korenskog stabla.
Stablo stepena veceg od dva moze se predstaviti koriscenjem samo dva pokazivaca po cvoru: jednog kaprvom sinu, a drugog ka narednom bratu – videti primer na slici 2.
Slika 2: Prikazivanje nebinarnog stabla sa po najvise 2 pokazivaca po cvoru.
5 Binarna stabla: eksplicitno i implicitno predstavljanje
U zavisnosti od toga da li se koriste pokazivaci ili ne, predstavljanje stabla je eksplicitno, odnosnoimplicitno.
7
Pri eksplicitnom predstavljanju se cvor sa k sinova predstavlja slogom ciji je deo vektor sa k po-kazivaca ka sinovima; ponekad je deo sloga i pokazivac ka ocu. Pogodno je da svi cvorovi budu istog tipa– sa m pokazivaca, gde je m stepen stabla.
Za implicitno predstavljanje stabla ne koriste se pokazivaci: svi cvorovi se smestaju u vektor, a vezeizmedu cvorova odredene su njihovom pozicijom u vektoru. Ako je sa A oznacen vektor u koji se smestajucvorovi binarnog stabla, onda se koren smesta u A[1]; njegov levi, odnosno desni sin zapisuju se u A[2],odnosno A[3], itd. Dakle, u vektoru se cvorovi zapisuju onim redom kojim se prolaze s leva u desno, nivopo nivo; pri tome se ocigledno u vektoru mora rezervisati prostor i za odsutne cvorove. Indukcijom semoze pokazati da ako je cvor v zapisan u elementu A[i], onda su njegov levi, odnosno desni sin zapisaniu elementu A[2i], odnosno A[2i+ 1].
6 Hip – realizacija reda sa prioritetom – osnovne operacije
Preporucuje se ucenje kodova.
Hip je binarno stablo koje zadovoljava uslov hipa: kljuc svakog cvora je veci ili jednak od kljucevanjegovih sinova. Neposredna posledica definicije (zbog tranzitivnosti relacije ≤) je da je u hipu kljucsvakog cvora veci ili jednak od kljuceva svih njegovih potomaka.Hip je pogodan za realizaciju liste sa prioritetom, apstraktne strukture podataka za koju su definisanedve operacije:
• umetni(x) – umetni kljuc x u strukturu, i
• ukloni() – ukloni (obrisi) najveci kljuc iz strukture.
Hip se moze realizovati sa implicitno ili eksplicitno zadatim stablom. Ovde ce biti prikazana realizacijahipa na implicitno zadatom stablu. Smatracemo da su kljucevi cvorova hipa smesteni u vektoru A, pricemu je k gornja granica za broj elemenata hipa (ako se ta granica ne zna unapred, onda se za hip morakoristiti povezana lista). Ako je n tekuci broj elemenata hipa, onda se za smestanje elemenata hipakoriste lokacije u vektoru A sa indeksima od 1 do n.
Algoritam Skini_max_sa_hipa(A, n);
Ulaz: A (vektor velicine n za smestanje hipa).
Izlaz: Vrh hipa (najveci elemenat hipa), A (novi hip),
n (nova velicina hipa; ako je n = 0 hip je prazan).
begin
if n = 0 then print "hip je prazan"
else
Vrh_hipa := A[1];
A[1] := A[n];
n := n - 1;
Otac := 1;
if n > 1 then
Sin := 2;
while Sin <= n do
if Sin + 1 <= n and A[Sin] < A[Sin + 1] then
Sin := Sin + 1;
if A[Sin] > A[Otac] then
zameni (A[Otac], A[Sin]);
Otac := Sin;
Sin := 2 * Sin;
else
Sin := n + 1 da bi se iskocilo iz petlje
end
8
Algoritam Upis_u_hip(A, n, x);
Ulaz: A (vektor velicine n za smestanje hipa), x (broj).
Izlaz: A (novi hip), n (nova velicina hipa).
begin
n = n + 1; pretpostavka je da novo n nije vece od velicine A
A[n] = x;
Sin = n;
Otac = n div 2;
while Otac >= 1 do
if A[Otac] < A[Sin] then
zameni(A[Otac], A[Sin]);
Sin = Otac;
Otac = Otac div 2;
else
Otac = 0; za iskakanje iz petlje
end
Obe operacije su slozenosti reda O(log n).
7 Binarno stablo pretrage – realizacija recnika – osnovne ope-racije (trazenje, umetanje, brisanje elementa)
Preporucuje se ucenje kodova.
Svaki cvor binarnog stabla ima najvise dva sina, pa se moze fiksirati neko preslikavanje skupa njegovihsinova u skup levi, desni. Ovo preslikavanje moze se iskoristiti pri iscrtavanju stabla u ravni: levi sincrta se levo, a desni sin desno od oca; svi cvorovi iste generacije (nivoa) crtaju se na istoj horizontalnojpravoj, ispod prave na kojoj su cvorovi prethodne generacije. Levom, odnosno desnom sinu korena stablaodgovara levo, odnosno desno podstablo. U binarnom stablu pretrage (BSP) kljuc svakog cvora vecije od kljuceva svih cvorova levog podstabla, a manji od kljuceva svih cvorova desnog podstabla. BSPomogucuje efikasno izvrsavanje sledece tri operacije:
• Nadji(x) – nadi elemenat sa kljucem x u strukturi, ili ustanovi da ga tamo nema (pretpostavljase da se svaki kljuc u strukturi nalazi najvise jednom);
• Umetni(x) – umetni kljuc x u strukturu, ako on vec nije u njoj; u protivnom ova operacija nemaefekta, i
• Ukloni(x) – ako u strukturi podataka postoji elemenat sa kljucem x, ukloni ga.
Struktura podataka sa ovim operacijama zove se recnik. Za njenu realizaciju moze se iskoristiti BSP.Svaki cvor stabla je slog sa bar tri polja: kljuc, levi i desni. Drugo, odnosno trece polje su pokazivaci kadrugim cvorovima, ili NULL (ako cvor nema levog, odnosno desnog sina).
Algoritam Nadji_u_BSP(Koren, x);
Ulaz: Koren (pokazivac na koren BSP), x (broj).
Izlaz: Cvor (pokazivac na cvor koji sadrzi kljuc x, ili NULL ako takvog cvora nema).
begin
if Koren = NULL or Koren.Kljuc = x then Cvor := Koren
else
if x < Koren.Kljuc then Cvor = Nadji_u_BSP(Koren.Levi, x);
else Cvor = Nadji_u_BSP(Koren.Desni, x);
return Cvor;
end
9
Algoritam Umetni u BSP(Koren, x);
Ulaz: Koren (pokazivac na koren BSP), x (broj).
Izlaz: U BSP se umece cvor sa kljucem x na koga pokazuje pokazivac Sin;
ako vec postoji cvor sa kljucem x, onda Sin = NULL.
begin
if Koren = NULL then
kreiraj novi cvor na koga pokazuje Sin;
Koren := Sin;
Koren.Kljuc = x; Koren.levi := NULL; Koren.Desni := NULL;
else
Cvor := Koren; tekuci cvor u stablu
Sin := Koren; postavlja se na vrednost razlicitu od NULL
while Cvor != NULL and Sin != NULL do
if Cvor.Kljuc = x then Sin := NULL
else silazak niz stablo za jedan nivo
Otac := Cvor;
if x < Cvor.Kljuc then Cvor := Cvor.Levi
else Cvor := Cvor.Desni;
if Sin != NULL then novi cvor je sin cvora Otac
kreiraj novi cvor na koga pokazuje Sin;
Sin.Kljuc := x;
Sin.Levi = NULL; Sin.Desni = NULL;
if x < Otac.Kljuc then Otac.Levi := Sin
else Otac.Desni := Sin
end
10
Algoritam Ukloni iz BSP(Koren, x);
Ulaz: Koren (pokazivac na koren BSP), x (broj).
Izlaz: Iz BSP se uklanja cvor sa kljucem x, ako takav postoji.
Pretpostavka je da se koren nikad ne brise, i da su svi kljucevi razliciti
begin
prva faza: trazenje cvora sa kljucem x
Cvor := Koren;
while Cvor != NULL and Cvor.Kljuc != x do
Otac := Cvor;
if x < Cvor.Kljuc then Cvor := Cvor.Levi;
else Cvor := Cvor.Desni;
if Cvor = NULL then print("x nije u BSP"); halt;
brisanje nadenog cvora Cvor, ili njegovog prethodnika
if Cvor != Koren then
if Cvor.Levi = NULL then
if x <= Otac.Kljuc then
Otac.Levi := Cvor.Desni;
else Otac.Desni := Cvor.Desni;
else if Cvor.Desni = NULL then
if x <= Otac.Kljuc then
Otac.Levi := Cvor.Levi;
else Otac.Desni := Cvor.Levi;
else slucaj sa dva sina
Cvor1 := Cvor.Levi;
Otac1 := Cvor;
while Cvor1.Desni != NULL do
Otac1 := Cvor1;
Cvor1 := Cvor1.Desni;
a sada brisanje; Cvor1 je prethodnik cvora Cvor
Cvor.Kljuc := Cvor1.Kljuc;
if Otac1 = Cvor then
Otac1.Levi := Cvor1.Levi; Cvor1 je levi sin cvora Otac1
else
Otac1.Desni := Cvor1.Levi; Cvor1 je desni sin cvora Otac1
end
Slozenost: Ukoliko je stablo priblizno uravnotezeno onda je slozenost sve tri operacije jednaka O(log n)sto je jednako visini stabla. U najgorem slucaju visina stabla moze biti O(n) i to se desava ako jeredosled ubacivanja elemenata u BSP ureden rastuce. Brisanje moze predstavljati problem ukoliko sesve vreme koristi samo prethodnik ili samo sledbenik kao pomocni cvor, a to se moze resiti naizmenicnomupotrebom funkcija sledbenik i prethodnik.
8 Binarno stablo pretrage – prethodnik, sledbenik elementa
Preporucuje se ucenje kodova.
Za algoritme prethodnika i sledbenika nekog elementa, potrebni su algoritmi za minimalni i maksimalnielement.
Minimum(koren)
begin
while koren.levi != NULL do
koren = koren.levi
return koren
end
11
Maksimum(koren)
begin
while koren.desni != NULL do
koren = koren.desni
return koren
end
Sledbenik nekog elementa x je cvor sa najmanjim kljucem koji je veci od x.kljuc. Algoritam za nalazenjesledbenika se razbija u dva slucaja:(1) Ako je desno podstablo neprazno, sledbenik je minimum u desnom podstablu i(2) Ako je desno podstablo prazno, premestamo se uvis sve dok je taj cvor desni sin oca. Ako postoji,naredni otac je sledbenik.
Sledbenik(x)
begin
if x.desni != NULL then
return Minimum(x.desni)
y = x.otac
while y != NULL and x = y.desni do
x = y
y = y.otac
return y
end
Pojam prethodnika i algoritam za nalazenje prethodnika je simetrican u odnosu na prethodni algoritam.
Prethodnik(x)
begin
if x.levi != NULL then
return Maksimum(x.levi)
y = x.otac;
while y != NULL and x = y.levi do
x = y;
y = y.p;
return y
end
9 Hes tabele, hes funkcije, kolizije i njihova obrada
Hes tabele spadaju medu najkorisnije strukture podataka. Ideja je da, ako imamo vektor duzine n ivrednosti od 1 do n da stavimo u tabelu, onda cemo vrednost i da stavimo na i-tu poziciju. Ova idejafunkcionise samo za manje vrednosti n-a. Ukoliko je opseg iz koga su vrednosti od 1 do M , gde je M nekijako veliki broj, onda ne mozemo da koristimo vektor duzine M . Primer je upis na osnovu maticnog broja.
Pretpostavimo da nam je dato n kljuceva iz skupa U velicine |U | = M >> m. Potrebno je nacifunkciju koja bi vrsila preslikavanja 0, 1, 2, ...,M − 1 −→ 0, 1, 2, ...,m− 1 koja se naziva hes funkcijai koja odreduje odgovarajucu poziciju elementa na osnovu njegovog kljuca. Ako velicina m nije dovoljnovelika, onda moze doci do deljenja odgovarajucih pozicija razlicitih podataka i to se naziva kolizija.Uniformnost i slucajnost su bitne osobine hes funkcija.
Postoje dva problema:
• Nalazenje hes funkcija koje minimiziraju verovatnocu da dode do kolizija i
• Nalazenje nacina da se obrade kolizije ako do njih ipak dode
12
Hes funkcije: Ako je velicina tabele m prost broj, onda je dobra hes funkcija:
h(x) = x mod m
Ukoliko m nije prost broj, onda se moze koristiti hes funkcija tipa:
h(x) = (x mod p) mod m,
gde je p prost broj takav da je m << p << M .Problem se javlja ako su sve vrednosti koje ubacujemo oblika r+ kp, za neki celi broj r zato sto ce uvekda idu na poziciju r. Ovaj problem se moze resiti time sto necemo uvek koristiti isto p vec ce se onomenjati po unapred odredenom redosledu. Drugo resenje je da koristimo hes funkciju oblika:
h(x) = (ax+ b mod p),
gde je a 6= 0 i a, b su slucajni brojevi. Ova funkcija u proseku daje dobro resenje.
Obrada kolizija: Razlikujemo odvojeno nizanje, linearno popunjavanje i dvostruko hesiranje kao mogucaresenja za kolizije.
Odvojeno nizanje je najjednostavniji nacin i tu je svaki element tabele u stvari pokazivac na po-vezanu listu koja cuva kljuceve kojima je hes funkcija dodelila tu poziciju. Kod trazenja kljuca se mora,u najgorem slucaju, proci cela lista kako bi se videlo da li sadrzi dati kljuc. Ovaj metod je neefikasanukoliko su liste na odgovarajucim pozicijama dugacke, a dodatno otezavanje predstavlja memorijska lo-kacija, ali s druge strane radi bez greske i ukoliko je dimenzija tabele pogresne velicine.
Linearno popunjavanje funkcionise po modelu h1(x) = (h(x) + i) mod m, gde je i ≥ 0. U slucajutrazenja zadatog elementa potrebno je pretraziti tabelu od pozicije h(x) sve do prve nepopunjene pozi-cije. Ovo resenje je efikasno ukoliko nam je tabela retka, u suprotnom bi dolazilo do mnogo sekundarnihkolizija (kolizija kljuceva kojima su vrednosti hes funkcija razlicite). Veliki broj mogucnosti za sekun-darne kolizije se naziva i efekat grupisanja.
Dvostruko hesiranje: Kada dode do kolizije na poziciji h(x) = i, izracunava se vrednost druge hesfunkcije h2(x) i onda se kljuc x stavlja na poziciju g(x) = (h(x) + i · h2(x)) mod m, za i ≥ 0. Trebavoditi racuna da vrednosti h2(x) budu uzajamno proste sa m.
10 Grafovi – predstavljanje: matrica povezanosti, lista poveza-nosti
Graf G = (V,E) sastoji se od skupa V cvorova i skupa E grana. Grana odgovara paru cvorova. Drugimrecima, grane predstavljaju relaciju izmedu cvorova. Na primer, graf moze da predstavlja skup ljudi, ada grana povezuje dva coveka ako se oni poznaju.
Graf je usmeren, odnosno neusmeren ako su mu grane uredeni, odnosno neuredeni parovi. Ako seusmereni graf predstavlja crtezom, granama se dodaju strelice koje vode ka drugom cvoru iz uredenogpara. Jednostavan primer grafa je stablo.
Uobicajena su dva nacina predstavljanja grafova:
Prvi je matrica povezanosti grafa. Neka je |V | = n i V = v1, v2, ..., vn. Matrica povezanostigrafa G je kvadratna matrica A = (aij) reda n, sa elementima aij = 1 akko (vi, vj) ∈ E, a ostali elementimatrice A su nule. Ako je graf neusmeren, matrica A je simetricna. Vrsta i ove matrice je dakle vektorduzine n cija je j-ta koordinata jednaka 1 ako iz cvora vi vodi grana u cvor vj , odnosno 0 u protivnom.Nedostatak matrice povezanosti je to sto ona uvek zauzima prostor velicine n2, nezavisno od toga kolikograna ima graf. Svakom cvoru grafa pridruzuje se vektor duzine n. Ako je broj grana u grafu mali,vecina elemenata matrice povezanosti bice nule.
13
Umesto da se i sve nepostojece grane eksplicitno predstavljaju u matrici povezanosti, mogu se formiratipovezane liste od jedinica iz i-te vrste, i = 1, 2, ..., n. Ovaj drugi nacin predstavljanja grafa zove se listapovezanosti. Svakom cvoru pridruzuje se povezana lista, koja sadrzi sve grane susedne cvoru (odnosnograne ka susednim cvorovima). Lista moze biti uredena prema rednim brojevima cvorova na krajevimanjenih grana. Graf je predstavljen vektorom lista. Svaki elemenat vektora sadrzi ime (indeks) cvora ipokazivac na njegovu listu cvorova. Ako je graf staticki, odnosno nisu dozvoljena umetanja i brisanja,onda se liste mogu predstaviti vektorima na sledeci nacin. Koristi se vektor duizne |V | + |E|. Prvih|V | clanova vektora su pridruzeni cvorovima. Komponenta vektora pridruzena cvoru vi sadrzi indekspocetka spiska cvorova susednih cvoru vi, i = 1, 2, ..., n. Na slici 3 prikazana su na jednom primeru obanacina predstavljanja grafa.
Slika 3: Predstavljanje grafa matricom povezanosti (a), odnosno listom povezanosti (b)
Sa matricama povezanosti je jednostavnije raditi. S druge strane, liste povezanosti su efikasnije zagrafove sa malim brojem grana. U praksi se cesto radi sa grafovima koji imaju znatno manje grana odmaksimalnog moguceg broja (n(n − 1)/2 neusmerenih, odnosno n(n − 1) usmerenih grana), i tada jeobicno bolje koristiti liste povezanosti.
11 Sortiranje objedinjavanjem
Preporucuje se ucenje kodova.
Algoritam radi na sledeci nacin. Najpre se niz podeli na dva jednaka ili priblizno jednaka dela (ako muje duzina neparna). Zatim se oba dela rekurzivno sortiraju. Na kraju se sortirani delovi objedinjavaju ujedan sortirani niz.
Dva sortirana niza mogu se objediniti u sortirani niz jednim prolazom. Objedinjavanje se vrsi takosto se brojevi iz drugog niza razmatraju redom: trazi se mesto u prvom nizu za najmanji broj, pa zasledeci itd. Preciznije, oznacimo nizove sa a1, a2, ..., an, odnosno b1, b2, ..., bm, i pretpostavimo da su obaniza sortirana u rastucem poretku. Elementi prvog niza se pregledaju dok se ne pronade mesto za b1,pa se umece b1. Zatim se nastavlja sa pregledanjem od te pozicije dalje, dok se ne pronade mesto za b2,
14
itd. Posto su brojevi u drugom nizu sortirani, nema potrebe za vracanjem u prvom nizu. Ukupan brojuporedivanja u najgorem slucaju jednak je zbiru duzina dva niza. Problem su premestanja: neefikasnoje premestati elemente pri svakom umetanju, jer se tada elementi moraju premestati vise puta. Umestotoga, posto objedinjavanje daje jedan po jedan elemenat u sortiranom redosledu, elemente kopiramo uprivremeni niz; svaki elemenat se kopira tacno jednom. Ukupno je za objedinjavanje dva sortirana nizaduzina n i m potrebno O(n+m) uporedivanja i premestanja podataka. Pretpostavlja se da je raspolozivmemorijski prostor za pomocni niz.
Algoritam Sort_objed(X, n);
Ulaz: X (niz od n brojeva);
Izlaz: X (sortirani niz);
begin
M_sort(1, n);
end
procedure M_Sort(Levi, Desni);
begin
if Desni - Levi = 1 then
provera koja nije neophodna, ali cini program efikasnijim
if X[Levi] > X[Desni] then zameni (X[Levi], X[Desni])
else if Levi != Desni then
Srednji := (Levi + Desni)/2;
M_Sort(Levi, Srednji - 1);
M_Sort(Srednji, Desni);
sada se dva sortirana dela niza objedinjavaju
i := Levi; pokazivac na levu polovinu niza
j := Srednji; pokazivac na desnu polovinu niza
k := 0; pokazivac na pomocni vektor Pom
while (i <= Srednji - 1) and (j <= Desni) do
k := k + 1;
if X[i] <= X[j] then
Pom[k] := X[i];
i := i + 1;
else
Pom[k] := X[j];
j := j + 1
if j > Desni then
kopiranje ostatka leve polovine na kraj vektora Pom
ako je i >= Srednji, onda je desna strana vec na svom mestu
for t := 0 to Srednji - 1 - i do
X[Desni - t] := X[Srednji - 1 - t];
kopiranje pomocnog vektora Pom nazad u X
for t := 0 to k - 1 do
X[Levi + t] := Pom[t + 1]
end
Slozenost: Neka je T (n) broj uporedivanja potrebnih za sortiranje objedinjavanjem u najgorem slucaju.Da bi se izracunalo T (n), treba resiti diferencnu jednacinu:
T (2n) = 2T (n) + cn, T (2) = 1.
Njeno resenje je T (n) = O(n log n).
Nedostatak ovog sortiranja, pored toga sto se ne realizuje lako, korak objedinjavanja zahteva dopun-sku memoriju, tj. ovo nije sortiranje u mestu. Kopiranje se radi pri svakom objedinjavanju manjihskupova, sto cini proceduru sporijom.
15
12 Sortiranje pomocu hipa (hip sort)
Hipsort predstavlja jos jedan tip brzih algoritama za sortiranje koji nije mnogo sporiji od sortiranja raz-dvajanjem, ali za razliku od njega hipsort ima garantovanu efikasnost. Njegova slozenost je O(n log n).Hipsort je algoritam koji radi u mestu (ne zahteva dodatni memorijski prostor). Pretpostavlja se da sehip predstavlja implicitno (preko niza). Hipsort se izvrsava isto kao i sortiranje izborom, razlika je uupotrebljenoj strukturi podataka. Najpre se elementi niza preurede tako da cine ispravan hip.
Problem formiranja hipa: ,,Dat je niz A[1], A[2], ..., A[n] tako proizvoljno rasporedenih elemenata i po-trebno je preurediti ih tako da cine hip.” Postoje dva pristupa formiranju hipa:
Odozgo-nadole (induktivna hipoteza): Niz A[1], A[2], ..., A[i] predstavlja hip.Bazni slucaj A[1] je trivijalan, zato sto jeste hip. Osnovni deo algoritma je ubacivanje novog elementaA[i+ 1] u hip A[1], A[2], ..., A[i]. Dakle, element A[i+ 1] se uporeduje sa svojim ocem, ako je veci, ondanjih dvojica zamenjuju pozicije i pozove se rekurzivno ubacivanje dalje u vrh. Menja se sve dok ne stignedo vrha hipa ili vrednost oca ne bude veca ili jednaka njegovoj. Slozenost je O(n log n).
Odozdo-nagore (induktivna hipoteza): Niz A[i+ 1], ..., A[n] je hip.Elementi sa indeksima vecim od n/2+1 su listovi, pa oni trivijalno zadovoljavaju uslov hipa. Dovoljno jeda indukcijom krenemo od i = n/2. Pristup odozdo-nagore je efikasniji zato sto je pola posla trivijalno.A[i] se uporeduje sa svojim sinovima A[2i] i A[2i+ 1] i zamenjuje se sa vecim ako je on manji od njega.Sa zamenama se nastavlja sve dok A[i] ne stigne na poziciju na kojoj ili nema sinove ili je veci ili jednakod vrednosti oba sina. Vremenska slozenost je O(n).
Na osnovu formiranog hipa se vrsi uklanjanje jednog po jednog elementa koriscenjem operacije ,,Uklonielement sa najvecom vrednoscu” i dobija se sortiran niz.
Algoritam Hipsort(X, n);
Ulaz: X (niz od n brojeva).
Izlaz: X (sortirani niz).
begin
Preurediti X tako da bude hip;
for i := n downto 2 do
zameni (X[1], X[n]);
Preuredi_Hip(i, 1);
procedura slicna algoritmu Skini_max_sa_hipa
end
13 Brzo sortiranje (kvik sort)
Preporucuje se ucenje kodova.
Sortiranje razdvajanjem predstavlja dobar primer algoritma zasnovanom na dekompoziciji. Ideja sorti-ranja razdvajanjem je da se veci deo vremena utrosi na fazu podele, a manji deo na objedinjavanje.
Pretpostavimo da znamo element x takav da je pola niza manje ili jednako od njega, a pola vece.Broj x se moze uporediti sa svim ostalim elementima sto je (n− 1) poredenja i podeliti ih u dve grupeprema rezultatu uporedivanja. Ovo razdvajanje se moze izvrsiti bez dopunskog memorijskog prostora– to je faza podele. Zatim se oba podniza rekurzivno sortiraju. Element x se jos naziva i pivotom iosnovna ideja je podeli niz na elemente vece ili jednake njemu i manje od njega.
Ideja je da imamo dva pokazivaca: L koji pokazuje na pocetku na skroz levi element niza i D kojipokazuje na skroz desni. Zatim se pokazivaci priblizavaju jedan drugom tako sto se L povecava ukolikoje element na koji pokazuje ≤ od pivota, a D se smanjuje sve dok je element na koji on pokazuje veciod pivota. Ako vazi L < D, onda zamenimo ta dva elementa. U protivnom, potrebno je izvrsiti dodatni
16
korak zamenjivanja pivota sa elementom na koji pokazuje D. Sledeca induktivna hipoteza (tj. invari-janta petlje) garantuje ispravnost razdvajanja:
Induktivna hipoteza. U koraku k algoritma vazi pivot ≥ xi za sve indekse i < L i pivot < xj zasve indekse j > D.
Ostaje problem izbora dobrog pivota i preciziranja poslednjeg koraka algoritma kad se pokazivaci sretnu.Algoritmi zasnovani na dekompoziciji najbolje rade kad delovi imaju priblizno iste velicine, sto sugeriseda sto je pivot blizi sredini, to ce algoritam biti efikasniji. Izbor slucajnog elementa niza je dobro resenje.Ako je polazni niz dobro ispreturan, onda se za pivot moze uzeti prvi elemenat niza.
Algoritam Quicksort(X, n);
Ulaz: X (niz od n brojeva).
Izlaz: X (sortirani niz).
begin
Q_sort(1, n);
end
procedure Q_Sort(Levi, Desni);
begin
if Levi < Desni then
S = Razdvajanje(X, Levi, Desni); S je indeks pivota posle razdvajanja
Q_Sort(Levi, S - 1);
Q_Sort(S + 1, Desni);
end
function Razdvajanje(X, Levi, Desni);
Ulaz: X (niz), Levi (leva granica niza) i Desni (desna granica niza).
Izlaz: X i S = Razdvoji, takav indeks da je X[i] <= X[S] za sve i <= S i X[j] > X[S] za sve j > S.
begin
pivot := X[Levi];
L := Levi; D := Desni;
while L < D do
while X[L] <= pivot and L <= Desni do L := L + 1;
while X[D] > pivot and D >= Levi do D := D - 1;
if L < D then
zameni X[L] i X[D];
Razdvoji := D;
zameni X[Levi] sa X[S]
end
Slozenost: Vreme izvrsenja sortiranja razdvajanjem zavisi od konkretnog ulaza i izbora pivota. Ako pivotuvek razdvaja niz na dva jednaka dela, onda je diferencna jednacina za slozenost
T (n) = 2T (n/2) + cn, T (2) = 1,
sto za posledicu ima T (n) = O(n log n). Ipak najgora analiza slucaja pokazuje da je ovaj algoritam redaO(n2), za primer ako je niz vec ureden rastuce (ili skoro ureden rastuce), posto se za pivot uvek biraprvi element.
14 Sortiranje slozenosti O(n), donja granica slozenostisortiranja kad se koriste uporedivanja
Funkcija f(n) predstavlja donju granicu slozenosti nekog problema ako za proizvoljan algoritam koji seizvrsava u vremenu T (n) vazi T (n) = Ω(f(n)). Dokazivanje da je neka funkcija donja granica slozenostinekog problema nije jednostavan posao zato sto se moraju uzeti u obzir svi algoritmi koji resavaju taj
17
problem. Neophodno je odabrati model koji odgovara odredenom nacinu resavanja, a zatim odrediti dali je slozenost tog proizvoljnog algoritma veca ili jednaka donjoj granici.
Stablo odlucivanja predstavlja model algoritma koji se zasniva uglavnom na uporedivanju. Definisese kao binarno stablo sa dve vrste cvorova, unutrasnjim i listovima. Svaki unutrasnji cvor predstavljapitanje na koje se mogu imati dva odgovora koji su predstavljeni granama, dok list predstavlja krajnjirezultat.
Ako se radi o problemu sortiranja, onda smatramo da nam je ulaz niz x1, x2, ..., xn. U svakom cvoru sepostavlja jedno pitanje u vezi sa ulazom, a broj rezultata (listova) jednak je broju permutacija ulaznogniza. Posto je n velicina niza, permutacija ima n!.
Slika 4: Sortiranje tri elementa pomocu stabla odlucivanja.
Vremenska slozenost algoritma definisanog stablom odlucivanja je najveci broj koraka koji su odredeniporedenjima, odnosno unutrasnjim cvorovima. Za stablo odlucivanja visine h, listova (resenja koja senalaze u listovima) ima najvise 2h. Za nas je bitna relacija
2h ≥ n!⇐⇒ h ≥ log2 n! > log2
(n2· n
2· ... · n
2
)︸ ︷︷ ︸
n2
= log2
(n2
)n2 =
n
2· (log2 n− 1),
odakle se dobija da svi algoritmi koji koriste uporedivanje moraju biti barem u nekom skupu slucajaslozenosti O(n log n).
Algoritam slozenosti O(n): Posmatrajuci ideju sortiranja bez uporedivanja, moze se konstruisati al-goritam sortiranja razvrstavanjem na sledeci nacin:
Neka treba sortirati niz A[1], A[2], ..., A[n] ciji su elementi celi brojevi iz opsega S = 1, 2, ...,m. Recimo,za n = 5, niz A = 3, 8, 2, 6, 4 i opseg S = 1, 2, ..., 8. Algoritam glasi:(1) Napraviti pomocni niz X duzine m i inicijalizovati njegove vrednosti na nule.(2) Prolazeci kroz niz A, kada se naide na broj i ∈ A, uvecati X[i](3) Prolazeci kroz niz X, ispisati one indekse i akko X[i] = 1.
Broj koraka ovog algoritma jednak je O(m) +O(n) = O(m+n), medutim, kako je m >> n u najcescemslucaju, broj koraka jednak je O(m). Ipak, opseg m se moze izraziti nekom multiplikativnom i/ili adi-tivnom konstantom u zavisnosti od n, pa je broj koraka jednak O(m) = O(c1 · n+ c2) = O(n).
Veliki nedostatak ovog algoritma je prostorna slozenost jer je duzina niza X jednaka broju m, za kojivazi, kao sto je prethodno receno, u najcescem slucaju m >> n.
18
15 Pretraga grafa u dubinu (dokaz ispravnosti, DFS stablo, nu-meracija cvorova, komponente povezanosti)
Preporucuje se ucenje kodova.
Neusmereni grafovi: Opis pretrage grafa u dubinu (DFS, skracenica od depth-first-search) odgovara po-lasku kroz galeriju. Uvek se trudimo da prodemo kroz neposeceni hodnik i kada se nademo na raskrsnici,ostavimo kamencic. Kada naidemo na hodnik koji ne vodi nikud, ili na vec posecenu raskrsnicu, mi sevracamo nazad do prethodne raskrsnice i pokusavamo da udemo u novi hodnik. Ako nema neposecenog,idemo nazad itd. Osnovni razlog upotrebljivosti DFS pretrage je jednostavna implementacija koriscenjemrekurzije.
Za neusmereni graf predstavljen listom povezanosti algoritam pocinje od zadatog cvora v koji predstavljakoren pretrage u dubinu. On se oznacava kao posecen i onda se vrsi rekurzivni poziv za proizvoljan cvorw koji je sused cvora v. Iz rekurzivnog poziva nekog cvora se izlazi tek ako ne postoji susedan cvor zakoji se moze pozvati dalja pretraga u dubinu.
Kako bi imao sto vecu upotrebljivost, DFS algoritam razlikuje ulaznu i izlaznu obradu pri poseti cvora.Ulazna obrada se vrsi u trenutku ulaska u novi rekurzivni poziv, dok se izlazna vrsi kada se rekurzivnipoziv zavrsava. Oni zavise od same primene DFS algoritma.
Pseudo kod uopstenog algoritma DFS:
DFS(G, v)
begin
oznaciti v;
preWork na v;
for sve grane (v, w) do
if w nije oznacen then DFS(G, w);
postWork na (v, w);
end
Sledecom lemom je obezbedena ispravnost DFS algoritma:
Lema: Ako je graf G povezan, onda ce algoritmom pretrage u dubinu svi njegovi cvorovi biti oznaceni, asve njegove grane bice u toku izvrsavanja algoritma pregledane bar po jednom.4: Pretpostavimo suprotno, i oznacimo sa U skup neoznacenih cvorova zaostalih posle izvrsavanja algo-ritma. Posto je G povezan, bar jedan cvor iz U mora biti povezan granom sa nekim oznacenim cvorom.Medutim, ovako nesto je nemoguce, jer kad god se poseti cvor, moraju biti poseceni (pa dakle i oznaceni)svi njegovi neoznaceni susedi. Posto su svi cvorovi poseceni, a kad se cvor poseti, onda se pregledaju svegrane koje vode iz njega, zakljucujemo da su i sve grane grafa pregledane. 2
Pseudo kod za pravljenje DFS stabla:
T = prazan_graf();
DFS_stablo(G, v)
begin
oznaciti v;
for sve grane (v, w) do
if w nije oznacen then
dodati (v, w) u T;
DFS(G, w);
end
Numeracija i DFS stablo imaju bitnu ulogu u mnogim algoritmima cak iako graf nije eksplicitno zadat.
19
DFS Numeracija moze biti dolazna ili odlazna koje odgovaraju ulaznoj i izlaznoj obradi. Pretposta-vimo da cvorovi imaju polja num1 i num2 koji treba da oznacavaju njihovu dolaznu, odnosno odlaznunumeraciju. Za preorder (dolaznu) numeraciju, potrebno je u preWork delu DFS algoritma staviti kodc1 = c1 + 1; v.Pre = c1, dok je za postorder (odlaznu) numeraciju potrebno u postWork delu sta-viti kod if w je poslednji u petlji then c2 = c2 + 1; v.Post = c2, pri cemu su c1 i c2
inicijalizovani na 0 pre prvog poziva.
Slika 5: Primer pretrage u dubinu. Dva broja uz cvor jednaka su njegovim rednim brojevima pri dolaznoj,odnosno odlaznoj DFS numeraciji.
Algoritam za nalazenje komponenti grafa:
Algoritam Komponente_povezanosti(G);
Ulaz: G = (V, E) (neusmereni graf);
Izlaz: v.Komp za svaki cvor v dobija vrednost jednaku rednom broju komponente povezanosti
koja sadrzi v;
begin
Rb.komp := 1;
while postoji neoznacen cvor v do
DFS(G, v);
u preWork DFS algoritma treba staviti: v.Komp := Rb.komp;
Rb.komp := Rb.komp + 1;
end
16 Klasifikacija grana grafa u odnosu na DFS stablo, kriterijumza prepoznavanje povratne grane
Pri obilasku DFS stabla razlikujemo 4 vrste grana: direktne grane, poprecne grane, povratne grane igrane stabla. Direktne, povratne i grane stabla povezuju dva cvora koji su u vezi predak–potomak. Di-rektne grane predstavljaju grane koje povezuju pretka sa potomkom. Povratne grane povezuju potomkasa pretkom. Poprecne grane povezuju dva cvora koja nisu u srodstvu u stablu i za njih vazi da morajubiti usmerene s desna na levo.
Lema (Osnovna osobina DFS stabla neusmerenog grafa): Neka je G = (V,E) povezan neusmeren graf, ineka je T = (V, F ) DFS stablo grafa G dobijeno algoritmom DFS stablo. Svaka grana e ∈ E pripada T(tj. e ∈ F ) ili spaja dva cvora grafa G, od kojih je jedan predak drugog u T .4 : Neka je (v, u) grana u G, i pretpostavimo da je u toku DFS v posecen pre u. Posle oznacavanja v, upetlji se rekurzivno pokrece DFS iz svakog neoznacenog suseda v. U trenutku kad dode red na suseda u,ako je u oznacen, onda je u potomak v u T , a u protivnom se iz u startuje DFS, pa u postaje sin v. 2
20
Tvrdenje leme moze se preformulisati na sledeci nacin: grane grafa ne mogu biti poprecne grane zaDFS stablo, odnosno grane koje povezuju cvorove na razlicitim putevima od korena (ili: takva dva cvorau i v da je npr. u levo od v).
Usmereni grafovi: Procedura pretrage u dubinu usmerenih grafova ista je kao za neusmerene grafove.Medutim, usmerena DFS stabla imaju nesto drugacije osobine. Za njih, na primer, nije tacno da nemajupoprecne grane, sto se moze videti iz primera na slici 5.
Slika 6: DFS stablo usmerenog grafa.
Lema (Osnovna osobina usmerenih DFS stabala): Neka je G = (V,E) usmereni graf, i neka je T = (V, F )DFS stablo grafa G. Ako je (v, w) ∈ E grana grafa G za koju vazi v.Pre < w.Pre, onda je w potomakv u stablu T .4 : Posto je prema dolaznoj DFS numeraciji v ispred w, w je oznacen posle v. Grana grafa (v, w)mora biti razmatrana u toku rekurzivnog poziva DFS iz cvora v. Ako u tom trenutku cvor w nije biooznacen, onda se grana (v, w) mora ukljuciti u stablo, tj. (v, w) ∈ F , pa je tvrdenje leme tacno. U protiv-nom, w je oznacen u toku izvodenja rekurzivnog poziva DFS iz v, pa w mora biti potomak v u stablu T . 2
Za DFS obilazak usmerenog grafa ne mora znaciti da se pozivom iz proizvoljnog cvora mogu obicisvi cvorovi, sto se moze videti iz primera na slici 6.
Slika 7: Primer kad DFS usmerenog grafa ne obilazi kompletan graf.
21
Razmotrimo sada za svaku granu (u, v) odnos odlaznih DFS brojeva cvorova u i v.
1. Ako je (u, v) grana stabla ili direktna grana, onda je v potomak u, pa je v.Post < u.Post.
2. Ako je (u, v) poprecna grana, onda je zbog toga sto je v levo od u, ponovo v.Post < u.Post.
3. Ako je (u, v) povratna grana i v 6= u, onda je v pravi predak u i v.Post > u.Post. Medutim, v = uje moguce za povratnu granu, jer je i petlja povratna grana. Prema tome, za povratnu granu (u, v)znamo da je v.Post ≥ u.Post.
Prema tome, dokazano je sledece tvrdenje:Lema: Grana (u, v) usmerenog grafa G = (V,E) je povratna akko prema odlaznoj numeraciji cvor uprethodi cvoru v, odnosno u.Post ≤ v.Post.
17 Pretraga grafa u sirinu, BFS stablo, osobine
Preporucuje se ucenje kodova.
Pretraga u sirinu (ili BFS, sto je skracenica od breadth-first-search) obilazak je grafa na sistematicannacin, nivo po nivo. Ako polazimo od cvora v, onda se najpre posecuju svi susedi v (deca u stablupretrage, nivo jedan). Zatim se dolazi do svih ,,unuka” (nivo dva), i tako dalje. Obilazak se realizujelistom FIFO (skracenica od first-in-first-out queue).
Prilikom obilaska cvorovi se mogu numerisati BFS brojevima, slicno kao pri DFS. Preciznije, cvor w imaBFS broj k ako je on k-ti cvor oznacen u toku BFS. BFS stablo grafa moze se formirati ukljucivanjemsamo grana ka novooznacenim cvorovima. Izlazna obrada ovde nema smisla.
Pseudo kod algoritma BFS (i pravljenja stabla T ):
BFS(G, v);
begin
oznaci v;
upisi v u red; red = FIFO lista
while red je neprazan do
skini prvi cvor w sa reda;
preWork na w; ulazna obrada zavisi od primene BFS
for sve grane (w, x) za koje x nije oznacen do
oznaci x;
dodaj (w, x) u stablo T;
upisi x u red;
end
Lema: Ako grana (u,w) pripada BFS stablu i cvor u je otac cvora w, onda cvor u ima minimalni BFSbroj medu cvorovima iz kojih postoji grana ka w.4 : Ako bi u grafu postojala grana (v, w), pri cemu v ima manji BFS broj od u, onda bi u trenutkuobrade v na listu morao biti stavljen cvor w, pa bi grana (v, w) morala biti ukljucena u stablo, suprotnopretpostavci. 2
Lema: Put od korena r BFS stabla do proizvoljnog cvora w kroz BFS stablo najkraci je put od r dow u grafu G.4 : Indukcijom po d dokazacemo da do svakog cvora w na rastojanju d od korena r (jedinstveni) putkroz stablo od r do v ima duzinu d. Za d = 1 tvrdenje je tacno: grana (r, w) je obavezno deo stabla,pa izmedu r i w postoji put kroz stablo duzine 1. Pretpostavimo da je tvrdenje tacno za cvorove kojisu na rastojanju manjem od d od korena, i neka je w neki cvor na rastojanju d od korena, tj. postojiniz cvorova w0 = r, w1, w2, ..., wd = w koji cine put duzine d od r do w. Prema induktivnoj hipoteziput od r do wd−1 kroz stablo ima duzinu d− 1. U trenutku obrade cvora wd1
, posto u G postoji grana(wd−1, wd), ta grana se ukljucuje u BFS stablo, pa do cvora wd postoji put duzine d kroz stablo. 2
22
Nivo cvora w je duzina puta u stablu od korena do w. Pretraga u sirinu obilazi graf nivo po nivo.
Lema: Ako je (v, w) grana iz E koja ne pripada T , onda ona spaja dva cvora ciji se nivoi razlikujunajvise za jedan.4 : Neka je npr. cvor v prvi dostignut pretragom i neka je njegov nivo d. Tada je nivo cvora w veci ilijednak od d. Taj nivo jednak je rastojanju w od korena, pa je manji ili jednak od d+ 1, jer do w postojiput duzine d+ 1 (put od korena do v produzen granom (v, w)). 2
18 Analiza algoritama – osnovni pojmovi (aproksimativna asimp-totska analiza najgoreg slucaja; asimptotske oznake O, o, Ω, Θ;vremenska i prostorna slozenost algoritma)
Cilj analize algoritama je da proceni brzinu izvrsavanja algoritma bez obzira na to koji racunar ga koristi.Ideja je da se proceni brzina rada bez realizacije. Tacno ponasanje algoritma je nemoguce predvidetisem u najjednostavnijim slucajevima. Analiza algoritma mora biti priblizna. Ona omogucava poredenjealgoritama koji resavaju isti problem.
Zanemaruju se konstantni faktori zato sto se i izvrsavanja na razlicitim racunarima razlikuju za kon-stantu. Najinteresantnija je asimptotska analiza algoritama, odnosno kada velicina ulaza tezi jako veli-kim vrednostima. Obicno se velicina ulaza opisuje kao memorijski prostor koji je neophodan za koriscenjealgoritma. Najcesce se koristi analiza najgoreg slucaja. Trajanje algoritma predstavlja funkciju u zavi-snosti od ulazne velicine.
Analiza asimptotskog ponasanja slozenosti algoritma, i to u najgorem slucaju medu ulazima odredenevelicine – to je dakle aproksimacija vremena rada odredenog algoritma na odredenom ulazu, koja ipaknajcesce dobro karakterise osobine algoritma.
Definicija 1: Neka su f i g pozitivne funkcije od argumenta n iz skupa N prirodnih brojeva. Kazese da je g(n) = O(f(n)) ako postoje pozitivne konstante c iN , takve da za svako n > N vazi g(n) ≤ cf(n).
Oznaka O(f(n)) se ustvari odnosi na klasu funkcija, a jednakost g(n) = O(f(n)) je uobicajena oznakaza inkluziju g(n) ∈ O(f(n)). Jasno je da je funkcija f samo neka vrsta gornje granice za funkciju g.Na primer, pored jednakosti 5n2 + 15 = O(n2) (jer je 5n2 + 15 ≤ 6n2 za n ≥ 4) vazi i jednakost5n2 + 15 = O(n3) (jer je 5n2 + 15 ≤ n3 za n ≥ 6). Ova notacija omogucuje ignorisanje multiplikativnihi aditivnih konstanti: umesto O(5n+ 4) moze se pisati O(n). Slicno, u izrazu O(log n) osnova logaritmanije bitna, jer se logaritmi za razlicite osnove razlikuju za multiplikativnu konstantu:
loga n = loga(blogb n) = logb n · loga b.
Specijalno, O(1) je oznaka za klasu ogranicenih funkcija. Lako se pokazuje da se O-izrazi mogu sabiratii mnoziti:
O(f(n)) +O(g(n)) = O(f(n) + g(n)),
O(f(n))O(g(n)) = O(f(n)g(n)).
Drugi problem u vezi sa slozenoscu algoritma je pitanje donje granice za potreban broj racunskih ope-racija. Dok se gornja granica odnosi na konkretan algoritam, donja granica slozenosti odnosi se naproizvoljan algoritam iz neke odredene klase. Zbog toga ocena donje granice zahteva posebne postupkeanalize.
Definicija 2: Za funkciju g(n) kaze se da je asimptotska donja granica funkcije T (n) i pise se T (n) =Ω(g(n)), ako postoje pozitivni c i N , takvi da za svako n > N vazi T (n) > cg(n).
Tako je na primer n2 = Ω(n2 − 100), i n = Ω(n0,9). Vidi se da simbol Ω odgovara relaciji ≥.
23
Definicija 3: Ako za dve funkcije f(n) i g(n) istovremeno vazi i f(n) = O(g(n)) i f(n) = Ω(g(n)),onda one imaju iste asimptotske brzine rasta, sto se oznacava sa f(n) = Θ(g(n)).
Tako je na primer 5n log2 n−10 = Θ(n log n), pri cemu je u poslednjem izrazu osnova logaritma nebitna.
Definicija 4: Cinjenica da je limn→∞
f(n)
g(n)= 0 oznacava se sa f(n) = o(g(n)).
Ocena (vremenske) slozenosti algoritma sastoji se u brojanju racunskih koraka koje treba izvrsiti.Medutim, termin racunski korak moze da podrazumeva razlicite operacije, na primer sabiranje i mnozenje,cije izvrsavanje traje razlicito vreme. Zato se obicno u okviru algoritma izdvaja neki osnovni korak, onajkoji se najcesce ponavlja. Tako, ako se radi o sortiranju, osnovni korak je uporedivanje. Ako je brojuporedivanja O(f(n)), a broj ostalih operacija je proporcionalan broju uporedivanja, onda je O(f(n))granica vremenske slozenosti algoritma.
Pod prostornom slozenoscu algoritma podrazumeva se velicina memorije potrebne za izvrsavanjealgoritma, pri cemu se prostor za smestanje ulaznih podataka najcesce ne racuna. Kao i kod vremenskeslozenosti, i za prostornu slozenost se najcesce trazi njeno asimptotsko ponasanje u najgorem slucaju,za velike velicine problema. Prostorna slozenost O(n) znaci da je za izvrsavanje algoritma potrebnamemorija proporcionalna onoj za smestanje ulaznih podataka. Ako je pak prostorna slozenost algoritmaO(1), onda to znaci da je potreban memorijski prostor za njegovo izvrsavanje ogranicen konstantom, bezobzira na velicinu ulaza.
19 Primeri sumiranja
Ako je osnova nekog algoritma petlja koja se izvrsava i = 1, 2, .., n puta, a izvrsavanje i-tog prolaska kroz
petlju trosi f(i) koraka, onda se broj koraka algoritma moze prikazati kaon∑
i=1
f(i).
Primer 1: Ako je f(i) = i, odnosno u i-tom prolasku kroz petlju izvrsava se i koraka, onda je ukupan
broj koraka S(n) =n∑
i=1
i = 12n(n+ 1).
4 : Kako je 1 = 12 · 1 · 2, tvrdenje je tacno za n = 1. Ako se pretpostavi da je ono tacno za neko n, onda
je:
S(n+ 1) = 1 + 2 + ...+ n+ (n+ 1) = S(n) + n+ 1 =1
2n(n+ 1) + (n+ 1) =
1
2(n+ 1)(n+ 2),
odnosno zakljucujemo da je tvrdenje tacno i za n+ 1. 2
Primer 2: (Stepene sume) Ako sa Sk(n) oznacimo opstiju sumu k-tih stepena prvih n prirodnih brojeva,n∑
i=1
ik, za izracunavanje suma Sk(n) moze se iskoristiti rekurentna relacija
Sk(n) = − 1
k + 1
k−1∑j=0
(k + 1
j
)Sj(n) +
1
k + 1((n+ 1)k+1 − 1).
Polazeci od S0(n) = n, S1(n) = n(n+ 1)/2, za k = 2 se dobija
S2(n) =
n∑i=1
i2 = −1
3(S0(n) + 3S1(n)) +
1
3((n+ 1)3 − 1) =
=1
3
(n3 + 3n2 + 3n− n− 3
n(n+ 1)
2
)=
1
6(n3 + 3n2 + n) =
=1
6n(n+ 1)(n+ 2)
24
Primer 3: Suma geometrijske progresije
F (n) =
n∑i=0
qi =qn+1 − 1
q − 1
dobija se oduzimanjem jednakosti F (n) =n∑
i=0
qi od q · F (n) =n∑
i=0
qi+1 =n+1∑i=1
qi:
(q − 1) · F (n) =
n+1∑i=1
qi −n∑
i=0
qi = qn+1 − 1.
Primer 4: Polazeci od izraza za sumu geometrijske progresije moze se izracunati suma G(n) =n∑
i=1
i2i.
Diferenciranjem, pa mnozenjem sa x jednakosti
n∑i=0
xi = (xn+1 − 1)/(x− 1)
dobija sen∑
i=1
ixi = x(n+ 1)xn(x− 1)− (xn+1 − 1)
(x− 1)2.
Odatle se za x = 2 dobija G(n) = (n− 1)2n+1 + 2.
Primer 5: Svodenjem na prethodnu moze se izracunati suma
H(n) =
n∑i=1
i2n−i.
Zaista, smenom indeksa sumiranja j = n − i, i = n − j, pri cemu j prolazi skup vrednosti n − 1, n −2, ..., n− n = 0, dobija se
H(n) =
n−1∑j=0
(n− j)2j = n
n−1∑j=0
2j −n−1∑j=0
j2j = n · F (n− 1)−G(n− 1) =
= n(2n − 1)− (n− 2)2n − 2 = 2n+1 − n− 2.
U slucaju kad je tesko izracunati sumun−1∑i=0
f(i), a funkcija f(x) od realnog argumenta je monotono
nerastuca neprekidna funkcija za x ≥ 0, tada se sabiranjem nejednakosti
f(i) ≥∫ i+1
i
f(x)dx ≥ f(i+ 1), 0 ≤ i ≤ n− 1,
dobijaju nejednakostin−1∑i=0
f(i) ≥∫ n
0
f(x)dx ≥n∑
i=1
f(i),
a time i granice intervala u kome lezi suman−1∑i=0
f(i):
∫ n
0
f(x)dx+ f(0)− f(n) ≥n−1∑i=0
≥∫ n
0
f(x)dx.
Ako je pak funkcija f(x) monotono neopadajuca, u ovim nejednakostima samo treba promeniti znake,,≥” u ,,≤”.
25
20 Resavanje linearnih rekurentnih relacija
Ako za clanove niza Fn, n = 1, 2, ..., vazi jednakost
Fn = f(Fn−1, Fn−2, ..., F1, n), (1)
onda se kaze da niz Fn zadovoljava diferencnu jednacinu (ili rekurentnu relaciju) (1). Specijalno, ako seza neko k ≥ 1 clan Fn izrazava preko k prethodnih clanova niza,
Fn = f(Fn−1, Fn−2, ..., Fn−k, n), (2)
onda je k red te diferencne jednacine.
Linearne diferencne jednacine: Razmotricemo sada homogene linearne diferencne jednacine oblika
F (n) = a1F (n− 1) + a2F (n− 2) + ...+ akF (n− k). (3)
Resenja se mogu traziti u oblikuF (n) = rn, (4)
gde je r pogodno izabrani (kompleksni) broj. Zamenom u (3) dobija se uslov koji r treba da zadovolji:
rk − a1rk−1 − a2rk−2 − ...− ak = 0,
takozvana karakteristicna jednacina linearne diferencne jednacine (3); polinom sa leve strane ove jednacineje karakteristicni polinom ove linearne diferencne jednacine. U slucaju kad su svi koreni karakteristicnogpolinoma r1, r2, ..., rk razliciti, dobijamo k resenja (3) oblika (4). Tada se svako resenje moze predstavitiu obliku
F (n) =
k∑i=1
cirni
(ovo tvrdenje navodimo bez dokaza). Ako je prvih k clanova niza F (n) zadato, resavanjem sistema od klinearnih jednacina dobijaju se koeficijenti ci, i = 1, 2, ..., k, a time i trazeno resenje.
U opstem slucaju, ako su koreni karakteristicne jednacine r1, r2, ..., rs visestrukosti redom m1,m2, ...,ms
(∑mi = k), onda se svako resenje jednacine (3) moze predstaviti u obliku
F (n) =
s∑i=1
hi(n),
gde jehi(n) = (Ci0 + Ci1n+ Ci2n
2 + ...+ Ci,mi−1nmi−1)rni
(ovo tvrdenje takode navodimo bez dokaza).
Diferencne jednacine koje se resavaju sumiranjem. Cesto se nailazi na linearnu nehomogenudiferencnu jednacinu oblika
F (n+ 1)− F (n) = f(n) (5)
pri cemu F (0) ima zadatu vrednost. Drugim recima, razlika dva uzastopna clana trazenog niza jednakaje datoj funkciji od indeksa n. Resavanje ovakve diferencne jednacine svodi se na izracunavanje sumen−1∑i=0
f(i). Zaista, ako u gornjoj jednakosti n zamenimo sa i i izvrsimo sumiranje njene leve i desne strane
po i u granicama od 0 do n− 1, dobijamo
n−1∑i=0
f(i) =
n−1∑i=0
F (i+ 1)−n−1∑i=0
F (i) =
n∑i=1
F (i)−n−1∑i=0
F (i) = F (n)− F (0).
Prema tome, resenje diferencne jednacine (5) dato je izrazom
F (n) =
n−1∑i=0
f(i) + F (0). (6)
26
21 Rekurentna relacija T (n) = aT (n/b) + cnk koja opisuje algo-ritme zasnovane na razlaganju (”divide-and-conquer”)
Pretpostavimo da nam je cilj analiza algoritma A, pri cemu broj operacija T (n) pri primeni algoritmaA na ulaz velicine n (vremenska slozenost) zadovoljava diferencnu jednacinu tipa
T (n) = aT(nb
)+ cnk (7)
pri cemu je a, b, c, k ≥ 0, b 6= 0, i zadata je vrednost T (1). Ovakva jednacina dobija se za algoritam kodkoga se obrada ulaza velicine n svodi na obradu a ulaza velicine n/b, posle cega je potrebno izvrsiti joscnk koraka da bi se od parcijalnih resenja konstruisalo resenje kompletnog ulaza velicine n. Jasno jezasto se za ovakve algoritme kaze da su tipa ,,zavadi pa vladaj ”, (engleski divide-and-conquer), kako sejos zovu algoritmi zasnovani na dekompoziciji. Obicno je u ovakvim diferencnim jednacinama b prirodanbroj.
Master teorema: Asimptotsko ponasanje niza T (n), resenja diferencne jednacine (7) dato je jed-nakoscu
T (n) =
O(nlogb a) za a > bk
O(nk log n) za a = bk
O(nk) za a < bk(8)
4: Dokaz teoreme bice sproveden samo za podniz n = bm, gde je m celi nenegativni broj. Pomnozivsiobe strane jednakosti (7) sa a−m/c, dobijamo diferencnu jednacinu tipa (5)
tm = tm−1 + qm, t0 =1
cT (1),
gde su uvedene oznake tm = 1ca−mT (bm) i q = bk/a. Njeno resenje je:
tm = t0 +
m∑i=1
qi
Za q 6= 1 jem∑i=1
= (1 − qm+1)/(1 − q) − 1, pa se asimptotsko ponasanje niza tm opisuje sledecim
jednakostima
tm =
O(m) za q = 1O(1) za 0 < q < 1O(qm) za q > 1
(9)
Posto je T (bm) = camtm, n = bm, odnosno m = logbn, redom se za 0 < q < 1 (bk < a), q = 1 (bk = a,odnosno logb a = k) i q > 1 (bk > a) dobija
T (n) =
O(am) = O(bm logb a) = O(nlogb a) za a > bk
O(mam) = O(logb n · nlogb a) = O(nk log n) za a = bk
O((aq)m) = O(bmk) = O(nk) za a < bk(10)
cime je tvrdenje teoreme dokazano. 2
22 Rekurentne relacije sa potpunom istorijom;
primer T (n) = 2n
n∑i=1
T (i) + n − 1, T (1) = 0 (prosecna slozenost
algoritma kvik sort)
Diferencna jednacina najopstijeg oblika (1) zove se potpuna rekurzija ili diferencna jednacina sa potpu-nom istorijom. Razmotriemo jedan primer ovakvih diferencnih jednacina.
27
Diferencna jednacina
T (n) = n− 1 +2
n
n−1∑i=1
T (i), n ≥ 2, T (1) = 0 (11)
vazna je, jer se do nje dolazi pri analizi prosecne slozenosti sortiranja razdvajanjem, algoritma zauredivanje zadatog skupa brojeva po velicini (sortiranje, videti u knjizi pod 5.3.4). Ideja o ,,elimina-ciji istorije” moze se i ovde primeniti – zbog toga je zgodno prepisati zadatu jednacinu tako da se u njoj
uz sumun−1∑i=1
T (i) ne pojavljuje promenljivi cinilac n:
nT (n) = n(n− 1) + 2
n−1∑i=1
T (i).
Zatim ovu jednakost treba oduzeti od one koja se od nje dobija zamenom n sa n+ 1:
(n+ 1)T (n+ 1)− nT (n) = (n+ 1)n+ 2
n∑i=1
T (i)− n(n− 1)− 2
n−1∑i=1
T (i) = 2n+ 2T (n),
odnosno
T (n+ 1) =2n
n+ 1+n+ 2
n+ 1T (n), n ≥ 2
Ovim je prvi cilj postignut: dobijena diferencna jednacina povezuje samo dva uzastopna clana niza.Resavanje ove diferencne jednacine moze se svesti poznat problem (5) deljenjem sa n + 2 i smenomtn = T (n)/(n+ 1):
T (n+ 1)
n+ 2− T (n)
n+ 1=
2n
(n+ 1)(n+ 2),
odnosno
tn+1 − t(n) =2n
(n+ 1)(n+ 2).
Zamenom n sa i i sumiranjem po i u granicama od 1 do n dobija se (t1 = 0)
tn+1 − tn =
n∑i=1
2i
(i+ 1)(i+ 2). (12)
Da bi se izracunala suma sa desne strane ove jednakosti, moze se njen opsti clan razloziti na parcijalnerazlomke
2i
(i+ 1)(i+ 2)=
A
i+ 1+
B
i+ 2,
gde se nepoznati koeficijenti A i B dobijaju tako sto se u identitetu 2i = A(i+ 2) +B(i+ 1) stavi najprei = −1 (dobija se A = −2), a onda i = −2 (odakle je B = 4). Sada je trazena suma jednaka
n∑i=1
= −2
n∑i=1
1
i+ 1+ 4
n∑i=1
1
i+ 2= −2
n+1∑i=2
1
i+ 4
n+2∑i=3
1
i=
= 2∑i=3
1
i− 2 · 1
2+
4
n+ 2= 2H(n+ 1)− 4 +
4
n+ 2,
gde je sa
H(n) =
n∑i=1
1
i= lnn+ γ +O
(1
n
), (13)
28
oznacena parcijalna suma harmonijskog reda; γ ≈ 0, 577 je Ojlerova konstanta. Zamenom vrednostisume u (12) dobija se resenje diferencne jednacine (11)
T (n+ 1) =
(2H(n+ 1)− 4 +
4
n+ 2
)(n+ 2) = 2(n+ 1)H(n+ 1)− 4(n+ 1),
odnosno
T (n) = 2nH(n)− 4n = 2n lnn+ (2γ − 4)n+O(1) = O(n log n). (14)
U toku izvodenja koriscen je poznati asimptotski razvoj (13). Cesto je korisno znati i asimptotski razvojza n!, Stirlingovu formulu
n! =2√
2πn(ne
)n(1 +O
(1
n
)),
odnosno
log(n!) = O(n log n). (15)
23 Algoritmi grube sile (najveci clan niza, dve najblize tacke uravni, problem trgovackog putnika)
Nalazenje najveceg ili najmanjeg elementa u nizu je jednostavno. Ako znamo najveci elemenat u nizuduzine n−1, onda treba da ga jos uporedimo sa n-tim elementom da bismo pronasli najveci elemenat nizaduzine n. Nalazenje najveceg elementa niza duzine 1 je trivijalno. Proces zahteva jedno uporedivanje poelementu, pocevsi od drugog elementa. Ukupan broj uporedivanja je dakle n− 1.
Mogu se izracunati rastojanja izmedu svake dve tacke, i zatim pronaci najmanje medu rastojanjima.To obuhvata n(n− 1)/2 izracunavanja rastojanja i n(n− 1)/2− 1 uporedivanja.Direktno induktivno resenje moglo bi se zasnivati na uklanjanju jedne tacke, resavanju problema za n−1tacaka, i dodavanju nove tacke. Medutim, jedina korisna informacija koja se dobija resavanjem problemaza n−1 tacaka je minimalno rastojanje, pa se moraju proveriti rastojanja nove tacke do svih prethodnihn− 1 tacaka. Zbog toga ukupan broj T (n) izracunavanja rastojanja za n tacaka zadovoljava diferencnujednacinu T (n) = T (n−1)+n−1, T (2) = 1, cije je resenje T (n) = O(n2). Dva opisana resenja sustinskisu ekvivalentna.
Problem trgovackog putnika: Za n gradova zadata su rastojanja svakog grada do drugih; potrebnoje obici sve gradove tako da predeni put bude najmanji. Ukoliko krecemo od nekog proizvoljnog grada,onda treba da obidemo n−1 grad. Algoritam se sastoji od trazenju najmanjeg puta izmedu tih preostalihgradova. Ukupan broj svih puteva je broj permutacija n− 1 elemenata, sto je jednako (n− 1)!.
24 Pohlepni (greedy) algoritmi: problem izbora aktivnosti
Preporucuje se ucenje kodova.
Neka je dat spisak aktivnosti koje treba da se odrze u nekoj sali. Svaka aktivnost i ima svoje pocetnovreme s[i] i vreme zavrsetka f [i], pri cemu je s[i] < f [i] za svako i. Problem se formulise tako da jepotrebno napraviti takav raspored koji dozvoljava sto veci broj aktivnosti tako da se one ne preklapaju.Prvo je potrebno sortirati nizove po vremenu zavrsetka (niz f mora biti rastuci, a uporedo se sa njim iniz s sortira). Prva aktivnost ce se sigurno naci u konacnom resenju jer se prva zavrsava i ostavlja najviseprostora za ostale aktivnosti, pa je zato ubacujemo u skup resenja A. Zatim, uzimamo sledecu aktivnostkoja se najranije zavrsava. Proveravamo njeno vreme pocetka i ukoliko je manje od zavrsnog vremenaprethodno ubacene aktivnosti, onda se ta aktivnost ne ukljucuje, vec se nastavlja dalje sa pretragom.Inace, aktivnost se dodaje u trazeni skup A i indeks poslednje dodate se postavlja na broj indeksa uneteaktivnosti.Slozenost ovog algoritma je O(n) ukoliko je vec dat sortiran niz zavrsnih vremena aktivnosti.
29
Aktivnosti(s, f, n)
begin
nizovi s, f su sortirani po vremenu zavrsetka
A = [1]; A je trazeni skup aktivnosti
poslednja = 1; poslednja ukljucena aktivnost
for j = 2 to n do
if s[j] >= f[poslednja] then
A = A + [j]; dodavanje naredne aktivnosti u skup
poslednja = j;
return A;
end
25 Pohlepni (greedy) algoritmi: razlomljeni problem ranca
Pretpostavimo da ranac treba napuniti stvarima. Neka je kapacitet ranca W , a stvari imaju svoje tezinew1, w2, ..., wn i vrednosti p1, p2, ..., pn. Resenje treba da bude u obliku niza x (inicijalizovanog nulama),za koji vazi da je x[i] deo i-tog predmeta koji se stavlja u ranac. Cilj je staviti u ranac stvari sto vece
vrednosti, pri cemu se predmeti mogu rezati, odnosnon∑
i=1
x[i] · w[i] ≤ W i P =n∑
i=1
j · p[i], j ∈ [0, 1] je
maksimalna vrednost ovih predmeta. Neka, bez umanjenja opstosti, vazi da su predmeti sortirani tako
da je niz c[i]df=p[i]
w[i], i = 1, 2, ..., n, opadajuci. Primetimo da je niz c niz vrednosti predmeta po jedinici
tezine. Tako da ce prvi elemenat niza c imati najvecu, a poslednji najmanju vrednost (u odnosu natezinu).Algoritam se svodi na to da se biraju predmeti redom, sto se svodi na upisivanje jedinica u niz x (zasvaku jedinicu znaci da uzimamo ceo predmet), sve dok se za neki i-ti predmet ne prevagne kapacitetranca. U tom slucaju, potrebno je uzeti samo neki deo k tog i-tog predmeta, za koji vazi x[1] · w[1] +x[2] · w[2] + ...+ k · w[i] = W , pri cemu se za x[i] uzima upravo taj deo k. Ovim se algoritam zavrsava,posto je niz x bio inicijalizovan na nule, pa se ostali predmeti ne uzimaju.
26 Pohlepni (greedy) algoritmi: optimalni prefiksni (Hofma-nov) kod
Zadat je tekst sa n razlicitih znakova, tako da su ucestanosti znakova zadate nizom F = f1, f2, ..., fn.Odrediti prefiksni kod E koji minimizira broj bita L(E,F ) upotrebljenih za kodiranje.
Slika 8: Predstavljanje prefiksnog koda stablom.
Za prefiksni kod koji minimizira vrednost L(E,F ) kaze se da je optimalni kod; on ocigledno zavisi
30
od niza ucestanosti znakova F . Cilj je za dati niz F odrediti optimalni prefiksni kod (bilo koji; uopstem slucaju postoji vise razlicitih optimalnih kodova). Razmotrimo zbog toga malo detaljnije osobineoptimalnih kodova:
1. Ako je f1 > f2, onda je l1 ≤ l2 (jer bi u protivnom, za l1 > l2 vazilo da je (f1 − f2)(l1 − l2) > 0,odnosno f1l1 + f2l2 > f1l2 + f2l1 sto znaci da bi broj bitova za prva dva slova bio veci od brojabitova ako zamenimo kodove, sto je suprotno pretpostavci da se radi o optimalnom kodu)
2. U kodnom stablu, svaki unutrasnji cvor mora da ima oba sina, u protivnom bi se kod mogaopojednostaviti skracivanjem kodnih reci u listovima podstabla ispod cvora sa samo jednim sinom(pogledati sliku 9)
3. Postoji optimalni kod u kojem su dva najreda slova u poslednjem nivou i sinovi istog oca (pogledatisliku 10)
Slika 9: Kodno stablo u kome neki cvor ima samo jednog sina sto nije kodno stablo optimalnog koda.
Slika 10: Transformacija kodnog stabla, posle koje dva znaka sa najmanjim frekvencijama fi i fj postajusinovi istog oca.
Realizacija. Operacije koje se izvrsavaju prilikom formiranja Hofmanovog koda su
• umetanje u strukturu podataka,
• brisanje dva znaka sa najmanjim frekvencijama iz strukture, i
• konstrukcija kodnog stabla.
Hip je pogodna struktura podataka za prve dve operacije, jer se tada te operacije u najgorem slucajuizvrsavaju za O(log n) koraka. Algoritam za formiranje Hofmanovog koda glasi:
Algoritam Hofman(S, F);
Ulaz: S (string znakova koji se pojavljuju u tekstu) i F (frekvencije).
Izlaz: T (kodno stablo Hofmanovog koda za S).
begin
ubaciti sve znake u hip H prema njihovim frekvencijama;
31
while H neprazan do
if H sadrzi samo jedan znak X then
formiraj stablo T koje ima samo koren, cvor X
else
skini sa hipa H znakove X, Y sa najmanjim frekvencijama fX, fY;
zameni X i Y novim znakom Z sa frekvencijom fZ = fX + fY;
ubaci Z u hip H;
povezi X i Y tako da budu sinovi Z u T; Z jos nema oca
end
Primer: Neka je dat fajl u kome se pojavljuju znaci A, B, C, D, E i F sa frekvencijama redom 5, 2,3, 4, 10 i 1. Dva znaka sa najmanjim frekvencijama su F i B; oni se zamenjuju novim znakom BF safrekvencijom 1 + 2 = 3. Dalja zamenjivanja prikazana su u sledecoj tabeli.
Na slici 11 prikazano je dobijeno kodno stablo.
Slika 11: Stablo Hofmanovog koda iz primera.
Slozenost. Slozenost dodavanja novog cvora stablu ogranicena je konstantom. Umetanja i brisanja izhipa izvrsavaju se u O(log n) koraka. Slozenost algoritma je dakle O(n log n).
27 Resavanje problema razlaganjem (divide-and-conquer): bi-narna pretraga i varijante
Osnovna ideja binarne pretrage je podela prostora na dva priblizno jednaka dela postavljanjem samojednog pitanja.
Problem (cista binarna pretraga). Neka je x1, x2, ..., xn niz realnih brojeva takav da je x1 ≤ x2 ≤... ≤ xn. Za zadati realni broj z treba ustanoviti da li se z pojavljuje u nizu, a ako je odgovor ,,da”,potrebno je pronaci indeks i takav da je xi = z.
Ideja je prepoloviti prostor koji se pretrazuje tako sto se najpre proveri srednji clan niza. Pretpo-stavimo zbog jednostavnosti da je n paran broj. Ako je z manje od xn/2+1, onda z moze biti samo uprvoj polovini niza; u protivnom, z moze biti samo u drugoj polovini niza. Pronalazenje z u prvoj ili
32
drugoj polovini niza je problem velicine n/2, koji se resava rekurzivno. Bazni slucaj n = 1 resava seneposrednim uporedivanjem z sa elementom.
Algoritam Binarna_Pretraga(X, n, z);
Ulaz: X (niz od n brojeva, uredenih neopadajuce) i z (broj koji se trazi).
Izlaz: Poz (indeks i takav da je X[i] = z, ili 0 ako takav indeks ne postoji).
begin
Poz = Nadji(z, 1, n);
end
function Nadji(z; Levi;Desni)
begin
if Levi = Desni then
if X[Levi] = z then Nadji = Levi;
else Nadji = 0;
else
Srednji = (Levi + Desni)/2;
if z < X[Srednji] then
Nadji = Nadji(z, Levi, Srednji - 1)
else
Nadji = Nadji(z, Srednji, Desni)
end
Slozenost. Slozenost binarne pretrage niza od n elemenata moze se opisati rekurentnom relacijomT (n) = T (n/2) + 1, odakle se dobija da je slozenost O(log n) na osnovu Master teoreme.
Problem. Za zadati rastuce uredeni niz celih brojeva a1, a2, ..., an utvrditi da li postoji indeks i, takavda je ai = i.
Ovaj problem je moguci svesti na binarnu pretragu. Zaista, niz xi = ai − i je neopadajuci (jer jexi+1−xi = ai+1−ai−1 ≥ 0), a uslov ai = i je ekvivalentan uslovu xi = 0. Prema tome, zadati problemresava se binarnom pretragom niza xi, u kome se trazi broj z = 0.
Problem (binarna pretraga ciklicki uredenog niza). Za zadati cikliqcki uredeni niz pronaci po-ziciju minimalnog elementa niza (zbog jednostavnosti moze se pretpostaviti da je ta pozicija jedinstvena).
Za niz x1, x2, ..., xn kaze se da je ciklicki ureden ako vaze nejednakosti
xi < xi+1 < ... < xn < x1 < ... < xi−1,
gde je xi najmanji elemenat niza.Da bismo pronasli minimalni elemenat xi u nizu, koristimo ideju binarne pretrage da jednim uporedivanjemeliminisemo polovinu niza. Uzmimo proizvoljna dva broja xk i xm takva da je k < m. Ako je xk < xm,onda i ne moze biti u intervalu k < i ≤ m, jer je xi najmanji elemenat niza (u tom slucaju bilo bixi < xm < xk – suprotno pretpostavci da je xk < xm). U protivnom, ako je xk > xm, onda i mora bitiu intervalu k < i ≤ m, jer je tada monotonost niza prekinuta negde u intervalu indeksa [k,m]. Prematome, jednim uporedivanjem moze se eliminisati mnogo elemenata.Odgovarajucim izborom k i m, i se moze odrediti pomocu O(log n) uporedivanja. Invarijanta glavnepetlje algoritma je uslov da se i uvek nalazi u intervalu [Levi,Desni].
Algoritam Cikl_Binarna_Pretraga(X, n);
Ulaz: X (vektor sa ciklicki uredenim nizom od n razlicitih brojeva);
Izlaz: poz (indeks minimalnog elementa u X);
begin
poz = c_Nadji(1, n);
end
33
function c_Nadji(Levi, Desni)
begin
if Levi = Desni then
c_Nadji = Levi;
else
Srednji = (Levi + Desni)/2;
if X[Srednji] < X[Desni] then
c_Nadji = c_Nadji(Levi, Srednji);
else
c_Nadji = c_Nadji(Srednji + 1, Desni);
end
Problem (Binarna pretraga niza nepoznate duzine). Posmatrajmo varijantu problema pretragekad se zadati broj z trazi u uredenom nizu nepoznate duzine. Da bi se problem sveo na vec resen,potrebno je pronaci bar jedan indeks i takav da je xi > z: tada se moze preci na binarnu pretragu opsegaindeksa od 1 do i.
Moze se postupiti na sledeci nacin. Najpre se z uporeduje sa x1. Ako je z ≤ x1, onda z moze bitijednako samo broju x1. Pretpostavimo da znamo indeks j takav da je z > xj . Posle uporedivanja zsa x2j postoje dve mogucnosti. Ako je z ≤ x2j , onda znamo da je xj < z ≤ x2j , pa se z moze pronacipomocu O(log2 j) uporedivanja. Ako je pak z > x2j , onda je prostor za pretrazivanje udvostrucen, itreba nastaviti (indukcijom) tako sto se j zameni sa 2j.Pretpostavimo da je i najmanji indeks takav da je z ≤ xi. Tada je dovoljno O(log2 i) uporedivanja dase (udvostrucavanjem) pronade takvo xj koje je vece ili jednako od z, i novih O(log2 i) uporedivanja dase pronade z.Isti algoritam moze se upotrebiti i ako je duzina niza poznata, ali ocekujemo da je indeks i vrlo mali.Da bi ovaj algoritam bio bolji od obicne binarne pretrage, potrebno je da bude priblino 2 log2 i < log2 n,odnosno i <
√n.
28 Resavanje problema razlaganjem (divide-and-conquer): is-tovremeno trazenje najmanjeg i najveceg clana niza
Podelimo skup na dva podskupa sa jednakim brojem elemenata. Resivsi rekurzivno oba potproblemadobijamo dva minimalna (a1 i a2) i dva maksimalna elementa (b1 i b2), pri cemu su a1 i b1 iz prvog, a a2i b2 iz drugog podniza. Potrebno je videti koliko uporedivanja je potrebno da je odrede maksimum i mi-nimum od ova cetiri broja. Lako je videti da ce biti dovoljna 2 pitanja: Prvo pitanje je a2 ≥ a1? Ukolikoje odgovor ,,da”, onda se postavlja pitanje b2 ≥ a1? Ukoliko je odgovor ,,da”, onda se u rekurzivnompozivu vraca par (a2, b2), a ukoliko je odgovor ,,ne”, onda se vraca par (a2, a1). Ukoliko je odgovor naprvo pitanje bio ,,ne”, onda se postavlja pitanje a2 ≥ b1? Ukoliko je odgovor ,,da”, onda se vraca par(a1, a2), a inace se vraca par (a1, b1).
Dakle, rekurentna relacija izgleda
T (n) = 2T (n/2) + 2, T (2) = 1,
odakle se dobija (n = 2k)
T (2k) = 2T (2k−1) + 2
= 2(2T (2k−1) + 2) + 2 =
= 22T (2k−2) + 22 + 2 =
= 23T (2k−3) + 23 + 22 + 2 =
= ... =
34
= 2k−1T (2) + 2k−1 + ...+ 22 + 2︸ ︷︷ ︸2k−2
=
= 2k−1 + 2k − 2
T (n) =n
2+ n− 2 =
=3n
2− 2
29 Resavanje problema razlaganjem (divide-and-conquer): pro-blem selekcije – nalazenje k-tog najmanjeg clana niza
Problem. Za zadati niz elemenata S = x1, x2, ..., xn i prirodni broj k, 1 ≤ k ≤ n, odrediti k-ti najmanjielemenat u S.
Ideja je primeniti dekompoziciju na isti nacin kao i kod algoritma sortiranje razdvajanjem, sem stoje ovog puta dovoljno resiti samo jedan od dva potproblema. Kod sortiranja razdvajanjem niz se raz-dvaja pomocu pivota na dva podniza. Dva podniza se zatim sortiraju rekurzivno. Ovde je dovoljnoodrediti koji od podnizova sadri k-ti najmanji elemenat, a onda algoritam primeniti rekurzivno samo nataj podniz. Ostali elementi mogu se ignorisati.
Algoritam Selekcija(X, n, k);
Ulaz: X (niz od n brojeva) i k (prirodni broj);
Izlaz: S (k-ti najmanji elemenat; niz X je promenjen);
begin
if (k < 1) or (k > n) then print "greska";
else
S = Sel(1, n, k);
end
function Sel(Levi, Desni, k);
begin
if Levi = Desni then
Sel = Levi;
else
S = Razdvajanje(X, Levi, Desni); videti sliku *
if S - Levi + 1 >= k then
Sel = Sel(Levi, S, k);
else
Sel = Sel(S + 1, Desni, k - (S - Levi + 1));
end
Slozenost. Kao i kod sortiranja razdvajanjem, los izbor pivota vodi kvadratnom algoritmu. Srednjaslozenost ovog algoritma moze se oceniti na slican nacin kao kod sortiranja razdvajanjem. Rekurentnarelacija koja opisuje prosecnu slozenost ovog algoritam je T (n) = T (n/2) + cn, odakle se iz Masterteoreme dobije slozenost O(n).
30 Resavanje problema razlaganjem (divide-and-conquer): mnozenjepolinoma, brojeva slozenosti O(nlog2 3)
Neka su P =n−1∑i=0
pixi i Q =
n−1∑i=0
qixi dva polinoma stepena n− 1. Polinom je predstavljen nizom svojih
koeficijenata.
Problem. Izracunati proizvod dva zadata polinoma stepena n− 1.
35
Prirodno je poci od izraza
PQ = (p0 + p1x+ ...+ pn−1xn−1)(q0 + q1x+ ...+ qn−1x
n−1) = (16)
= p0q0 + x(p0q1 + q0p1) + x2(p0q2 + p1q1 + p2q0) + ...+ x2n−2(pn−1qn−1)
Koeficijenti polinoma PQ mogu se izracunati direktno iz (16), pri cemu je jasno da ce tada broj mnozenjai sabiranja biti O(n2).
Pretpostavimo zbog jednostavnosti da je n stepen dvojke. Svaki od polinoma delimo na dva jednakadela. Neka je dakle P = P1 + xn/2P2 i Q = Q1 + xn/2Q2, gde su
P1 = p0 + p1x+ ...+ pn/2−1xn/2−1, P2 = pn/2 + pn/2+1x+ ...+ pn−1x
n/2−1,
Q1 = q0 + q1x+ ...+ qn/2−1xn/2−1, Q2 = qn/2 + qn/2+1x+ ...+ qn−1x
n/2−1.
U izrazu za PQ pojavljuju se proizvodi polinoma stepena n/2−1, koji se mogu izracunati indukcijom (re-kurzivno). Sabiranjem dobijenih rezultata dobija se resenje. Uzimajuci u obzir da je mnozenje polinomastepena 0 isto sto i mnozenje brojeva, ovim je kompletno definisan rekurzivni algoritam za mnozenjepolinoma. Ukupan broj operacija T (n) koje se izvrsavaju u okviru ovog algoritma zadovoljava sledecudiferencnu jednacinu:
T (n) = 4T (n/2) +O(n), T (1) = 1.
Faktor 4 odgovara izracunavanju cetiri proizvoda manjih polinoma, a clan O(n) odgovara sabiranju pro-izvoda. Resenje diferencne jednacine je T (n) = O(n2) (na osnovu Master teoreme), pa ovaj algoritamnije bolji od prethodnog. Da bi se doslo do poboljsanja u odnosu na kvadratni algoritam, potrebno je,na primer, da problem resimo svodenjem na manje od cetiri potproblema.
Oznacimo proizvode P1Q1, P2Q1, P1Q2, P2Q2 redom sa A, B, C, D. Treba da izracunamo A+ (B +C)xn/2 +Dxn. Zapaza se da nisu neophodni sami proizvodi B i C, nego samo njihov zbir. Ako znamoproizvod E = (P1+P2)(Q1+Q2) = P1Q1+(P2Q1+P1Q2+P2Q2), onda je trazeni zbir B+C = E−A−D.Dakle, dovoljno je izracunati samo tri proizvoda manjih polinoma: A, D i E. Sve ostalo su sabiranjai oduzimanja polinoma, sto ionako ulazi u clan O(n) u diferencnoj jednacini. Diferencna jednacina zaslozenost poboljsanog algoritma je
T (n) = 3T (n/2) +O(n),
a njeno resenje je T (n) = O(nlog2 3) = O(n1,59).
Zapazamo da su polinomi P1 +P2 i Q1 +Q2 sa polaznim polinomima vezani na neobican nacin: dobijenisu od njih sabiranjem koeficijenata ciji indeksi se razlikuju za n = 2. Ovaj neintuitivni nacin mnozenjapolinoma znatno smanjuje broj operacija za velike vrednosti n.
31 Resavanje problema razlaganjem (divide-and-conquer): Strasenovalgoritam za mnozenje matrica
Ako su P = (pij) i Q = (qij) date kvadratne matrice reda n, onda je elemenat tij matrice R = PQ datizrazom
rij =
n∑k=1
pikqkj . (17)
Problem. Izracunati proizvod R = PQ dve realne n x n matrice.
Direktni (i na prvi pogled jedini) postupak mnozenja matrica zasniva se na definiciji (17), sto pod-razumeva n3 mnozenja i (n − 1)n2 sabiranja. Zapazimo da je n broj vrsta, odnosno kolona matrice, ane velicina ulaza, koja je u ovom slucaju n2.
36
Strasenov algoritam. Na mnozenje matrica moze se primeniti postupak dekompozicije, slicno kaona mnozenje polinoma. Zbog jednostavnosti pretpostavicemo da je n stepen dvojke. Neka je
P =
(a bc d
), Q =
(A BC D
), (18)
gde su a, b, c, d, odnosno A, B, C, D matrice reda n/2. Primenom dekompozicije se problem svodi naizracunavanje cetiri n/2 x n/2 podmatrice matrice R. Proizvod blok matrica izracunava se na isti nacinkao kad se blokovi zamene elementima, pa se problem moze shvatiti kao trazenje efikasnog nacina zaizracunavanje proizvoda dve 2 x 2 matrice. Od algoritma za mnozenje 2 x 2 matrica dobija se algoritamza mnozenje n x n matrica tako sto se umesto proizvoda elemenata umetnu rekurzivni pozivi procedureza mnozenje.Obiqan algoritam za mnozenje 2 x 2 matrica koristi 8 mnozenja. Zamenjujuci svako mnozenje rekurzivnimpozivom, dobijamo diferencnu jednacinu
T (n) = 8T (n/2) +O(n2)
(kombinovanje manjih resenja sastoji se od nekoliko sabiranja matrica reda n/2, slozenosti O(n2)), cije jeresenje T (n) = O(n log2 8) = O(n3). Ovo nije iznenadujuce, jer se koristi obican algoritam za mnozenje.Ako bismo uspeli da izracunamo proizvod 2 x 2 matrica izvodeci manje od 8 mnozenja elemenata, dobilibismo algoritam koji je asimptotski brzi od kubnog.
Faktor koji najvise utice na rekurziju je broj mnozenja potrebnih za izracunavanje proizvoda 2 x 2matrica. Broj sabiranja nije tako vazan, jer menja samo cinilac uz clan O(n2) u diferencnoj jednacini,pa ne utice na asimptotsku slozenost (on medutim utice na konstantni faktor). Strasen (Strassen) otkrioje da je dovoljno sedam mnozenja elemenata da se izracuna proizvod dve matrice reda dva. Ako matriceP,Q (18) shvatimo kao matrice reda dva, onda se njihov proizvod moze izracunati na sledeci nacin:
PQ =
(z1 + z4 z2 − z3 + z4 + z5
z1 + z3 + z6 + z7 z2 + z6
),
pri cemu su sa z1, z2, ..., z7 oznaceni sledeci proizvodi z1 = b(A + C), z2 = c(B + D), z3 = (c − b)(A +D), z4 = (a− b)A, z5 = (a− c)(B −A), z6 = (d− c)D i z7 = (d− b)(C −D).
Slozenost. U algoritmu se izracunava sedam proizvoda matrica dva puta manje dimenzije i konstantnibroj sabiranja takvih matrica. Sabiranja su manje vazna od proizvoda, jer se dve matrice reda n sabirajuza vreme O(n2), sto je linearna funkcija od velicine ulaza. Clan O(n2) nije dominantan u diferencnojjednacini
T (n) = 7T (n = 2) +O(n2).
Resenje ove diferencne jednacine je T (n) = O(nlog2 7), odnosno priblizno O(n2,81), sto znaci da jeStrasenov algoritam asimptotski brzi od obicnog mnozenja matrica.
Komentar. Strasenov algoritam ima tri vazna nedostatka:
1. Prakticne provere pokazuju da n mora biti vece od 100 da bi Strasenov algoritam bio brzi odobicnog mnozenja matrica slozenosti O(n3).
2. Strasenov algoritam manje je stabilan od obicnog. Za iste velicine greske ulaznih podataka,Strasenov algoritam obicno dovodi do vecih gresaka u izlaznim podacima.
3. Strasenov algoritam je komplikovaniji i tezi za realizaciju od obicnog. Pored toga, njega nije lakoparalelizovati.
37
32 Resavanje problema razlaganjem (divide-and-conquer): nalazenjedve najblize tacke u ravni
Umesto da razmatramo tacke jednu po jednu, mozemo da skup tacaka podelimo na dva jednaka dela.Induktivna hipoteza je takva da problem svodimo na dva problema sa n/2 tacaka. Zbog jednostavnostipretpostavimo da je n stepen dvojke, tako da je skup uvek moguce podeliti na dva jednaka dela.Postoji vise nacina da se skup podeli na dva jednaka dela. Biramo nacin koji najvise odgovara nasimciljevima. Voleli bismo da dobijemo sto vise korisnih informacija iz resea manjih problema, odnosno dasto veci deo tih informacija vazi i za kompletan problem. Izgleda razumno da se skup podeli na dva delapodelom ravni na dva disjunktna dela, tako da svaki od njih sadrzi polovinu tacaka.Posto se pronade najmanje rastojanje u svakom delu, treba razmotriti samo rastojanja izmedu tacaka bli-skih granici skupova. Najjednostavniji nacin podele je sortirati tacke prema (na primer) x-koordinatamai podeliti ravan pravom paralelnom sa y-osom, koja deli skup na dva jednaka dela, videti sliku 12 (ako visetacaka lezi na pravoj podele, tacke se mogu na proizvoljan nacin razdeliti izmedu skupova). Nacin podeleizabran je tako da se maksimalno pojednostavi objedinjavanje resenja manjih problema. Sortiranje trebaizvrsiti samo jednom.
Slika 12: Problem nalazenja dve najblize tacke.
Zbog jednostavnosti ogranicicemo se na nalazenje vrednosti najmanjeg rastojanja izmedu tacaka (a ne ipara tacaka za koje se ono dostize). Pronalazenje dve najblize tacke izvodi se na sledeci nacin.Neka je P skup tacaka i neka je n stepen dvojke. Najpre se skup P deli na dva istobrojna podskupaP1 i P2 na opisani nacin. Najmanje rastojanje u svakom podskupu pronalazi se na osnovu induktivnehipoteze. Neka je d1 minimalno rastojanje u P1, a d2 minimalno rastojanje u P2. Bez smanjenja opstostimoze se pretpostaviti da je d1 ≤ d2. Potrebno je pronaci najmanje rastojanje u celom skupu, odnosnoustanoviti da li u P1 postoji tacka na rastojanju manjem od d1 od neke tacke u P2.Primetimo najpre da je dovoljno razmatrati tacke u traci sirine 2d1, simetricnoj u odnosu na pravupodele (videti sliku 12). Ostale tacke ne mogu biti na rastojanju manjem od d1 od neke tacke iz drugogpodskupa. Na osnovu ovog zapazanja obicno se iz razmatranja eliminise veliki broj tacaka. Medutim,u najgorem slucaju sve tacke mogu biti u traci, pa ne mozemo da sebi priustimo primenu trivijalnogalgoritma na njih.
Drugo manje ocigledno zapazanje je da za proizvoljnu tacku p u traci postoji samo mali broj tacakau suprotnoj traci cije rastojanje od p moze biti manje od d1. Iskoristicemo cinjenicu da je
√2/2 > 0, 7.
Neka je sa yp oznacena y-koordinata tacke p. Konstruisimo pravougaonik visine 2, 1d1 <32
√2d1 i sirine
1, 4d1 <√
2d1 u suprotnoj traci (videti sliku 13), tako da naloze na pravu podele i da mu je y-koordinatapreseka dijagonala jednaka yp. Podelimo ga jednom vertikalnom pravom i sa dve horizontalne prave nasest jednakih kvadrata stranice 0, 7d1 (kojima je dijagonala manja od d1!!! ). U svakom od malih kvadrata
38
moze se naci najvise jedna tacka, jer je rastojanje bilo koje dve tacke u kvadratu manje od d1. Sve tackeu drugom podskupu, sa rastojanjem od p manjim od d1, ocigledno se moraju nalaziti u pravougaoniku.Dakle, u drugom podskupu se moze nalaziti najvise sest tacaka na rastojanju od p manjem od d1: tackakandidat sa y-koordinatom yq mora da zadovolji i uslov |yp − yq| < d1, pa se mora nalaziti u jednomod 6 kvadrata. Prema tome, ako sve tacke u traci sortiramo prema y-koordinatama i pregledamo ih timredom, dovoljno je da za svaku tacku proverimo rastojanje osam suseda u suprotnoj traci, cetiri ispod icetiri iznad (a ne od svih n− 1 tacaka u najgorem slucaju).
Slika 13: Ocena maksimalnog broja tacaka iz suprotnog podskupa, bliskih fiksiranoj tacki.
Slozenost. Sortiranje slozenosti O(n log n) izvrsava se samo jednom. Zatim se resavaju dva potproblemavelicine n/2. Eliminacija tacaka van centralne trake moze se izvesti za O(n) koraka. Za sortiranje tacakau traci po y-koordinatama u najgorem sluqaju potrebno je O(n log n) koraka. Konacno, potrebno jeO(n) koraka da se pregledaju tacke u traci, i da se provere rastojanja svake od njih od konstantnog brojasuseda u sortiranom redosledu.Ukupno, da bi se resio problem velicine n, treba resiti dva potproblema velicine n/2 i izvrsiti O(n log n)koraka za kombinovanje njihovih resenja (plus O(n log n) koraka za jednokratno sortiranje tacaka pox-koordinatama na pocetku).Dobijamo diferencnu jednacinu
T (n) < 2T (n/2) + cn log2 n, T (2) = 1,
pri cemu u T(n) nije ukljuceno pocetno sortiranje po x-koordinatama. Indukcijom se pokazuje da jenjeno resenje T (n) = O(n log2 n). Ovo je bolje od kvadratne slozenosti, ali se moze poboljsati.
Algoritam slozenosti O(n log n). Osnovna ideja je pojacati induktivnu hipotezu. U toku objedinja-vanja resenja potproblema izvodi se O(n log n) koraka zbog sortiranja tacaka po y-koordinatama. Mozeli se sortiranje izvesti usput u toku nalazenja dveju najblizih tacaka? Drugim reqima, cilj je pojacatiinduktivnu hipotezu za problem dve najblize tacke tako da obuhvati i sortiranje.
Pojacana induktivna hipoteza. Za zadati skup od < n tacaka u ravni umemo da pronademo najma-nje rastojanje i da skup tacaka sortiramo po y-koordinatama.
Vec smo videli kako se moze pronaci minimalno rastojanje ako se tacke u svakom koraku sortiraju poy-koordinatama. Dakle, potrebno je jos samo prosiriti induktivnu hipotezu tako da obuhvati sortiranjen tacaka kad su dva podskupa velicine n/2 vec sortirana. Medutim, to je upravo sortiranje objedinja-vanjem. Osnovna prednost ovog pristupa je u tome sto se pri objedinjavanju re senja ne mora izvesti
39
kompletno sortiranje, nego samo objedinjavanje dva vec sortirana podniza. Posto se objedinjavanje sor-tiranih podnizova izvodi za O(n) koraka, diferencna jednacina za slozenost (bez pocetnog sortiranja pox-koordinatama) postaje
T (n) < 2T (n/2) + cn, T (2) = 1.
Njeno resenje je T (n) = O(n log n), sto je asimptotski jednako slozenosti pocetnog sortiranja tacaka pox-koordinatama.
Algoritam Najblizi_par(p1, p2, ..., pn); Poboljsana verzija
Ulaz: p1, p2, ..., pn (skup tacaka u ravni);
Izlaz: d (rastojanje izmedu dve najblize tacke skupa);
begin
Sortirati tacke prema x-koordinatama;
ovo sortiranje izvrsava se samo jednom, na pocetku
Podeliti skup na dva istobrojna podskupa;
Rekurzivno izvrsiti sledece:
izracunati minimalno rastojanje u oba podskupa;
sortirati tacke u svakom delu prema y-koordinatama;
Objediniti dva sortirana niza u jedan;
Objedinjavanje se mora izvrsiti pre eliminacije:
sledecem nivou rekurzije mora se isporuciti sortiran kompletan skup
Neka je d manje od dva minimalna rastojanja;
Eliminisati tacke koje su na rastojanju vecem od d od prave podele;
Za preostale tacke proveriti njihova rastojanja od 4 prethodne i 4 naredne taqke iz
suprotne trake;
dovoljno je proveriti i samo 4 prethodne tacke!
if neko od ovih rastojaa je manje od d then
popraviti d;
end
33 Pretraga (backtracking): problem 8 dama
Problem. Treba postaviti 8 dama na sahovsku tablu dimenzija 8 x 8, ali tako da nikoje dve dame nenapadaju jedna drugu. Ovaj problem se moze uopstiti na n dama i sahovsku tablu dimenzija n x n.Izlaz treba da predstavlja niz x1, x2, ..., xn, gde je xi broj kolone gde se smesta dama u i-toj vrsti. Naslici 14 je prikazano jedno resenje ovog problema.
••
••
••
••
Slika 14: Resenje problema 8 dama. Trazeni niz je (4, 6, 8, 2, 7, 1, 3, 5).
Prikazacemo ideju resenja za tablu 4 x 4 (n = 4):
40
• x x xx xx xx x
x • x xx x x
x xx
↓• x x xx x • xx x x xx x x
• x x xx x x •x x xx x x
x • x xx x x •
x x xx x
↓ ↓ ↓• x x xx x x •x • x xx x x x
x • x xx x x •• x x xx x x
↓ ↓•
••
•
Prikazana su resenja za samo prve dve kolone u prvoj vrsti jer su za trecu i cetvrtu kolonu resenjasimetricna drugoj i prvoj, redom. Resenje je da probamo da stavimo damu na svako mesto u i-toj vrsti,pa da ispitujemo da li postoji mesto za narednu damu u i+ 1-oj vrsti. Do odsecanja dolazi onda kada ui+ 1-oj vrsti ne mozemo da stavimo damu ni na jedno mesto. Sa ,,x” su oznacena mesta koja ne mogubiti upotrebljena za smestanje dama.
Dame(Matrica, n)
begin
Pocni u najlevljoj koloni;
if sve dame su postavljene then
return true;
for svi redovi u tekucoj koloni do
if dama moze da se smesti ispravno u ovom redu then
obelezi ovaj (red, kolona) kao deo resenja;
rekurzivno pozovi algoritam Dame za naredno ispitivanje;
if stavljanje dame u (red, kolonu) dovodi do resenja then
return true;
if stavljanje dame ne dovodi do resenja then
eliminisi ovaj (red, kolona) iz pretrage (Backtrack);
continue;
Ako smo ovde dosli, onda nema resenja za ovaj red.
if svi redovi su probani i nema resenja
return false; Ovo ce pokrenuti dalju pretragu (Backtrack).
end
34 Pretraga (backtracking): trazenje podskupa brojeva sa za-datim zbirom
Problem. Neka je zadat skup brojeva w1, w2, ..., wn i zbir W . Potrebno je naci podskup datogskupa ciji je zbir jednak datom zbiru W , odnosno, pronaci i1 < i2 < ... < ik, k ≤ n tako da je
41
wi1 + wi2 + ...+ wik = W , ukoliko takav podskup postoji.
Izlaz ce biti predstavljen nizom x1, x2, ..., xn, gde je xi =
0, ako wi ne ulazi u zbir1, ako wi ulazi u zbir
.
Primer: Ukoliko je n = 4, 2, 4, 6, 9 i W = 15, onda su moguca resenja 15 = 6 + 9 i 15 = 2 + 4 + 9, stose predstavlja kao x′ = (0, 0, 1, 1) i x′′ = (1, 1, 0, 1), x′ i x′′ su dva niza resenja.
Ovde se takode razvija stablo varijanti, kao kod prethodnog problema (8 dama). Probamo da uba-cimo i-ti elemenat skupa u tekucu sumu i rekurzivno pozovemo pretragu nadalje. Ukoliko se dode dolista stabla varijanti, a tekuca suma nije jednaka tazenoj sumi, onda se izbacuje poslednji unet elemenatiz tekuce sume i algoritam nastavlja sa pretragom. Ukoliko se u bilo kom trenutku dobije da je tekucasuma jednaka trazenoj sumi, ispisuje se niz x i prekida se program (ukoliko se trazi samo jedno resenje,a u protivnom se dalje nastavlja sa pretragom).
35 Pretraga (backtracking): 3-bojenje
Preporucuje se ucenje kodova.
Oznacimo tri boje sa C(rveno), P(lavo) i Z(eleno). Na pocetku se mogu izabrati neka dva susedna cvorav i w, i obojiti recimo sa P i Z. Posto se oni ionako moraju obojiti razlicitim bojama, nije bitno koje ceboje biti izabrane (konacno bojenje se uvek moze ispermutovati), pa se zato moze zapoceti sa bojenjemdva umesto jednog cvora. Ako je u prvi izabrani cvor (posle v i w), a u je susedan cvoru w (koji je vecobojen bojom Z), onda postoje dve mogunosti za bojenje u, P i C, bira se jedna od ove dve boje i processe nastavlja.Kad se jedan cvor oboji, smanjuje se broj mogucnosti za bojenje ostalih cvorova. U slucaju da su obojenisvi cvorovi grafa, problem je resen. Verovatnije je, medutim, da cemo naici na cvor koji se ne moze obojiti(jer ima tri susedna cvora koji su vec obojeni razliqitim bojama). U tom trenutku cinimo korak nazad.Primer grafa, koje odgovara resavanju problema 3-bojenje na njemu, prikazan je na slici 15. Primetimoda u ovom slucaju, kad se fiksiraju boje cvorova 1 i 2, za bojenje ostalih cvorova postoji samo jedannacin.
Slika 15: Primer primene pretrage na 3-bojenje grafa.
Algoritam 3-bojenje(G, U);
Ulaz: G = (V,E) (neusmereni graf) i U (skup vec obojenih cvorova);
U je obicno na pocetku prazan skup
Izlaz: Pridruzivanje jedne od tri boja svakom cvoru G;
begin
if U = V then
print "bojenje je zavrseno";
42
halt;
prekid svih rekurzivnih poziva
else
izabrati neki cvor v koji nije u skupu U;
for C := 1 to 3 do
if ni jedan sused v nije obojen bojom C then
dodaj cvor v obojen bojom C skupu U;
3-bojenje(G, U);
end
36 Ogranicavajuce funkcije za pretragu: bojenje grafa minimal-nim brojem boja
Grananje sa odsecanjem je varijacija pretrage, koja se moze primeniti ako se trazi minimum (ili maksi-mum) neke ciljne funkcije. Posmatrajmo opsti problem bojenja grafa: cilj je pronaci najmanji broj bojapotreban za bojenje zadatog grafa, a ne samo ustanoviti da li je graf moguce obojiti sa tri boje.
Moze se formirati stablo slicno kao za 3-bojenje, ali broj sinova svakog cvora moze da bude vrlo ve-liki. Svaki novi cvor moze se obojiti nekom od vec koriscenih boja (sem ako je neki od njegovih susedavec obojen tom bojom), ili novom bojom. Prema tome, algoritam za 3-bojenje menja se na dva mesta:(1) konstanta 3 zamenjuje se brojem do sada koriscenih boja, i(2) algoritam se ne zavrsava u trenutku kad je V = U , jer je moguce da postoji bolji nacin da se oboji graf.
Poteskoce izaziva cinjenica da u algoritmu dolazi do vracanja unazad samo kad se dode do lista u stablu(odnosno kad je V = U), jer se nova boja uvek moze dodeliti cvoru. Prema tome, skoro je sigurno da ceovakav algoritam biti vrlo neefikasan (sem ako je graf vrlo gust).
Efikasnost algoritma moze se poboljsati pomocu sledeceg zapazanja, koje je u osnovi metoda grana-nja sa odsecanjem. Pretpostavimo da smo prosli deo stabla do nekog lista i tako pronav sli ispravnobojenje sa k boja. Pretpostavimo dalje da smo posle vracanja unazad krenuli drugim putem, i tako doslido cvora koji zahteva uvodenje (k+ 1)-e boje. U tom trenutku moze se napraviti korak nazad, jer je vecpoznato bolje resenje. Prema tome, k sluzi kao granica za pretragu.
U svakom temenu stabla izracunavamo donju granicu za najbolje resenje na koje se moze naici medusledbenicima tog temena. Ako je ta donja granica veca od nekog vec nadenog resenja, cinimo koraknazad.
37 Ogranicavajuce funkcije za pretragu: trazenje podskupa sazadatom sumom, koriscenje razlomljenog problema ranca
Resenje je prevedeno sa http://poincare.matf.bg.ac.rs/~ezivkovm/nastava/backtrack.ps. Pre-poruka: Najbolje je nauciti ovo pitanje preko primera datog ispod objasnjenja.
Ovaj problem ima identicnu formulaciju razlomljenog problema ranca sa tom razlikom da sada nijemoguce rezati predmet.
Neka je CurW =l−1∑i=1
wixi ≤ M , za svako parcijalno resenje X = (x1, x2, ..., xl−1). Neka je profit(x)
vrednost za bilo koje resenje X i neka je za to resenje P (X) maksimalna vrednost resenja koje se dobijakad se ude dublje u stablo. Drugim recima, P (X) je maksimalna vrednost od profit(X ′) za sva mogucaresenja X ′ = (x1, x2, ..., xn).
Generalno, P (X) moze da se racuna prolaskom kroz podstablo sa koren u X. Da bismo ovo izbegli,ako je to moguce, uvescemo granicnu funkciju B, definisanu na skupu cvorova u stablu odlucivanja, koja
43
zadovoljava sledecu osobinu: ,,Za svako parcijalno resenje X, B(X) ≥ P (X)”. B zapravo predstavljamaksimalnu vrednost ranca koja se dobija kada se primeni algoritam za razlomljeni problem ranca.
Dalje, neka je OptP trenutna optimalna vrednost ranca. Kada je B(X) ≤ OptP , onda je P (X) ≤B(X) ≤ OptB. Ovo implicira da nema resenja u daljoj pretrazi kroz drvo koje moze da poboljsatrenutno optimalno resenje.
0-1_ranac(l, CurW);
begin
if l = n + 1 then
if suma pi*xi u granicama od 1 do n > OptP then
OptP = suma pi*xi u granicama od 1 do n;
OptX = (x1, x_2, ..., x_n);
else
B = suma pi*xi u granicama od 1 do l-1 + Razlomljeni(n+l-1, p, w, M - CurW);
Razlomljeni() je algoritam za resenje razlomljenog problema ranca.
if B <= OptP then
return;
if CurW + wl <= M then
xl = 1;
0-1_ranac(l+1, CurW + wl);
if B <= OptP then
return;
xl = 0;
0-1_ranac(l+1, CurW);
end
Primer: Neka imamo pet stvari zadate tezinama 11, 12, 8, 7 i 9, i vrednostima 23, 24, 15, 13 i 16redom, i kapacitet ranca M = 26. Primetimo da su stvari vec poredane opadajuce po vrednosti podjedinici tezine. Crtamo stablo koje odgovara rekurzivnim pozivima algoritma prikazano na slici 16, gdeu svakom cvoru racunamo trenutnu vrednost od X, B(X) i CurW . Na pocetku: niz X je prazan,B = 11 + 12 + 3
8 · 8 = 52, 625 i CurW = 0.
Slika 16: Stablo odlucivanja razapeto algoritmom 0-1 ranac.
44
38 Trazenje uzorka u tekstu – naivni algoritam, algoritam KMP
Preporucuje se ucenje kodova.
Neka su S = s1s2...sn i P = p1p2...pm dva stringa (niza znakova iz konacnog alfabeta). Za prvi od njihreci cemo da je tekst, a za drugi da je uzorak. Podstring stringa S je string sisi+1...sj od uzastopnihznakova S.
Problem. Za dati tekst S = s1s2...sn i uzorak P = p1p2...pm ustanoviti da li postoji podstring Sjednak P , a ako postoji, pronaci prvu pojavu uzorka u tekstu, odnosno najmanji indeks k takav da jesk+i−1 = pi za i = 1, 2, ...,m.
Naivni algoritam. Na prvi pogled problem izgleda jednostavno. Dovoljno je uporediti uzorak Psa svim mogucim podstringovima S oblika sksk+1...sk+m−1 duzine m, pri cemu k uzima vrednosti redom1, 2, ..., n − m + 1. Uporedivanje uzorka sa podstringom vrsi se znak po znak sleva udesno, sve dokse ne ustanovi da su svi znaci uzorka jednaki odgovarajucim znacima podstringa (u tom trenutku pre-kida se dalje pregledanje podstringova), ili dok se ne naide na neslaganje pi 6= sk+i−1 za neko i, 1 ≤ i ≤ m.
Sloenost. Broj uporedivanja znakova manji je od mn, pa je slozenost ovog algoritma O(mn) u najgoremslucaju.
Algoritam Nadji_uzorak(S, n, P, m);
Ulaz: S (string duzine n) i P (uzorak duzine m).
Izlaz: Start (indeks pocetka prvog podstringa S jednakog P, ako takav postoji,
odnosno 0 u protivnom).
begin
Start = 0;
i = 1; pokazivac na uzorak
j = 1; pokazivac na string
while i <= m and j <= n do dok ima nade da se nade podstring jednak uzorku
if P[i] = S[j] then
i = i + 1; j = j + 1 poklapanje: napredovanje i u stringu i u uzorku
else
j = j - i + 2; i = 1 neslaganje: uzorak klizi za jedno mesto udesno
if i > m then
Start = j - i + 1 pronaden je podstring jednak uzorku
end
KMP algoritam. Pretpostavimo da je do neslaganja doslo na poziciji i u uzorku, tj. za neki indeksj u tekstu je pi 6= sj i p1p2...pi−1 = sj−i+1sj−i+2...sj−1. Postavlja se pitanje: koliko uzorak najmanjetreba pomeriti udesno, odnosno koji znak pl uzorka treba postaviti ispod znaka sj teksta, tako da se(manji) deo uzorka p1p2...pl−1, l < i, i dalje slaze sa delom teksta sj−l+1sj−l+2...sj−1, i da pri tome budepl 6= pi?
Slika 17: Ilustracija ideje na kojoj se zasniva algoritam KMP.
Pretpostavimo da imamo tabelu pomeraja h, za koju vazi da ako do neslaganja dode na mestu l, onda
45
treba zameniti l sa h[i] (postoji algoritam za nalazenje ove tabele). Tada ce algoritam poznat podimenom KMP (Knutt−Morris− Pratt) izgledati:
Algoritam KMP(S, n, P, m);
Ulaz: S (tekst - string duzine n) i P (uzorak duzine m).
Pretpostavlja se da je niz h izracunat
Izlaz: Start (indeks pocetka prvog podstringa S jednakog P, ako takav postoji,
odnosno 0 u protivnom).
begin
Start = 0;
i = 1; pokazivac na uzorak
j = 1; pokazivac na tekst
while i <= m and j <= n do dok ima nade da se nade podstring jednak uzorku
while i > 0 cand P[i] != S[j] do
i = h[i]; pomeranje uzorka udesno za i - h[i]
i = i + 1; j = j + 1; napredovanje u tekstu i u uzorku
if i > m then
Start = j - i + 1 pronaden je podstring jednak uzorku
end
Slozenost. Broj izvrsavanja i = h[i]; manji je od i = i + 1;, pa se i = h[i]; izvrsava manje odn puta (jer se i = i + 1; izvrsava kao i j = j + 1;, odnosno n puta). Dakle, slozenost je O(n) (nezavisi od duzine uzorka).
39 Trazenje uzorka u tekstu – izracunavanje pomocnog niza zaalgoritam KMP
Preporucuje se ucenje kodova.
Razmotrimo sada kako se efektivno mogu izracunati elementi vektora h. Kao sto je receno, ako je pi 6= sj, onda je l = h[i] indeks znaka uzorka koga sledeceg treba uporediti sa znakom teksta sj . Drugim recima,l je najveci indeks za koji je p1p2...pl−1 = pi−l+1p + i− l + 2pi−1 i pl 6= pi. Uz uslov h[1] = 0 ovim suodredeni svi clanovi vektora h.
Slika 18: Ilustracija ideje na kojoj se zasniva algoritam za trazenje tabele h.
Ukoliko je A najduzi prefiks p1p2...pk jednak sufiksu pupu+1...pi−1, onda ce h[i] biti jednak duzini togprefiksa + 1, odnosno h[i] = |A| + 1. Ukoliko imamo izracunat h[i], i vazi jednakost j = |A| + 1, tadacemo h[i+ 1] potraziti na sledeci nacin:
• Ako je pi = pj , onda je h[i+ 1] = j + 1
• Ako je pi 6= pj , onda je j = h[j] i vracamo se nazad.
Algoritam Pomaci(P, m);
Ulaz: P (uzorak, string duzine m);
Izlaz: h (niz duzine m);
46
begin
i = 1; indeks elementa h koji se izracunava
j = 0; pokazivac na smaknuti uzorak; uskakae u petlju
h[1] = 0; g[1] = 0; neslagae na prvom znaku u KMP: pomeranje udesno
while i < m do
na ovom mestu je P[i - j + k] = P[k] za k = 1, 2, ..., j - 1] invarijanta petlje
while j > 0 cand P[i] != P[j] do
j = h[j]; smanjivanje indeksa j; moze i j = g[j];, ali je ovako bolje!
i = i + 1; j = j + 1; paralelno napredovanje pokazivaca
g[i] = j;
neka je s simbol u tekstu, sa kojim se P[i] uporeduje u algoritmu KMP
if P[i] = P[j] then
h[i] = h[j] ako P[i] != s, onda je i P[j] != s; udesno na h[j]
else
h[i] = j ako P[i] != s, onda proveriti da li je P[j] != s; udesno na j
end
40 Numericki algoritmi: izracunavanje vrednosti polinoma (Hor-nerova sema)
Problem. Dati su realni brojevi an, an−1, ..., a1, a0 i realni broj x. Izracunati vrednost polinoma
Pn(x) =n∑
i=0
aixi.
Induktivna hipoteza. Umemo da izracunamo vrednost polinoma P ′n−1(x) sa koeficijentima an, an−1, ..., a1u tacki x.
Ovakva induktivna hipoteza je pogodna jer se lako prosiruje. Posto je Pn(x) = x · P ′n−1(x) + a0, zaizracunavanje Pn(x) polazeci od P ′n−1(x) dovoljno je jedno mnozenje i jedno sabiranje. Izracunavanje semoze opisati sledecim izrazom:
anxn + an−1x
n−1 + ...+ a1x+ a0 = ((...((anx+ an−1)x+ an−2)...)x+ a1)x+ a0,
poznatim kao Hornerova sema.
Algoritam Vrednost_polinoma(a, x);
Ulaz: a (niz koeficijenata polinoma) i x (realni broj);
Izlaz: P (vrednost polinoma u tacki x);
begin
P = a[n];
for i = 1 to n do
P = x * P + a[n-i];
end
41 Numericki algoritmi: Lagranzov interpolacioni polinom
Preporucuje se ucenje kodova.
Problem. Date su vrednosti polinoma Pn(x) : P (x0) = y0, P (x1) = y1, ..., P (xn) = yn, gde su svaki odx1, x2, ..., xn medusobno razliciti. Tacke su oblika (xi, yi), i = 1, 2, ..., n. Izracunati koeficijente polinomaPn(x).
Napravicemo izraz
K = (x− x0) · (x− x1) · ... · (x− xi−1) · (x− xi+1) · ... · (x− xn). (19)
47
Primetimo da smo ispustili (x− xi) clan. Zamenjivanjem xi umesto x u izrazu (19), napravicemo izraz
K ′ = (xi − x0) · (xi − x1) · ... · (xi − xi−1) · (xi − xi+1) · ... · (xi − xn). (20)
Posmatrajmo kolicnik K/K’:
K
K ′=
1, ako je x = xi0, ako je x = xj , j 6= i
. (21)
Ukoliko pomnozimo (21) sa yi, dobijamo
yi ·K
K ′=
yi, ako je x = xi0, ako je x = xj , j 6= i
, (22)
odakle se dobija da je Pn(x) =n∑
i=0
yi ·K
K ′trazeni polinom koji je jednoznacno odreden. Taj polinom se
naziva Lagranzov interpolacioni polinom.
Slika 19: Primeri Lagranzovih interpolacionih polinoma.
42 Numericki algoritmi: priblizno resavanje jednacina (polo-vljenje intervala, metod secice, metod tangente)
Problem. Date su dve neprekidne i diferencijabilne funkcije g(x) i h(x). Potrebno je resiti jednacinug(x) = h(x) u granicama zadate tacnosti.
Neka je f(x) = g(x) − h(x). Sada se problem g(x) = h(x) svodi na trazenje nule funkcije f(x) ugranicama zadate tacnosti. Postoje tri metoda: metod polovljenja intervala, metod secice i metod tan-gente.
Metod polovljenja intervala (bisekcija). Neka je funkcija f neprekidna na intervalu [a, b] i vazif(a)f(b) < 0. Za nju je onda poznato da postoji tacka x1 ∈ [a, b] za koju vazi f(c) = 0. Izracunava sevrednost funkcije u tacki x1 = (a+b)/2. Ako je f(x1) = 0 (u granicama zadate tacnosti), onda je resenjepronadeno. U protivnom, funkcija u krajevima jednog od podintervala [a, x1] ili [x1, b] ima vrednostisuprotnog znaka, pa u tom podintervalu postoji bar jedno resenje jednacine. Posle k koraka dolazi sedo intervala duzine (b − a)/2k koji sadrzi resenje. Sa polovljenjem intervala nastavlja se do postizanjazahtevane tacnosti.
Metod secice. Vazi da je f(a)f(b) < 0. Ideja metoda secice jeste da na osnovu dve prethodne
48
tacke formiramo trecu tacku koja ce u kombinaciji sa prethodnom dati blize resenje nego primenomprethodnog metoda. Jednacina secice data sa
y − f(a)
x− a=f(b)− f(a)
b− a,
odakle sledi
y = f(a) +x− ab− a
(f(b)− f(a)). (23)
Zamenom y = 0 u (23), dobija se trazena tacka
x = a− (b− a)f(a)
f(b)− f(a).
Metod tangente. Metod tangente daje najblizu vrednost tacke blizu trazenog resenja. Ideja se zasnivana tome da za proizvoljnu tacku (x1, y1) trazimo tangentu u odnosu na funkciju f . X-koordinata sledecetacke se formira tako sto nademo presek tangente i x-ose. Nakon toga za tu tacku trazimo (x2, f(x2))pa postupak ponavljamo dok ne aproksimiramo koren funkcije do zeljene velicine. Jednacina tangentedata je sa
y − f(a)
x− a= f ′(a),
odakle sledi
y = f(a) + f ′(a)(x− a). (24)
Zamenjivanjem y = 0 u (24), dobija se trazena tacka
x = a− f(a)
f ′(a).
43 Svodenje rekurzije na iteraciju – repna rekuzija, n!, Fibonacijevniz
Preporucuje se ucenje kodova.
U matematici i racunarstvu, rekurzija je pristup u kojem se neki pojam, objekat ili funkcija definise naosnovu jednog ili vise baznih slucajeva i na osnovu pravila koja slozene slucajeve svode na jednostavnije.Primeri ovakvih objekata su prirodni brojevi, binarna stabla, faktorijel itd. Za njih je karakteristicno toda se algoritmi lako implementiraju preko rekurzije.
Svaku rekurzivnu funkciju je moguce implementirati na drugi nacin tako da ne koristi rekurziju. Nepostoji jednostavan opsti postupak za generisanje takvih alternativnih implementacija. Medutim, takavpostupak postoji za neke specijalne slucajeve. Narocito je zanimljiv slucaj repne rekurzije jer se u tomslucaju rekurzija moze jednostavno eliminisati4. Rekurzivni poziv je repno rekurzivni ukoliko je vrednostrekurzivnog poziva upravo i konacan rezultat funkcije, tj. nakon rekurzivnog poziva funkcije ne izvrsavase nikakva dodatna naredba.
Primer: Repno rekurzivni kod na levoj strani se lako eliminise kodom na desnoj strani:
x = x0;
P() P()
begin begin
if B then x = x0;
S; while B do
P(); S;
end
49
Pogledajmo jos neke primere:
Primer 1: Faktorijel broj n. Faktorijel broja n se rekurzivno definise kao
n! =
1, ako je n = 0n(n− 1)!, ako je n > 0
.
Pogledajmo repno rekurzivan kod (levo) i iterativni kod (desno) za faktorijel broja n:
F(i, n) F(n)
begin begin
if i = 0 then i = 0; f = 1;
return; while i < n do
else i = i + 1;
return F(i-1, n*i); f = f * i;
end return f;
end
Poziv za rekurzivnu funkciju je F(broj, 1);. Dokaz ispravnosti se izvodi invarijantom petlje f =
(i+1)!, gde je i vrednost pri ulasku u petlju.
Primer 2: Fibonacijev niz. Fibonacijev niz je rekurzivno definisan rekurentnom relacijom
F (n+ 2) = F (n+ 1) + F (n), F (0) = 1, F (1) = 1.
Prirodno se namece rekurzivan algoritam koji trazi n-ti clan Fibonacijevog niza:
Fib(n)
begin
if n <= 2 then
return 1;
else
return Fib(n-2) + Fib(n+1);
end
Medutim, osim sto ovaj algoritam cak nije ni repno rekurzivan (lako se moze napraviti repno rekurzivnaverzija), slozenost ovog algoritma je eksponencijalna (pogledati profesorovu knjigu, oblast 2.5.2, primer2.7), pa je zbog toga veoma neefikasan. Uklanjanje rekurzije moze se izvrsiti na sledeci nacin:
Fib(n) poboljsana verzija
begin
if n <= 2 then
return 1;
else
x = 1; y = 1;
for i = 3 to n do
z = x + y;
x = y;
end
50