45
Algoritmi i strukture podataka Ilija Lalovic

Algoritmi Skripta

Embed Size (px)

Citation preview

Page 1: Algoritmi Skripta

Algoritmi i strukture podataka

Ilija Lalovic

Page 2: Algoritmi Skripta

0.1 Asimptotske oznake

O - notacija je korisna za analizu programa, posto obuhvata asimptotski rast funkcija i ignorise konstantne mnozitelje.Konstantni mnozitelji su ionako van nase kontrole kada prevedemo algoritme u programe. Mi koristimo sledecedefinicije, mada postoje i alternativne:

Neka f,g: N → N :• g(n) = O(f(n)) akko (∃K ∈ R), tako da za dovoljno veliko n0 za svako n > n0 imamo g(n) 6 K · f(n)

Primer 0.1. 1. (1000n2 + 100n+ 1000) = O(n3)

2. n2 = O(n3 − 100n2 − 2n)

3. ni = O(poly(n)), gde je deg(p)≥ i , a vodeci koeficijent p(n) je pozitivan.•f(n) = (g(n)) akko g(n) = O(f(n))

•g(n) = θ(f(n)) akko (g(n)=O(f(n)) i f(n)=O(g(n))

Primer 0.2. Razmotriti sledece funkcije:√n, n, 2n, nlogn, n− n3 + 7n5, n2 + logn, n2, n3, logn, n1/3 + logn, (logn)2, n!, lnn, n

logn , loglogn, (1/3)n, (3/2)n, 6.

Grupisati ove funckije tako da su f(n) i g(n) u istoj grupi akko g(n) =O(f(n)) i ispitati grupe u rastucem poretku.

0.2 Primer programa koji ispisuje sopstveni kod

U inzinjerstvu samorepliciranje bi moglo omoguciti snizenje cena proizvodnje. Sledeci C++ program replicira samogsebe:

\# inc lude <i o s t ream . h>main ( ){

char ∗ s= ”\# inc lude <i o s t ream . h> \%cmain ( )

{char ∗ s=\%c\%s\%c ;count . form ( s , 10 , 34 , s , 3 4 , 1 0 ) ; }\%c ” ;count . form ( s , 10 , 34 , s , 3 4 , 1 0 ) ; }

Autor je [email protected] C program velicine 800bitova, objavljen u casopisu Byte, Avgust 1980.g. – 74.strana, takodje replicira samogsebe.

main ( ){

char q=34, n=10,∗a=”main ( ) { char q=34, n=10, ∗a= \%c\%s\%c ;p r i n t f ( a , q , a , q , n ) ; } \%c ” ;p r i n t f ( a , q , a , q , n ) ; }

Neki drugi samoreplicirajuci mehanizmi su puno slozeniji. Za poredjenje, Morisov internet crv ima oko 500 000bitova, bakterija Esherichia coli ima 8 000 000 bitova, Drekslerov assembler ima 100 000 000 bitova, a covek oko 64000 000 000 bitova.Gornji primeri samoreproducirajucih programa daju nadu da ce u buducnosti biti moguce napraviti jednostavnesamoreproducirajuce masine koje ce pomagati u procesu proizvodnje u nanotehnologijama. Za vise detalja i referencevd. N.Mitic, Osnovi racunarskih sistema, CET, Beograd 2003.

0.3 Hijerarhije slozenosti algoritama

Vremenska slozenost(kompleksnost) algoritma se odredjuje kao asimptotska slozenost funkcije koja predstavlja “brojkoraka” (jedinica vremena) algoritma u odnosu na duzinu ulaza(ne u odnosu na partikularni ulaz). Prostotna slozenostalgoritma odredjuje se kao asimptotska slozenost funkcije koja predstavlja prostorne resurse(memoriju) potrebnu al-goritmu u odnosu na duzinu ulaza. Razlikujemo worst case, best case i awerage case slozenosti algoritma. Algoritmi

Page 3: Algoritmi Skripta

mogu biti polinomijalni, nepolinomijalni, potpuno eksponencijalni i subeksponencijalni.Izvodljivi( eng. Feasible) algoritmi imaju polinomijalnu slozenost.

Ovde ne razmatramo artimeticke i analiticke hijerarhije slozenosti. Samo napominjemo da se jedan od najvaznijihproblema teorijskih kompjuterskih nauka kratko formulise P=NP (?!).

0.4 Poredjenje algoritama polinomijalne, logaritamske i eksponencijalneslozenosti

Slozenost algoritama zavisi od modela komputacije. Dimenzija problema je mera ulaznih podataka. Npr. Dimenzijaproblema mnozenja matrica moze biti najveca dimenzija matrice faktora. Kada govorimo o vremenskoj slozenosti mis-limo na asimptotsku vremensku slozenost, a kada govorimo o prostornoj slozenosti mislimo na asimptotsku prostornuslozenost. Poredjenje algoritama dajemo u sledecoj tabeli:

Maksimalna dimenzija problemaAlgoritam Vremenska slozenost 1s 1min 1h

A1 n 1000 6 ∗ 104 3.6 ∗ 106

A2 nlogn 140 4893 2 ∗ 105

A3 n2 31 244 1897A4 n3 10 39 153A5 2n 9 15 21

0.5 Uticaj povecanja brzine procesora na kompleksnost algoritma

Maksimalna dimenzija problemaAlgoritam Vremenska slozenost Do ubrzanja Nakon 10x ubrzanja

A1 n s1 10s1A2 nlogn s2 ∼ 10s2 za veliko s2A3 n2 s3 3.16 s3A4 n3 s4 2.15 s4A5 2n s5 s5+3.3

Pitanje:Moze li eksponencijalni algoritam biti bolji od polinomijalnog?Odgovor:Razmotrimo algoritme.

Algoritam A1 A2 A3 A4 A5Slozenost 100n 100nlogn 10n2 n3 2n

Nije tesko izracunati da:A5 je najbolji za 2 6 n 6 9;A3 je najbolji za 10 6 n 6 58;A2 je najbolji za 59 6 n 6 1024;A1 je najbolji za n > 1024.

0.6 Worst case, best case i awerage case slozenost algoritama

Mi se najcesce koncentrisemo na nalazenje worst case(najgori slucaj) vremena izvodjenja algoritama. Za ovakav pristupimamo najmanje tri razloga:

Page 4: Algoritmi Skripta

• Worst case vreme izvodjenja je gornja granica vremena izvodjenja za svaki ulaz. Znanje te granice garantuje daalgoritam nece nikada raditi duze, sto nam je u praksi vazno.• Neki algoritmi cesto rade u worst case vremene. Npr. Kod trazenja u bazi podataka neke partikularne informacije,algoritam pretrazivanja ce cesto raditi u worst case vremenu, ako ta informacija ne postoji u bazi. Pri tome je trazenjenepostojece informacije cest slucaj.• Awerage case (statisticka slozenost, matematicko ocekivanje) je cesto lose kao i worst case. Npr. kod sortiranjaumetanjem(insert sort) awerage case je O(n2), kao i worst case. Kod Quick Sort-a to nije slucaj. Awerage caseslozenost ili ocekivano vreme za jedan algoritam je T(n)=

∑ni=1 piT (i), gde je pi verovatnoca slozenosti T(i).

Insert sort

Primer 0.3. 1. Worst case slozenost T(n)=O(n2)=0+1+. . . +(n-1).

2. Best case slozenost. Ako u svakom koraku element koji umecemo dolazi na prvo mesto imamo T(n)=0+1+. . . +1

=∑n−1

i=0 i=n-1=O(n).

3. Awerage case slozenost.

Lema 0.1. . Srednji broj inverzija u jednom nizu od n elemenata je n(n−1)4 .

Dokaz 0.1. Posmatrajmo listu L i njen reverz Lr. Npr. L=(8,34,64,51,32,21), Lr=(21,32,51,64,34,8). (x,y) prave

inverziju ako je y > x. Tacno u jednoj L ili Lr je (x,y) inverzija I=n(n−1)4 .

Teorema 0.1.. Awerage case slozenost za insert sort je T(n)=O(n2).

Dokaz 0.2. Svaki korak u sortiranju eliminise samo jednu inverziju.

0.7 Racionalizacija mnozenja velikog broja kompleksnih brojeva

Mnozenje kompleksnih brojeva (a u odnosu na polje realnih brojeva) moze se posmatrati kao izracunavanje izraza ac-bd i ad+bc tako da je (a,b)·(c,d)=(ac-bd, ad+bc). U ovom slucaju imamo cetiri mnozenja i dva sabiranja/oduzimanja(+/-). Slozenost algoritama je T(n)=O(n2). Do brzeg resenja dolazimo ako za kompleksne brojeve (a,b) i (c,d)izracunamo:

1. (a+b)·(c+d)=ac+ad+bc+bd;

2. a·c;

3. b·d.

Proizvod dobijamo do shemi (2-3,1-2-3). Ukupno imamo tri mnozenja · i pet sabiranja/oduzimanja. Moze se pokazatida je dobijeni algoritam brzi. Takodje se moze dokazati da su tri mnozenja neophodna i dovoljna.

0.8 Hornerova shema. Kompleksnost izracunavanja vrednosri polinoma.

Posmatramo izracunavanje vrednosti polinoma u tacki X. p(x) = anxn + an−1x

n−1 + . . . + a1x+ a0Ulaz: a0, a1, a2, . . . , an−1, an, xIzlaz: p(x)Pravilo Hornera:

1. a1x+ a0, za n=1

2. (a2x+ a1)x+ a0, za n=2

3. ((a3x+ a2)x+ a1)x+ a0, za n=3,itd.

Uopste a0 + x[a1 + x[a2 + . . . + anx]. . . ] Za izracunavanje p(x) po Hornerovoj shemi, trebamo n operacija mnozenjai ne operacija sabiranja. Moze se pokazati da Hornerova shema daje optimalan algoritam za izracunavanje vrednostipolinoma u datoj tacki x (u odnosu na broj operacija sabiranja i mnozenja).

Page 5: Algoritmi Skripta

0.9 Elementarne metode sortiranja: bubble sort, sort izborom i sortumetanjem. Dizajn i analiza slozenosti.

Neka je niz koji treba sortirati sastavljen od a[i] ∈ S, i=1,2,. . . ,n, pri cemu je S linearno uredjen skup. Sortiramo urastucem poretku.Bubble sort(sort mehuricima)Poredimo a[j] sa a[j+1], j=1,2,...,n-1, i=1,2,...,n-1. Ukoliko je a[j]¿a[j+1] tada elementima razmenjujemo mesta. Nataj nacin ce u prvom prolazu najveci element doci na zadnje mesto, u drugom prolazu ce drugi po velicini elementdoci na pretposlednje mesto itd. U i-tom prolazu dovodimo i-ti element na odgovarajuce mesto. Nakon nekog brojaprolaza, najvise n-1, svi ce elementi biti sortirani. Napominjemo da uvodjenjem indikatora(zastavice) mozemo ucinitida algoritam prekine rad cim su brojevi sortirani. Naime, cim u nekom prolazu nema izmena postavljamo indikatorina 1, a onda izlazimo iz petlje, jer je provera indikatora postavljena u uslovu petlje.Bubble sort

template <classT>1void s o r t (T∗a , i n t n){f o r ( i n t i =1; i<n ; i++)f o r ( i n t j =1; j<=n ; j++)i f ( a [ j−1]<a [ j ] ) swap ( a [ j −1] , a [ j ] ) ;// i n v a r i j a n t a : i−t i po v e l i c i n i e l ement i su na ispravnom mestu}

Worst case slozenost: T(n)=(n-1)+(n-2)+...+1= (n−1)n2 =O(n2) je broj poredjenja koje trebe napraviti u najgorem

slucaju.Insertion sort (sort umetanjem)Na prvo mesto dovodimo proizvoljan element niza a[]. Iz ostatka niza uzimamo proizvoljno elemenat i dovodimo gana prvo mesto niza, ako je manji od elementa koji tamo vec stoji ili na drugo mesto, u suprotnom. Zatim iz ostatkaniza uzimamo neki element i poredimo gas a prvim i drugim elementom, tako da prva tri elementa budu uredjeni urastucem poretku, itd. dok ne uredimo svih n elemenata niza. [Slicno postupamo na primer slazuci karte u remiju.]Implementacija sorta umetanjem u C++

template <classT>void s o r t ( T ∗a , i n t n){f o r ( i n t i =1; i<n ; i++){T temp=a [ i ] ;f o r ( i n t j=I ; j>0 && a [ j−i ]>temp ; j−−)a [ j ]=a [ j −1] ;a [ j ]=temp ;// I n v a r i j a n t a : a[0]<=a [ 1 ] <=...<=a [ i ]}}

Worst case kompleksnost T(n)=1+2+...+(n-1)=O( n2 ) jer za dvoclani niz imamo jedno poredjenje, za troclanidva poredjenja... I za n-ti clan, zavrsni niz, imamo n-1 poredjenja. Uopste, i-ti element se dovodi na pravo mesto ui-tom nizu, koristeci u najgorem slucaju (i-1) poredjenja.

Sort izboromU prvom krugu se na prvo mesto niza a[] dovodi najmanji element niza, u drugom krugu se na drugo mesto dovodinajmanji element iz ostatka niza, itd.

// Sort izborom

template <classT>void s o r t ( T ∗a , i n t n){

f o r ( i n t i =0; i<n−1; i++){

i n t min=I ;f o r ( i n t j=i +1; j<n ; j++)

i f ( a [ j ]<a [ min ] )

Page 6: Algoritmi Skripta

min =j ;// I n v a r i j a n t a : a [ min]<=a [ j ] za i<=j<nswap ( a [ min ] , a [ i ] ) ;

}}

Worst case slozenost T(n)=(n-1)+(n-2)+...+1=O(n2) (n-1)→ broj poredjenja da se od n brojeva izabere najmanji(n-2)→ broj poredjenja da se iz n-1 brojeva izabere najmanji 1 → broj poredjenja da se od 2 elementa izabere manji

0.10 Algoritam za nalazenje drugog elementa u nizu i razvoj algoritamaefektivnog sortiranja

Dajemo primer za nalazenje prvog i drugog po velicini elementa niza u n+log2n - const koraka.

Sa slike vidimo da prvi element biramo u n-1 koraka (== broj cvorova drveta). Kandidati za drugi po velicinielement su oni koji su izgubili od najveceg kandidata. Na svakom nivou drveta je po jedan takav element, pa je zbogtoga njihov broj jednak visini drveta, dakle log2n. Na slici smo takve brojeve oznacili pravougaonikom. Dakle, prvi idrugi element niza mozemo izabrati u (n-1)+(log2n-1) koraka.Ideja za sortiranje niza od n elemenata:Naci najveci element niza i staviti ga prvo mesto u novom nizu. Naci drugi element po velicini u nizu i staviti ga nadrugom mesto, itd. U najgorem slucaju, ovaj algoritam ima slozenost T(n)=n+(n-1)+...+1=O(n2). Medjutim, akoalgoritam poboljsamo tako da pamtimo ko je sve izgubio od prethodnog izabranog elementa, dobicemo slozenost unajgorem slucaju. T(n)=O(nlogn).

0.11 Metoda programiranja podeli i vladaj. Dizajn i analiza slozenostirekurzivnih algoritama.

1. Definisati model komputacije

2. Definisati formate podataka ulaza i izlaza

3. Definisati COST funkciju

4. Pridruziti duzine ulazima

5. Slozenost funkcije se odnosi na duzinu inputa i pri tome ne na partikularan input

Pokusavamo naci gornju i donju granicu problema. Ako problem ima gornju granicu O(f(n)) to znaci ∃ algoritamA za problem i O(f(n)) je slozenost od A.Algoritam je jedan potpuno specifikovan niz koraka koji uvek daje korektan odgovor. Sa druge strane, hevristikadozvoljava na nekim inputima greske, ali na vecini inputa ne.

Page 7: Algoritmi Skripta

0.11.1 Divide and conquer tehnika (ili rekurzivna tehnika) resavanja problema.

Svaki od b problema dobija nc duzinu inputa duzine n. Analiza kompleksnosti takvog algoritma daje

T (n) =

{bT (n

c ) + nd, n > 11, n = 1

T(n)= O(nh(a,b,c))T (n) = nd + bd(n

c )d + bd( nc2 )d + b · T ( n

c3 )eenci = 1 ⇒ i = logcn daje nam uslov zaustavljanja = nd + b(n

c )d + b2( nc2 )d + b3( n

c3 ) + ... + bi( nci )d = ndd1 + b

cd+

( bcd

)2 + ( bcd

)3 + ...+ ( bcd

)ieMi razlikujemo izmedju b?cd ⇔ logcb ? d

1. logcb = d⇒ T(n)=O(ndlogcn)

2. logcb < d⇒ T(n)=O(nd)

3. logcb > d⇒ T(n)=O(nlogcb), jer je blogcn = blogcblogbn

logcb nazivamo eksponent rekurzije, a d nazivamo direktni eksponent.

0.12 Binarno pretrazivanje: nalazenje zadatog elementa u uredjenomnizu brojeva za vreme O(logn)

Dat je sortiran niz od n brojeva. Treba naci clan niza jednak zadatom elementu x. Dajemo sledeci algoritam.Biramo u nizu clan an

2.

Ako je an2

=x, tada Stop.Ako je an

2< x, ostaje da se pretrazi samo desna polovina, a ako je an

2> x, ostaje da se pretrazi samo leva polovina.

Slozenost u najgorem slucaju je T(n)=n+T(n2 ).

Dakle, d=0, b=1, c=2, sto daje logcb = log21 = 0 = d; Prema rezultatima u pitanju 85. dobijamo T(n)=O(logn).Implementacija algoritma binarnog pretrazivanja C++(a) Rekurzivna procedura/* Ako je x u nizu a[ ] tada ce njegova lokacija biti vracena, a inace ce biti vraceno -1 */

i n t f i n d ( f l o a t ∗a , i n t s ta r t , i n t stop , f l o a t x ){i f ( s t a r t>stop ) re turn −1 li n t mid=( s t a r t+stop ) / 2 ;i f ( x==a [ mid ] re turn mid ) ;i f (x<a [ mid ] re turn f i n d ( a , s t a r t , mid−1,x ) ;i f (x>a [ mid ] re turn f i n d ( a , mid+1, stop , x ) ;}Dajemo t e s t n i program za proceduru f i n di n t main ( ){ f l o a t a [ ]={11 . 1 , 2 2 . 2 , 3 3 . 3 , 4 4 . 4 , 5 5 . 5 , 6 6 . 6 , 7 7 . 7 , 8 8 . 8 } ;i n t k=f i n d ( a , 0 , 8 , 6 6 . 6 ) ;cout<<”k=” <<k<<end ;k=f i n d ( a , 0 , 8 , 5 0 ) ;cout<<”k=” <<k<<end ;}

(b) Iterativna procedura

Page 8: Algoritmi Skripta

template <c l a s s T>i n t f i n d ( constT∗a , i n t begin , i n t end , const T & t a r g e t ){ i n t Lo=begin ; i n t h i=end−1 lwhi l e (Lo<=hi ){i n t mid=(Lo+hi (/2 ; // Naci s r ed inu .i f ( a [ mid]==t a r g e t ) re turn mid ; //Nadjen !i f ( a [ mid]> t a r g e t ) h i=mid−1;// Trazi u l e v o j p o l o v i n i .e l s e Lo=mid+1 l // Trazi u desnoj p o l o v i n i .}re turn end ;}

Testni program bi se napravio slicno kao u slucaju a.

0.13 Efektivno mnozenje dugackih celih brojeva u vremenu O(n1.59)

Razmotrimo mnozenje dva n-bitna binarna broja. Tradicionalni metod treba T(n)=T(n2) operacija nad bitovima. Umetodu koji izlazemo dovoljno je T(n)=O(n1.59) operacija nad bitovima. Razbijemo x i y na dva jednaka dela kao na

slici.Ako svaki od tih delova posmatramo kao n

2 -cifreni, rada mozemo predstaviti mnozenje x i y u obliku xy =(a2

n2 + b)(c2

n2 + d) = ac2n + (ad+ bc)2

n2 + bd. Proizvod dakle mozemo izracunati pomocu programa

{u<−(a+b )∗ ( c+d ) ;v<−a∗c ;w<−b∗d ;z<−v∗2ˆn + (u−v−w)∗2ˆ{m/2} + w;

}

Prema formuli za slozenost programa imamo T (n) = 3T (n

2) + n, sto daje T(n)=O(n1.59).

0.14 Merge sort. Dizajn i analiza slozenosti

Razmotrimo niz celih brojeva x1, x2, . . . , xn. Radi prostijeg racuna pretpostavimo da je n stepen broja 2. Jedan odnacina da sortiramo dati niz je da razbijemo dati niz na dva podniza x1, x2, . . . , xn

2i xn

2 +1, xn2 +2, . . . , xn, sortiramo

svaki od njih i zatim ih merdzujemo(smesamo). Pod merdzovanjem mi podrazumevamo spajanje dva vec sortiranapodniza u jedan sortiran niz. Slozenost (worst-case):Prema podeli i vladaj imamo T(n)=2T(n

2 )+n, pa je d=1, b=1,c=2. Konacno logcb = log22 = 1 = d =⇒ T(n)=O(nlogn). Dakle, merge sort je bolji od insert sorta, bubble sorta isorta izborom, ako nas interesuje worst-case.Implementacija merge sorta u C++

//Merge s o r ttemplate <c l a s s T>void merge (T∗a , i n t n1 , i n t n2 ){T∗temp=new T[ n1+n2 ] ;i n t i =0, j 1 =0, j 2 =0;whi l e ( j1>n1 && j2<n2 )temp [ i ++]=(a [ j 1 ]<=a [ n1+j2 ] ? a [ j 1 ++]:a [ n1+j2 ++]);whi l e ( j1<n1 )temp [ i++]=a [ j 1 ++];whi l e ( j2<n2 )temp [ i ++]=(a+n1 ) [ j 2 ++];f o r ( i =0; i<n1+n2 ; i++)a [ i ]=temp [ i ] ;

Page 9: Algoritmi Skripta

d e l e t e [ ] temp ;}template <c l a s s T>void s o r t (T∗a , i n t n){ i f (n>1){ i n t n1=n /2 ;i n t n2=n−n1 ;s o r t ( a , n1 ) ;s o r t ( a+n1 , n2 ) ;merge ( a , n1 , n2 ) ;}}

0.15 Efektivno mnozenje matrica u vremenu O(n2.81)

Neka su A i B dve (nxn) matrice, pri cemu je n stepen broja 2. Svaku matricu A i B mozemo razbiti na cetiri matricei preko njih izraziti proizvod matrica A i B:[

A11 A12

A21 A22

] [B11 B12

B21 B22

]=

[C11 C12

C12 C22

]gde je

C11 = A11B11 +A12B21, C12 = A11B12 +A12B22, C21 = A21B11 +A22B21, C22 = A21B12 +A22B22

Ako se Cij izracunava pomocu m mnozenja i a sabiranja/oduzimanja, tada rekurzivno primenjujuci gornji algoritam

dobijamo T (n) ≤ mT (n2 ) +

a · n2

4, n > 2, gde je n stepen dvojke. Obican metod mnozenja matrica ima slozenost

T(n)=O(n3). Nas rekurzivni metod ima 8 mnozenja(*) i 4 sabiranja(+), sto daje T (n) = 8T (n2 ) + n2, i dalje logcb =

log28 = 3 > d = 2⇒ T (n) = O(nloccb) = O(n3). Dakle, na ovaj nacin primene tehnike podeli i vladaj nismo ostvarilinapredak.Strasen (Strassen W.) napravio je svojevremeno iznenadjenje kada je nasao metod mnozenja matrica nad proizvoljnimprstenom u kojem je dovoljno sedam mnozenja, pa je poboljsao vremensku slozenost. Na pocetku je formirao proizvodeblokova matrica.m1 = (A12 −A22)(B21 +B22)m2 = (A11 +A22)(B11 +B22)m3 = (A11 −A21)(B11 +B12)m4 = (A11 +A12)B22

m5 = A11(B12 −B22)m6 = A22(B21 −B11)m7 = (A21 +A22)B11

Zatim izracunamoC11 = m1 +m2 −m4 +m6,C12 = m4 +m5,C21 = m6 +m7,C22 = m2 −m3 +m5 −m7.Prema formuli iz ”Podeli i vladaj” imamo: T (n) = 7T (n

2 ) + 18n2 , sto daje T (n) = O(nlog27) = O(n2.81) sto je boljeod klasicnog algoritma.Napomena.

Neki pokusavaju popraviti algoritam tako sto startuju sa 3x3 matricama. Tada je T (n) = xT (n3 ) +O(n2) i treba naci

x(tj. broj mnozenja) tako da bude log3x < 2.81.

0.16 Quick sort. Dizajn i analiza slozenosti.

Algoritam:

• Izabrati slucajno(random) element deljenja niza.

• Podeliti niz u podskupove manjih i vecih elemenata u odnosu na izabrani element.

• Posebno sortirati podskup.

Page 10: Algoritmi Skripta

• Nadovezati sortirane podskupove.

Worst case vreme izvodjenja:U slucaju da u svakom koraku deljenja izaberemo maksimalan(minimalan) element, za niz od n elemenata imamoT(n)=n+(n-1)+. . .+1=O(n2).Best case vreme izvodjenja:U slucaju da u svakom koraku izaberemo medium element, prema formuli iz ”Podeli i vladaj” imamo T(n)=2T(n

2 )+nsto daje T(n)=O(nlogn).Awerage case analiza:T (n) 6 c · n+

∑ni=1

1n (T (i− 1) + T (n− i)) = c · n+ 2

n

∑n−1i=0 T (i), c · n je vreme podele za n elemenata.

Mi zelimo dokazati ogranicenje T(n)6 knlogn. T (n) ≤ cn+2

n

n−1∑i=0

ilogi ≤ cn+2k

ndn

2logn

2− n

2

4e ≤ knlogn+cn− k

2n Za

k=2c imamo T (n) ≤ knlogn. Ocena je postignuta koristeci induktivnu hipotezu T (i) ≤ ilogi za i<n, te sledeci kvaziar-

gument

n−1∑i=0

ilogi =

∫ n−1

0+

xlogxdx =x2

2logx |n−10 −

∫ n−1

0+

x2

2

1

xdx =

(n− 1)2

2log(n− 1)− x2

4|n−10 =

(n− 1)2

2log(n−

1)− (n− 1)2

4

//Quick s o r ttemplate <c l a s s T>void q u i c k s o r t (T∗a , i n t Lo , i n t h i ){ i f (Lo>=hi ) re turn ;T p ivot = a [ h i ] ;i n t i= Lo−1 li n t j=hi ;whi l e ( i<j ){whi le ( a[++ i ]<pivot )whi l e ( j>=0 && a[−− j ]<pivot ) ;i f ( i<j ) swap ( a [ i ] , a [ j ] ) ;}swap ( a [ i ] , a [ h i ] ) ;// I n v a r i j a n t a : a [ j ]<=a [ i ]<=a [ k ] za Lo<=j<i<k<=hi //q u i c k s o r t ( a , Lo , i −1);q u i c k s o r t ( a , i +1, h i ) ;}template <c l a s s T>void s o r t (T∗a , i n t n){ q u i c k s o r t ( a , 0 , n−1);}

0.17 Nalazenje k-tog elementa u linearnom vremenu

Za izbotr k-tog po velicini elementa niza S primenjujemo sledeci algoritam ”Procedure izbor(k,s)”:

1. if | 5 |< 50 then {

2. urediti 5;

3. return k-ti najmanji element iz S }; else

4. { Razbiti S na b| 5 | /5c nizova po 5 elemenata u svakom nizu

5. pri cemu ce ostati najvise 4 neiskoristena elementa niza

6. urediti svaki petoelementni niz

7. neka je M niz medijana tih petoelementnih nizova

8. M=IZBOR(d|M | /2e)

9. S1, S2, S3 - skupovi elemenata manjih, jednakih, vecih od m

10. if | S1 |≥ k then return IZBOR(k, S1); else

Page 11: Algoritmi Skripta

11. if | S1 | + | S2 |≥ k) then return m; else

12. return IZBOR (k-| S1 | − | S2 |, S3)

0.18 Donje ogranicenje O(nlogn) za algoritme sortiranja poredjenjem uopstem slucaju

Dokazujemo da je Φ(nlogn) donje ogranicenje za vreme sortiranja n vrednosti, ako se koristi poredjenje, u opstemslucaju. Slicno kao u primeru drveta odlucivanja za tri elementa a,b,c. Vidimo da i u opstem slucaju algoritamsortiranja poredjenjem i u opstem slucaju moze biti opisan drvetom odlucivanja sa najmanje n! listova. Jasno je da je

1. Worst case vreme=visina dohvatljivog dela drveta. Svako drvo visine h moze imati najvise 2h listova. Za n!

listova visina mora biti veca ili jednaka log2n!. Posto je n! ≈ (n

e)n to je h≥logn! ≈ n[log2n− log2e]=O(nlogn)

2.

Teorema 0.2.. Φ(nlogn) donja granica za sortiranje poredjenjem, primenljiva je i za awerage case kompleksnost.

Dokaz 0.3. Opsta definicija awerage case kompleksnosti jeA(n)=

∑|x|=n ρ(x)T (x). U opstem slucaju je 1

n!

∑|x|=n T (x) i D(m)=minD(T) za sumu dubina listova bilo kojeg

drveta poredjenja sa m listova. Treba dokazati D(m)=nlogn.Dokaz izvvodimo indukcijom. Za m=1 je trivijalno 0.Za m>1:Pretpostavimo da TR ima k listova, tako da je i listova u levom poddrvetu TRi i k-i listova u desnom poddrvetuTRk−i.

0.19 Dinamicko programiranje. Poredak mnozenja matrica.

Dynamic ProgrammingDynamic programming, like the divide-and-conquer method, solves problems by combining the solutions to subprob-lems. (”Programming” in this context refers to a tabular method, not to writing computer code.) As we saw inChapter 2, divide-and-conquer algorithms partition the problem into independent subproblems, solve the subproblemsrecursively, and then combine their solutions to solve the original problem. In contrast, dynamic programming is ap-plicable when the subproblems are not independent, that is, when subproblems share subsubproblems. In this context,a divide-and-conquer algorithm does more work than necessary, repeatedly solving the common subsubproblems. Adynamic-programming algorithm solves every subsubproblem just once and then saves its answer in a table, therebyavoiding the work of recomputing the answer every time the subsubproblem is encountered.Dynamic programming is typically applied to optimization problems. In such problems there can be many possiblesolutions. Each solution has a value, and we wish to find a solution with the optimal (minimum or maximum) value.We call such a solution an optimal solution to the problem, as opposed to the optimal solution, since there may beseveral solutions that achieve the optimal value.The development of a dynamic-programming algorithm can be broken into a sequence of four steps.Characterize the structure of an optimal solution.Recursively define the value of an optimal solution.Compute the value of an optimal solution in a bottom-up fashion.Construct an optimal solution from computed information.Steps 1-3 form the basis of a dynamic-programming solution to a problem. Step 4 can be omitted if only the value ofan optimal solution is required. When we do perform step 4, we sometimes maintain additional information duringthe computation in step 3 to ease the construction of an optimal solution.The sections that follow use the dynamic-programming method to solve some optimization problems. Section 15.1examines a problem in scheduling two automobile assembly lines, where after each station, the auto under constructioncan stay on the same line or move to the other. Section 15.2 asks how we can multiply a chain of matrices so thatthe fewest total scalar multiplications are performed. Given these examples of dynamic programming, Section 15.3discusses two key characteristics that a problem must have for dynamic programming to be a viable solution technique.Section 15.4 then shows how to find the longest common subsequence of two sequences. Finally, Section 15.5 usesdynamic programming to construct binary search trees that are optimal, given a known distribution of keys to belooked up.

0.19.1 Matrix-chain multiplication

Our next example of dynamic programming is an algorithm that solves the problem of matrix-chain multiplication.We are given a sequence (chain) 〈 A1, A2, ...,An 〉 of n matrices to be multiplied, and we wish to compute the product

Page 12: Algoritmi Skripta

(15.10) We can evaluate the expression (15.10) using the standard algorithm for multiplying pairs of matrices as asubroutine once we have parenthesized it to resolve all ambiguities in how the matrices are multiplied together. Aproduct of matrices is fully parenthesized if it is either a single matrix or the product of two fully parenthesizedmatrix products, surrounded by parentheses. Matrix multiplication is associative, and so all parenthesizations yieldthe same product. For example, if the chain of matrices is 〈A1, A2, A3, A4〉, the product A1 ·A2 ·A3 ·A4 can be fullyparenthesized in five distinct ways: (A1(A2(A3A4)))(A1((A2A3)A4))((A1A2)(A3A4))((A1(A2A3))A4)(((A1A2)A3)A4). The way we parenthesize a chain of matrices can have a dramatic impact on the cost of evaluating theproduct. Consider first the cost of multiplying two matrices. The standard algorithm is given by the following pseu-docode. The attributes rows and columns are the numbers of rows and columns in a matrix. MATRIX-MULTIPLY(A,B)

1 i f columns [A] \neq rows [B]2 then e r r o r ” incompat ib le dimensions ”3 e l s e f o r i <− 1 to rows [A]4 do f o r j <− 1 to columns [B]5 do C[ i , j ] <− 06 f o r k <− 1 to columns [A]7 do C[ i , j ] <− C[ i , j ] + A[ i , k ] B[ k , j ]8 re turn C

We can multiply two matrices A and B only if they are compatible: the number of columns of A must equal thenumber of rows of B. If A is a p x q matrix and B is a q x r matrix, the resulting matrix C is a p x r matrix. The timeto compute C is dominated by the number of scalar multiplications in line 7, which is pqr. In what follows, we shallexpress costs in terms of the number of scalar multiplications. To illustrate the different costs incurred by differentparenthesizations of a matrix product, consider the problem of a chain 〈 A1, A2, A3 〉 of three matrices. Supposethat the dimensions of the matrices are 10 x 100, 100 x 5, and 5 x 50, respectively. If we multiply according to theparenthesization ((A1A2)A3), we perform 10·100· 5 = 5000 scalar multiplications to compute the 10 x 5 matrix productA1A2, plus another 10 · 5 · 50 = 2500 scalar multiplications to multiply this matrix by A3, for a total of 7500 scalarmultiplications. If instead we multiply according to the parenthesization (A1(A2A3)), we perform 100 · 5 · 50 = 25, 000scalar multiplications to compute the 100 x 50 matrix product A2A3, plus another 10 · 100 · 50 = 50, 000 scalarmultiplications to multiply A1 by this matrix, for a total of 75,000 scalar multiplications. Thus, computing theproduct according to the first parenthesization is 10 times faster. The matrix-chain multiplication problem can bestated as follows: given a chain 〈A1, A2, ..., An〉 of n matrices, where for i = 1, 2, ..., n, matrix Ai has dimension pi−1xpi, fully parenthesize the product A1A2An in a way that minimizes the number of scalar multiplications.

0.19.2 Counting the number of parenthesizations

Before solving the matrix-chain multiplication problem by dynamic programming, let us convince ourselves thatexhaustively checking all possible parenthesizations does not yield an efficient algorithm. Denote the number ofalternative parenthesizations of a sequence of n matrices by P(n). When n = 1, there is just one matrix and thereforeonly one way to fully parenthesize the matrix product. When n ≥ 2, a fully parenthesized matrix product is theproduct of two fully parenthesized matrix subproducts, and the split between the two subproducts may occur betweenthe kth and (k + 1)st matrices for any k = 1, 2, ..., n - 1. Thus, we obtain the recurrence Problem 12-4 asked youto show that the solution to a similar recurrence is the sequence of Catalan numbers The number of solutions is thusexponential in n, and the brute-force method of exhaustive search is therefore a poor strategy for determining theoptimal parenthesization of a matrix chain.

0.19.3 The structure of an optimal parenthesization

Our first step in the dynamic-programming paradigm is to find the optimal substructure and then use it to construct anoptimal solution to the problem from optimal solutions to subproblems. For the matrix-chain multiplication problem,we can perform this step as follows. For convenience, let us adopt the notation Ai..j , where i ≤ j, for the matrixthat results from evaluating the product AiAi+1Aj . Observe that if the problem is nontrivial, i.e., i ¡ j, then anyparenthesization of the product AiAi+1Aj must split the product between Ak and Ak+1 for some integer k in therange i≤ k ¡ j. That is, for some value of k, we first compute the matrices Ai...k and Ak+1...n and then multiply themtogether to produce the final product Ai..j . The cost of this parenthesization is thus the cost of computing the matrixAi..k, plus the cost of computing Ak+1..n, plus the cost of multiplying them together. The optimal substructure ofthis problem is as follows. Suppose that an optimal parenthesization of Ai Ai+1Aj splits the product between Ak

and Ak+1. Then the parenthesization of the ”prefix” subchain AiAi+1Ak within this optimal parenthesization ofAiAi+1Aj must be an optimal parenthesization of AiAi+1Ak. Why? If there were a less costly way to parenthesize

Page 13: Algoritmi Skripta

Ai Ai+1Ak, substituting that parenthesization in the optimal parenthesization of AiAi+1Aj would produce anotherparenthesization of AiAi+1Aj whose cost was lower than the optimum: a contradiction. A similar observation holdsfor the parenthesization of the subchain Ak+1Ak+2Aj in the optimal parenthesization of AiAi+1Aj : it must be anoptimal parenthesization of Ak+1Ak+2Aj . Now we use our optimal substructure to show that we can construct anoptimal solution to the problem from optimal solutions to subproblems. We have seen that any solution to a nontrivialinstance of the matrix-chain multiplication problem requires us to split the product, and that any optimal solutioncontains within it optimal solutions to subproblem instances. Thus, we can build an optimal solution to an instanceof the matrix-chain multiplication problem by splitting the problem into two subproblems (optimally parenthesizingAiAi+1Ak andAk+1Ak+2Aj), finding optimal solutions to subproblem instances, and then combining these optimalsubproblem solutions. We must ensure that when we search for the correct place to split the product, we haveconsidered all possible places so that we are sure of having examined the optimal one.

0.19.4 A recursive solution

Next, we define the cost of an optimal solution recursively in terms of the optimal solutions to subproblems. For thematrix-chain multiplication problem, we pick as our subproblems the problems of determining the minimum cost of aparenthesization of AiAi+1Aj for 1 ≤ i ≤ j ≤ n. Let mdi, je be the minimum number of scalar multiplications neededto compute the matrix Ai...j ; for the full problem, the cost of a cheapest way to compute A1..n would thus be md1, ne.We can define m di, je recursively as follows. If i = j, the problem is trivial; the chain consists of just one matrix Ai..i

= Ai, so that no scalar multiplications are necessary to compute the product. Thus, m[i, i] = 0 for i = 1, 2, ..., n.To compute mdi, je when i ¡ j, we take advantage of the structure of an optimal solution from step 1. Let us assumethat the optimal parenthesization splits the product AiAi+1Aj between Ak and Ak+1, where i ≤ k ¡ j. Then, mdi, jeis equal to the minimum cost for computing the subproducts Ai...k and Ak+1...j , plus the cost of multiplying these twomatrices together. Recalling that each matrix Ai is pi−1xpi, we see that computing the matrix product Ai..k Ak+1..j

takes pi−1pkpj scalar multiplications. Thus, we obtain mdi, je = mdi, ke + mdk + 1, je + pi−1pkpj . This recursiveequation assumes that we know the value of k, which we do not. There are only j - i possible values for k, however,namely k = i, i + 1, ..., j - 1. Since the optimal parenthesization must use one of these values for k, we need onlycheck them all to find the best. Thus, our recursive definition for the minimum cost of parenthesizing the productAiAi+1Aj becomes (15.12)

mdi, je =

{0, if i = jmini≤k<j mdi, ke+mdk + 1, je+ pi−1pjpk, if i < j

The mdi, je values give the costs of optimal solutions to subproblems. To help us keep track of how to constructan optimal solution, let us define sdi, je to be a value of k at which we can split the product AiAi+1Aj to obtain anoptimal parenthesization. That is, sdi, je equals a value k such that mdi, je = mdi, ke + mdk + 1, je + pi−1pkpj .

0.19.5 Computing the optimal costs

At this point, it is a simple matter to write a recursive algorithm based on recurrence (15.12) to compute the minimumcost m[1, n] for multiplying A1 A2 An. As we shall see in Section 15.3, however, this algorithm takes exponential time,which is no better than the brute-force method of checking each way of parenthesizing the product. The importantobservation that we can make at this point is that we have relatively few subproblems: one problem for each choice of iand j satisfying 1 ≤ i ≤ j ≤ n, or in all. A recursive algorithm may encounter each subproblem many times in differentbranches of its recursion tree. This property of overlapping subproblems is the second hallmark of the applicability ofdynamic programming (the first hallmark being optimal substructure). Instead of computing the solution to recurrence(15.12) recursively, we perform the third step of the dynamic-programming paradigm and compute the optimal costby using a tabular, bottom-up approach. The following pseudocode assumes that matrix Ai has dimensions pi−1xpifor i = 1, 2, ..., n. The input is a sequence p = bp0, p1, ..., pn〉, where lengthdpe = n + 1. The procedure uses anauxiliary table md1...n, 1...ne for storing the mdi, je costs and an auxiliary table sd1...n, 1...ne that records whichindex of k achieved the optimal cost in computing mdi, je. We will use the table s to construct an optimal solution.MATRIX-CHAIN-ORDER(p)

1 n <− l ength [ p ] − 12 f o r i <− 1 to n3 do m[ i , i ] <− 04 f o r l <− 2 to n5 do f o r i <− 1 to n − l + 16 do j <− i + l − 17 m[ i , j ] <− \ i n f t y8 f o r k <− i to j − 19 do q <− m[ i , k ] + m[ k + 1 , j ] + p i−1 p kp j10 i f q < m[ i , j ]

Page 14: Algoritmi Skripta

11 then m[ i , j ] <− q12 s [ i , j ] <− k13 return m and s

The algorithm first computes mdi, ie ← 0 for i = 1, 2, ..., n (the minimum costs for chains of length 1) in lines 2-3.It then uses recurrence (15.12) to compute m[i, i + 1] for i = 1, 2, ..., n - 1 (the minimum costs for chains of lengthl = 2) during the first execution of the loop in lines 4-12. The second time through the loop, it computes m[i, i +2] for i = 1, 2, ..., n - 2 (the minimum costs for chains of length l = 3), and so forth. At each step, the m[i, j] costcomputed in lines 9-12 depends only on table entries m[i, k] and m[k + 1, j] already computed. Figure 15.3 illustratesthis procedure on a chain of n = 6 matrices. Since we have defined mdi, je only for i 6 j, only the portion of thetable m strictly above the main diagonal is used. The figure shows the table rotated to make the main diagonal runhorizontally. The matrix chain is listed along the bottom. Using this layout, the minimum cost m[i, j] for multiplyinga subchain AiAi+1Aj of matrices can be found at the intersection of lines running northeast from Ai and northwestfrom Aj . Each horizontal row in the table contains the entries for matrix chains of the same length.

MATRIX-CHAIN-ORDER computes the rows from bottom to top and from left to right within each row. Anentry mdi, je is computed using the products pi−1pkpj for k = i, i + 1, ..., j - 1 and all entries southwest and southeastfrom m[i, j].

Figure 15.3: The m and s tables computed by MATRIX-CHAIN-ORDER for n = 6 and the

following matrix dimensions:matrix dimensionA1 30 · 35A2 35 · 15A3 15 · 5A4 5 · 10A5 10 · 20A6 20 · 25

The tables are rotated so that the main diagonal runs horizontally. Only the main diagonal and upper triangle areused in the m table, and only the upper triangle is used in the s table. The minimum number of scalar multiplicationsto multiply the 6 matrices is md1, 6e = 15,125. Of the darker entries, the pairs that have the same shading are takentogether in line 9 when computing

A simple inspection of the nested loop structure of MATRIX-CHAIN-ORDER yields a running time of O(n3) forthe algorithm. The loops are nested three deep, and each loop index (l, i, and k) takes on at most n -1 values. Exercise15.2-4 asks you to show that the running time of this algorithm is in fact also ω(n3). The algorithm requires θ(n2)space to store the m and s tables. Thus, MATRIX-CHAIN-ORDER is much more efficient than the exponential-timemethod of enumerating all possible parenthesizations and checking each one.

0.19.6 Constructing an optimal solution

Although MATRIX-CHAIN-ORDER determines the optimal number of scalar multiplications needed to compute amatrix-chain product, it does not directly show how to multiply the matrices. It is not difficult to construct an optimalsolution from the computed information stored in the table s d1...n, 1...ne. Each entry s di, je records the value of ksuch that the optimal parenthesization of AiAi+1...Aj splits the product between Ak and Ak+1. Thus, we know thatthe final matrix multiplication in computing A1..n optimally is A1..s[1,n] As[1,n]+1..n. The earlier matrix multiplicationscan be computed recursively, since sd1, sd1, nee determines the last matrix multiplication in computing A1..s[1,n], ands dsd1, ne+ 1, ne determines the last matrix multiplication in computing As[1,n]+1..n.The following recursive procedure prints an optimal parenthesization of 〈Ai, Ai+1, ..., Aj〉, given the s table computedby MATRIX-CHAIN-ORDER and the indices i and j. The initial call is MATRIX-CHAIN-ORDER (A, s, 1, n).

Page 15: Algoritmi Skripta

MATRIX−CHAIN−ORDER (A, s , 1 , n )1 i f i < j2 then X <− MATRIX−CHAIN−ORDER (A, s , i , s [ i , j ] )3 then Y <− MATRIX−CHAIN−ORDER (A, s , s [ i , j ] + 1 , j )4 re turn MATRIX − MULTIPLY (X,Y)5 e l s e re turn Ai

In the example of Figure 15.3, the call MATRIX-CHAIN-MULTIPLY (A, s, 1, 6) computes the matrix-chain productaccording to the parenthesization ((A1(A2A3))((A4A5)A6)).

0.19.7 Exercises

Exercises 15.2-1Find an optimal parenthesization of a matrix-chain product whose sequence of dimensions is 〈5, 10, 3, 12, 5, 50, 6〉.Exercises 15.2-2Give a recursive algorithm MATRIX-CHAIN-MULTIPLY(A, s, i, j) that actually performs the optimal matrix-chainmultiplication, given the sequence of matrices 〈A1, A2, ..., An〉, the s table computed by MATRIX-CHAIN-ORDER,and the indices i and j. (The initial call would be MATRIX-CHAIN-MULTIPLY(A, s, 1, n))Exercises 15.2-3Show that a full parenthesization of an n-element expression has exactly n - 1 pairs of parentheses.

subsectionOsobine najduzeg zajednickog podniza Algoritam grube sile. Numerisati sve odnizove niza X i probatikoji je od njih najduzi i zajednici sa Y podnizom. Postoji 2m podnizova od X, pa algoritam zahteva eksponencijalnovreme sto ga cini nepakticnim. Definisemo i-ti prefiks od X, i=0,1,...,m kao Xi = 〈x1, x2, ..., xi〉. Na primer: X =〈A,B,C,B,D,A,B〉 je X4 = 〈A,B,C,D〉.

Teorema 0.3.. Neka je Xi = 〈x1, x2, ..., xm〉 i Yi = 〈y1, y2, ..., yn〉 i neka je Zi = 〈z1, z2, ..., zk〉 LCS za X i Y.

1. Ako je xm = yn tada je zk = xm = yn i zk−1 = LCS(xm−1, yn−1)

2. Ako je xm 6= yn tada iz zk 6= xm sledi da je z = LCS(xm−1, y)

3. Ako je xm 6= yn tada iz zk 6= yn sledi da je z = LCS(x, yn−1)

Dokaz 0.4. 1. Ako je zk 6= xm, tada mozemo dodati yn = xm na Z i dobiti zajednicki podniz X i Y duzine k+1, stoje suprotno pretpostavci xm = yn = zk. Pretpostavka zk−1 6= LCS(xn−1, ym−1) . Lako dovodi do kontradikcije.

2. Ako je zk 6= xm, tada je Z zajednicki podniz od Xm−1 i Y. Ako bi postojao zajednicki podniz Xm−1 i Y saduzinom vecom od k, tada bi taj podniz W bio zajednicki podniz Xm i Y, sto je suprotno pretpostavci.

3. Simetricno dokazu 2.

0.19.8 Najduzi zajednicki podniz

X = 〈x1, x2, ..., xm〉; Z = 〈z1, z2, ..., zk〉 je podniz niza X ako postoji strogo rastuci niz 〈i1, i2, ..., il〉 indeksa X, takoda je za svako j=1,2,...,l u vaznosti xij = zj .

Primer 0.4. X = 〈A,B,C,B,D,A,B〉; Z = 〈B,C,D,B〉 je podniz niza X sa odgovarajucim indeksima 〈2, 3, 5, 7〉.Za dva niza X i Y niz Z je zajednicki podniz, ako je Z podniz od oba X i Y.

Primer 0.5. X = 〈A,B,C,B,D,A,B〉, Y = 〈B,D,C,A,B,A〉, niz Z = 〈B,C,A〉 je podniz i X i Y. 〈B,C,A〉 nijenajduzi zajednicki podniz, jer je niz 〈B,C,B,A〉 zajednicki i ima duzinu 4. Pri tome je 〈B,C,B,A〉 najduzi zajednickipodniz X i Y, jer ne postoji zajednicki podniz duzine 5 ili vise.

LCS problem. Dati su nizovi X = 〈x1, x2, ..., xm〉 i Y = 〈y1, y2, ..., yn〉. Naci najduzi zajednicki podniz Z nizovaX i Y. (Longest Common Subsequence problem)

Rekurzivno resenje problema

Cena je definisana kao duzina LCS od XiiYj : cdi, je =

0, za i = 0 ili j = 0cdi− 1, j − 1e+ 1, za i, j > 0, Xi = Yjmax(cdi, j − 1e, cdi− 1, je, i, j > 0, Xi 6= Yi)

Page 16: Algoritmi Skripta

Racunanje duzine LCS

LCS LENGTH (x , y )m <− l ength [ x ]n <− l ength [ y ]f o r i<− 1 to m

do c [ i , 0 ] <−0f o r i<−1 to m

do f o r j<−1 to ndo i f x i = yj

then c [ i , j ] <−c [ i −1, j−1]+1b [ i , j ] <− ”<−”

e l s e i f c [ i −1, j ]>=c [ i , j −1]then c [ i , j ] <− c [ i −1, j ]

b [ i , j ] <− ”<−”e l s e c [ i , j ] <− c [ i , j −1]

b [ i , j ] <−”<−”return c and b\end{ l s t i l i s t i n g }

\ subsubsec t ion {Konstrukc i ja LCS}\begin { l s t l i s t i n g }PRINT−LCS(b ,X, i , j )i f i=0 or j=0then returni f b [ i , j ]=”<−”then PRINT−LCS(b ,X, i −1, j−1)p r i n t Xie l s e i f b [ i , j ]=”<−”then PRINT−LCS(b ,X, i −1, j )e l s e PRINT−LCS (b ,X, i , j−1)

Optimalna triangulacija poligona

Dat je konveksan poligon P = 〈v0, v1, ..., vn−1〉 i tezinska funkcija w definisana na trouglovima formiranim stranama itetivama P. Problem je naci triangulaciju koja minimizira tezinu trouglova u triangulaciji. Primer tezine. ω(∆vivjvk) =|vivj | + | vjvk | + | vkvi |, gde je | vivj | Euklidovo rastojanje tacaka vi i vj .

Page 17: Algoritmi Skripta

Korespodencija sa postavljanjem zagrada

Struktura resenja

Triangulacija podpoligona mora biti optimalna, inace, mogli bismo poboljsati globalnu strukturu(triangulaciju). Jednaoptimalna triangulacija P u odnosu na tezinsku funkciju daje ”parsing” drvo za optimalno razmestanje zagrada primnozenju matrice A1A2...An. Obrnuto nije tacno.

Rekurzivno resenje

y =

{0, ako je i = jmint[i, k] + t[k + 1, j] + ω(∆vi−1vkvj), zai < j, i ≤ k ≤ j − 1

Optimalno binarno drvo za pretrazivanje

Ulaz: lista reci sa fiksnim verovatnocama pojavljivanja p1, p2, ..., pn. Problem: Aranzirati ove reci u binarno drvopretrazivanja tako da MINIMIZIRAMO ocekivano vreme pretrazivanja. Posto je broj poredjenja do pristupa elemntuna dubini d jednak d+1, treba minimizirati

∑i=1 npi(1 + di).

rec wi verovatnoca pi broj niz broj niz broj niza 0.22 2 0.44 3 0.66 2 0.44am 0.18 4 0.72 2 0.36 3 0.54and 0.20 3 0.60 3 0.60 1 0.20egg 0.05 4 0.20 1 0.05 3 0.15if 0.25 1 0.25 3 0.75 2 0.50the 0.02 3 0.06 2 0.04 4 0.08two 0.08 2 0.16 3 0.24 3 0.24

1.00 2.43 2.70 2.15

Page 18: Algoritmi Skripta

Cleft,right = min{pi + Cleft,i−1 + Ci+1,right +

i−1∑j=left

pj +

right∑j=i+1

pi} = min{Cleft,i−1 + Ci+1,right +

right∑j=left

pj}

0.19.9 Dijkstra algoritam. Najkraci put medju svim parovima vrhova grafa

Dk,i,j = min{Dk−1,i,j +Dk−1,i,k +Dk−1,k,j}D0,i,j = cij (vi, vj) /∈ Grane⇒ Dij = +∞D|v|,i,j je najkraci put izmedju vi i vj .Dk,i,j je najrkaci put izmedju vi i vj koji koristi samo vrhove v1, v2, ..., vk.

0.20 Minimizacija vremena cekanja procesa na jednom ili vise procesora.Greedy (nezasiti) algoritmi.

Postupak: Neki ”lokalni optimum” je izabran i kada se algoritam zavrsi ocekujemo da je lokalni optimum jednak”globalnom optimumu”. Ako apsolutno najbolji odgovor nije zahtevan, tada se greedy algoritam koristi za generisanjepribliznog odgovora. U slucaju da se trazi tacan odgovor, moramo koristiti komplikovanije algoritme. Svakodnevniprimeri:

1. Razmena banknote.

2. Traffic jam: da li uci u ulicu u kojoj vas mozda nakon kilometar cekuje zacepljenje ili se vratiti 5km nazad dabi se izbeglo zacepljenje.

3. Pravljenje rasporeda procesa na jednom ili vise procesora razmatramo detaljnije. U principu su problemi pravl-jenja rasporeda NP-kompletni.Dati su poslovi p1, p2, ..., pn, koji se zavrsavaju za vreme t1, t2, ..., tn respektivne.Imamo jedan procesor. Koji jenajbolji nacin da se rasproede ovi poslovi tako da je srednje vreme cekanja minimalno?

posao vremep1 15p2 8p3 3p4 10

Prosecno vreme tsr =15 + 23 + 26 + 36

4= 25

Prosecno vreme tsr =3 + 11 + 21 + 36

4= 17.75 optimalno.

Resenje problema. Aranziranje po najkracim vremenima cekanja uvek daje oprimalno resenje.

Dokaz 0.5. Raspored pi1, pi2, ..., pin. Prvi posao zavrsava u vremenu ti1. Drugi posao zavrsava u vremenu ti1 + ti2,treci ti1 + ti2 + ti3,...

C =

n∑k=1

(n−k+1)tik = (n+1)

n∑k=1

tik−n∑

k=1

ktik Ako je stavljeno x iza y uz tix < tiy, tada razmenom x i y smanjujemo

totalno vreme cekanja. Zbog toga je svaki raspored po rastucim vremenima SUBOPTIMALAN.

Vise procesora Slicno kao u slucaju jednog procesora dokazujemo da se optimalna cena postize ako prvom pro-cesoru damo proces sa najmanjim vremenom cekanja, drugom procesoru proces sa najmanjim vremenom cekanja upreostalim procesima, i tako ciklicno dok ne iscrpimo sve procese.

Page 19: Algoritmi Skripta

posao vremep1 3p2 5p3 6p4 10p5 11p6 14p7 15p8 18p9 20

Minimizacija konacnog vremena zavrsavanja Kada ce i poslednji proces zavrsiti? U primerima a i c vremezavrsavanja je i 40 i 38 respektivno. Ovaj problem ekvivalentan je problemu pakovanja ranca, pa je prema tomeNP-kompletan(tj. problem minimizacije konacnog vremena). U slucaju b minimalnog vremena izvrsavanja ne mozebiti poboljsan, jer su svi procesori uvek zauzeti.

0.21 Huffman-ovi kodovi. Huffman-ov algoritam.

Skup ASCII sastoji se od 100 printabilnih karaktera. dlog2100e = 7, pa je potrebno 7 bita za reprezentaciju. Posto je27=128, imamo i neke neprintabilne karaktere. Osmi bit je dodat za kontrolu parnosti.

Primer 0.6. Datoteka sadrzi a,e,i,s,t,space,new line.

Karakter Kod Frekvencija Broj bitovaa 000 10 30e 001 15 45i 010 12 36s 011 3 9t 100 4 12

space 101 3 39new line 110 1 3

total 174

Problem Zainteresovani smo za redukovanje duzine datoteke zbog prenosa telefonskom linijom ili zbog smanjenjavelicine prostora za zapis datoteke na disku. Je li moguce uvesti novi kod i tako smanjiti duzinu datoteke i ukupanbroj potrebnih bita? Odgovor Da! To je moguce i mozemo ustedeti i 25 odsto, a na velikim datotetkama i do 50 -60 odsto prostora.Opsta strategija je da se dozvoli da duzina koda varira od karaktera do karaktera i omoguciti da karakteri sa visokimfrekvencijom imaju kraci kod. Ako nam se svi karakteri pojavljuju sa istom frekvencijom, tada verovatno necemoimati velike ustede.

Page 20: Algoritmi Skripta

Predstavljanje koda drvetom

Grana levo znaci 0, a desno znaci 1. Npr. 010 predstavlja ”i”. Cena koja je∑difi, gde karakter ci ima dubinu di

i frekvenciju di. Jeftiniji je donji kod na slici. Kod kod kojeg su vrednosti samo u listovima naziva se PREFIKSNIKOD.Zadatak. Izracunati cenu kodova u gornja dva drveta.Primedba Optimalan kod je predstavljen potpunim drvetom, inace jednog potomka mozemo dici na visi nivo i takosmanjiti cenu.Ako su znaci samo na listovima drveta, tada svaka sekvenca moze biti kodirana na jedinstven nacin. Npr, pret-postavimo da je kodirani string 0100111100010110001000111, sledi da 0 nije znak, 01 nije nak, ali 010 predstavlja i,pa je prvi karakter i. Tada je 011 s, 11 je nl, a zatim a,sp,t,i,e,nl. Nijedan od znakova nije prefiks nekog drugog kodaznaka. Ako se karakteri pojavljuju i u cvorovima, tada dekodiranje nije jednoznacno.

Nas problem se svodi na nalazenje KOMPLETNOG BINARNOG DRVETA SA MINIMALNOM TOTALNOMCENOM, pri cemu se svi znakovi nalaze na listovima.

Optimalan prefiksni kodKarakter Kod Frekvencija Broj bitova

a 001 10 30e 01 15 30i 10 12 24s 00000 3 15t 0001 4 16

space 11 13 26new line 00001 1 5

total 146Razmenom dece u drvetu, mozemo dobiti razlicite optimalne kodove.

Huffman-ov algoritam Neka je C broj razlicitih znakova. Svaki znak predstavljamo drvetom i razmatramoSUMU drveta. Tezina drveta jednaka je zbiru frekvencija njegovih listova. C-1 puta izaberemo dva drveta T1 i T2sa najmanjom tezinom ( u slucaju jednakih tezina uzimamo proizvoljno) i formiramo novo drvo sa poddrvetima T1 iT2. Inicijalno (ulaz) je C suma od drveta sa jednim cvorom za svaki znak. Na kraju (izlaz) postoji jedinstveno drvo ito je OPTIMALNO HUFFMAN-ovo drvo kodiranja.

Page 21: Algoritmi Skripta
Page 22: Algoritmi Skripta

Ideje za dokaz korektnosti Huffman-ovog algoritma:

1. Drvo mora biti potpuno, inace mozemo jedan list podici na nivo za jedan visi i smanjiti cenu.

2. Dva najmanje frekventna karaktera αiβ moraju biti najdublji listovi. Dokaz kontradikcijom: Ako αiβ nisunajdublji listovi, tada to mora biti neko γ, jer je drvo kompletno. Swaping γsaαiβ smanjuje cenu drveta!

3. Dva lista iste duvine mogu zameniti mesta ne narusavajuci optimalnost.

4. Inicijalni korak je dobar.

5. Indukcija kod spajanja drveta. Dati detalje!

Pitanje. Zasto je ovaj algoritam ”hill climbing” (greedy)?Odgovor. U svakoj fazi mi izvodimo merge lokalno, bez obzira na globalno stanje.Pitanje. Oceniti slozenost algoritma.Odgovor.

1. Ako drveta drzimo na heap-u (priority queue) tada je T(c)=O(clogC), jer imamo izgradnju heap-a, 2c-2 brisanjamin i c-2 inserta.

2. Linked list priority queue daje T(c)=O(c2). Posto je u ASCII kodu C malo, kvadratna ocena je prihvatljiva.

Napomene.

1. Kodirana informacija mora biti transformisana na pocetak datoteke, inace je necemo moci dekodirat. To je slavoi skupo za male fajlove.

2. Algoritam ima dva prolaza. Prvi prolaz utvrdjuje frekvenciju podataka, a drugi kodira. Dvoprolaznost je skupaza velike fajlove.

0.22 Pravljenje rasporeda: minimizacija konacnog vremena cekanja. Prob-lem pakovanja ranca.

Neka su dati poslovi p1, p2, ..., pn sa vremenima izvrsavanja t1, t2, ..., tn retrospektivno. Treba naci raspored izvrsa-vanja poslova koji ce minimizirati neku zadatu funkciju. U ”Minimizacija vremena cekanja procesa na jednom ili viseprocesora. Greedy (nezasiti) algoritmi.” razmotrili smo i resili problem rasporeda za jednostavan problem minimizacijeprosecnog vremena cekanja.

U problemu minimizacije KONACNOG VREMENA IZVRSAVANJA trazi se raspored u kome ce vreme izvrsavanja iposlednjeg procesa biti minimalno(optimalno). Mada je po formulaciji poslednji problem slican prethodnom, pokazujese da je on zapravo mnogo tezi. Ovaj problem je NP-kompletan jer je ekvivalentan problemu pakovanja ranca. U”Minimizacija vremena cekanja procesa na jednom ili vise procesora. Greedy (nezasiti) algoritmi” dali smo ilustracijuproblema optimizacije konacnog vremena izvrsavanja za jedan specijalni slucaj.

Page 23: Algoritmi Skripta

NAPOMINJEMO da mi razmatramo NONPREEMPTIVNE RASPOREDE, tj. ako je neki posao pocet, tada seon izvrsava do kraja i to bez prekida. Umesto problema pakovanja ranca mi razmatramo ekvivalentan problempakovanja u bin-ove (kutije,korpe). Dacemo ”Greedy”(nezasicen) resenje problema pakovanja u bin-ove. ”Greedy”algoritmi su brzi, ali ne daju uvek optimalno resenje. Dokazujemo da nasa resenja nisu daleko od optimalnih.

Dato je n komada kapaciteta s1, s2, ..., sn. Svi komadi zadovoljavaju 0 < si < 1. PROBLEM PAKOVANJA UBINOVE je problem pakovanja svih komada u sto manji broj kutija(binova) kapaciteta 1.

Primer 0.7. s1 = 0.2, s2 = 0.5, s3 = 0.4, s4 = 0.7, s5 = 0.1, s6 = 0.3, s7 = 0.8

0.8

0.2

0.30.7

0.50.10.4

Razlikujemo on-line i off-line algoritme. ON-LINE problem trazi da svaki komad mora biti ubacen u kutiju prenego sto sledeci komad bude razmotren. U OFF-LINE problemima ne moramo raditi nista pre nego sto svi komadibudu ucitani.

0.23 ON-LINE algoritmi : primer pakovanja u binove.

Pokazujemo da ON-LINE algoritmi pakovanja u binove ne moze uvek dati odgovor koji je optimalan. Cak akomu dozvolimo neograniceno racunanje, on-line algoritam mora smestiti komad pre nego sto razmotri sledeci komad.Situaciju ilustrujemo sledecim primerom :

Primer 0.8. Neka su I1 = (i1||i1| = 12 − ε) , |I1| = m i I2 = (i2||i2| = 1

2 + ε) , |I2| = m, 0 < ε < 0.01. Neka jeI = I1 ∪ I2, gdje je ∪ operacija konkatenacije (dopisivanja)nizova.

1. Pretpostavimo da postoji optimalan algoritam A koji pakuje niz I optimalna u m kutija, tako da jedan binizgleda kao na slici.

12 + ε

12 − ε

2. Neka je J = I1. Niz J moze biti upakovan u [m2 ] kutija, ali ce sa optimalnim algoritmom A pakovati isto ako ipre niz I, dakle u m kutija.

Iz (1) i (2) sledi da ne postoji optimalan on-line algoritam za pakovanje u binove.

Dajemo sledecu kvantitativnu ocjenu.

Teorema 0.5.. Postoji ulaz koji forsira on-line algoritam pakovanja u binove da koristi najmanje 43 od optimalnog

broja binova.

Dokaz 0.6. Neka je Mε2N , a niz I kao u primeru 1. Pretpostavimo suprotno.

1. Nakon m komada A koristi b binova,a optimalno je m2 .

Na osnovu pretpostavke slijedi 2b < 43 i odatle 6b > 4m.

2. Nakon 2m komada svi su komadi upakovani. Svi binovi nakon b-tog sadrze najvise jedan komad, jer su svi 12 − ε

komadi upakovani u b-binova.⇒ Trebamo 2m− b binova vise ⇒ 2m−b

m < 43 ⇒ 6b > 4m. Zakljuci pod (1) i (2) su u kontradikciji i to dokazuje

tvrdnju.

POSTOJE TRI JEDNOSTAVNA ZA IMPLEMENTACIJU ALGORITMA KOJI GARANTUJU NE VISE OD2 ∗ (OPTIMALANBROJBINOV A) : ”NEXT FIT”, ”FIRST FIT”, ”BEST FIT”. Razmotrimo ih u sledecimpitanjima.

Page 24: Algoritmi Skripta

0.24 ”Next fit” pakovanje

NEXT FIT (SLEDECI ODGOVARAJUCI)

Algoritam: Komad se stavlja u istu kutiju kao i prethodni, a ako to nije moguce stavlja se u novoformiranu kutiju.

Teorema 0.6.. Neka je m optimalan broj kutija potrebnih ya pakovanje niza komada

Dokaz 0.7. Bj i Bj+1 sadrze komade sa zbirom vecim od 1-inace bi svi komadi iz njih stali u jedan bin. Primijenjenona sve parove susjednih binova daje dokaz, jer najvise pola prostora moze biti izgubljeno (nepopunjeno). �

Primer 0.9. I = (0.5, 2n , 0.5,

2n , ...)

0.50.5

B1 ...0.50.5

Bn4

2n

2n

2n

2n

Bn4 +1

0.25 ”Best fit” pakovanje

”Best fit” (najbolje smestanje)

Umesto stavljanja u prvi bin (kutiju,korpu,boks), trazi se bin u koji komad najbolje pasuje (”tesno pasuje”).

Primer 0.10. ”Best fit” za niz d0.2, 0.5, 0.4, 0.7, 0.1, 0.3, 0.8e

Prazan0.10.50.2

Prazan0.4

0.30.7

Prazan0.8

Bez dokaza navodimo da ”best fit” u najgorem slucaju trosi 1.7 od optimalnog broja binova.Jednostavan je za kodiranje ako trebamo 0(nlogn) vreme izvodjenja.

0.26 ”First fit” pakovanje

”First fit” (Prvi odgovarajuci)

”First fit” strategija skenira binove (kutije,korpe,boksove) i smesta novi komad u prvu pregradu (prvi bin) sa do-voljno mesta da se prihvati. Nova kutija se kreira samo ako prethodne kutije ne mogu da prihvate element.

Primer 0.11. ”First fit” za niz d 0.2,0.5,0.4,0.7,0.1,0.3,0.8 e

Prazan0.10.50.2

Prazan

0.30.4

Prazan

0.7

Prazan

0.8

Teorema 0.7.. Neka je m optimalan broj binova za pakovanje niza I.

1. Tada ”First fit” koristi manje ili jednako od d17

10me binova.

2. Postoji niz koji zahteva17

10(m-1) binova.

Page 25: Algoritmi Skripta

Dokaz 0.8. Ovde izostavljamo dokaz (1)(2) Za ilustraciju dajemo sledeci primer:

Neka u nizu I imamo

6m komada duzine 17 + ε

6m komada duzine 13 + ε

6m komada duzine 12 + ε.

Lako se vidi da optimalno imamo 6m binova, svaki za sve tri vrste elemenata. ”First fit” koristi 10m binova umesto 6m.

Prazno17 + ε17 + ε17 + ε17 + ε17 + ε17 + ε

Od B1 do Bm · · ·

Prazno

13 + ε

13 + ε

Od Bm+1 do B4m · · ·

Prazno

12 + ε

Od B4m+1 do B10m

Napomena Prakticna merenja pokazuju da u slucaju vrednosti uniformno rasporedjenih u intervalu d0, 1e, za ”firstfit” trebamo oko 2 posto vise binova.

0.27 Off-Line algoritmi : ”First fit decreasing”.

U off-line obradi korisno je elemente sortirati pre rasporedjivanja u binove. Za ”First fit” algoritam sortiramo uopadajucem(decreasing) poretku, a za ”best fit” zgodnije je sortirati elemente u rastucem (increasing) poretku.

Primer 0.12. ”First fit” za niz 〈0.8, 0.5, 0.4, 0.3, 0.2, 0.1〉

0.20.8 B1

0.30.7 B2

0.10.40.5

B3

Zelimo dokazati da ”first-fit” decreasing algoritam koristi najvise 4m+13 binova, ukoliko optimalno pakovanje koristi m

binova.

Lema 0.2. Neka n elemenata niza sortiranog u opadajucem poretku imaju duzine s1, ..., sn i pretpostavimo da seoptimalno mogu u m binova. Tada svi komadi koji se smestaju u dodatne binove po principu ”first fit” decreasingimaju duzinu manju ili jednaku 1

3 .

Dokaz 0.9. Dokazimo da za si element koji je prvi smjesten u m+1-om binu vazi |si| 5 13 .

Pretpostavimo da je | si |> 13 . Tada je svaki od s1, s2, ..., si−1 > 1

3 jer su sortirani u opadajucem poretku. Zbogtoga svaki od binova B1, ..., Bm imaju najvise dva elementa.Neka ∃BxiBy takvi da je 1 ≤ x<y ≤ m i neka su u Bx dva komada x1 i x2, a u By jedan komad y1. Tada(x1 ≥ y1 ∧ x2 ≥ si) ⇒ x1 + x2 ≥ y1 + si.Iz zakljucka implikacije sledi da si moze biti smesten u By, sto je suprotno pretpostavci.

⇒ Moramo imati prvo niz binova sa po jednim komadom, a zatim ide niz binova koji sadrze po dva komada. Nekaje prvih j, a drugih m-j. Neka su s1, ..., sj po jedan u binu, a sj+1, sj+2, ..., si−1 i m-j binova, po dva komada zajedno⇒ 2(m-j) je ukupan broj komada u tih m-j binova. ⇒ Ne mogu se svi elementi staviti u m binova, sto je kontradikcija.

Lema 0.3. Broj objekata u dodatnim binovima najvise moze biti m-1.

Dokaz 0.10. Pretpostavimo, suprotno tvrdnji, da u dodatnim binovima imamo ≥ m komada(elemenata niza). Postos eoptimalno svi elementi niza s1, ..., sn mogu smestiti u m binova, to je

∑ni=1 si ≤ m. Sa druge strane, ako oznacimo

si =

{wj , 1 ≤xi, ako se si nalazi u dodatnom binu(a ima ih najmanje m po pretpostavci)

imamo da je∑n

i=1 si ≥∑m

j=1 wj +∑m

j=1 xj ≥∑m

j=1(wj + xj)

⇒ wj + xj > 1, inace bi xj moglo biti smesteno u Bj . ⇒∑n

j=1 si >∑m

j=1 1 > m Kontradikcija! Time je lemadokazana.

Page 26: Algoritmi Skripta

Teorema 0.10.. Neka je m optimalan broj binova za pakovanje niza I elemenata s1, ..., sn.Tada ”first-fit” decreasing

ne treba vise od4m+ 1

3binova.

Dokaz 0.11. m-1 elemenata velicine koja je ≤ 13

⇒ treba ≤ dm−13 e ekstra binova. ⇒ Ukupan broj binova je najvise dm−13 e ≤m+13 e.

Teorema 0.11.. Neka je m optimalan broj binova potrebnih za pakovanje niza I=〈s1, s2, ..., sn〉

1. Tada ”first fit” decreasing ne koristi vise od 119 +m binova

2. Postoji niz koji za FFD trazi 119 m binova.

Dokaz 0.12. (2) I:12 + ε - 6m elemenata14 + 2ε - 6m elemenata14 + ε - 6m elemenata14 − 2ε - 12m elemenata

14 − 2ε

14 + 2ε

12 + ε

B1, ..., B6m

14 − 2ε

14 − 2ε

14 + 2ε

14 + 2ε

B6m+1, ..., B9m

Prazan

14 + 2ε

12 + ε

B1, ..., B6m

Prazan

14 + ε

14 + ε

14 + ε

B6m+1, ..., B8m

14 − 2ε

14 − 2ε

14 − 2ε

14 − 2ε

B8m+1, ..., B11m

0.28 Metoda ”Hill Climbins”. Problem prelaska pustinje dzipom

Algoritam ”Hill Climbins” daje neki ”lokalni optimum” za koji ocekujemo da je jednak ”globalnom optimumu”. Akoapsolutno najbolje resenje nije tacno, tada se ”hill climbins” koristi za generisanje pribliznog resenja.U slucaju da se trazi tacno resenje, tada ”hill clibinG” algoritam treba poboljsati do tacnog algoritma.

Primer 0.13. Pustinja je duga 1000km. Dzip trosi 1l benzina na 1km. Neka na pocetku pustinje postoji neogranicenakolicina goriva i neka je dozvoljeno praviti skladista goriva na proizvoljno izabranom mestu u pustinji. Naci minimalnukolicinu goriva potrebnu da dzip predje pustinju,ako dzip moze imati maksimalno 500l goriva.

Dokaz 0.13.

1. Neka dzip iz poslednjeg skladista A uzme dovoljnu kolicinu goriva za dolazak do kraja pustinje. Koristeci principoptimalnosti zakljucujemo da skladiste A mora sadrzati 500l benzina.

Page 27: Algoritmi Skripta

2. Skladiste A punimo koristeci skladiste B, udaljenosti xkm od skladista A. Da bi smo u A mogli uskladistiti 500lbenzina moramo imati u B(3x+500)l benzina. Zbog optimalnosti dzip u svakoj turi nosi maksimalnu kolicinu od

500l benzina. To nam daje jednacinu 3x+500=1000 za tacku B,pa sledi da je tako maksimizirano x=500

3.

3. Slicno za tacku C dobijamo 5y+1000=1500, odakle je y=500

5. Dalje je z=

500

7itd.

Konacno imamo:(500+x+y+z+...)=1000

(500+500

3+

500

5+

500

7+...)=1000

500(1+1

3+

1

5+

1

7+...)=1000 tj.

(1+1

3+

1

5+

1

7+ ...)=2

OPTIMALAN

Broj skladista i kolicinu benzina u njima odredjujemo iz broja clanova harmonijskog reda ciji zbir po prvi put pre-

masi 2,znaci (1 +1

3+

1

5+

1

7+

1

9+

1

11+

1

13). Nas dokaz optimalnosti je neuristicki. Formalan dokaz moze se izvesti

u teoriji lanaca Markova.

0.29 Metoda ”Backtracking”. Problem osam kraljica.

Ideju pretrazivanja sa vracanjem (backtrack) lako je objasniti na primeru izlaska iz lavirinta. Nas je cilj da iz nekogzadatog kvadrata dodjemo u drugi zadati kvadrat premestajuci se postepeno po kvadratima. Problem je u tome stou nekim kvadratima postoje pregrade koje onemogucuju prolaz.

Jedan od nacina prolaska kroz lavirint je kretanje od pocetnog kvadrata po sledeca dva pravila.

1. U svakom kvadratu izabrati jos neiskoristen put.

2. Ako iz kvadrata razmatranog u datom trenutku ne vode neiskoristeni putevi, tada se treba vratiti jedan koraknazad po zadnjem predjenom putu, po kojem smo usli u kvadrat.

Sustina pretrazivanja sa vracanjem sastoji se u tome da produzavamo put dok je moguce, a kada nije moguce, vratimose po putu i pokusamo drugi izbor po najblizem putu, ako takav izbor postoji.

Backtracking mozemo predstaviti drvetom pretrazivanja tako da cvor drveta predstavlja dato stanje, a grane drvetapredstavljaju korake iz datog stanja u sledeca stanja. Tada drvo pretrazujemo po putevima oznacenim isprekidanimlinijama. Na nekom nivou biramo resenja di uz pretpostavku da su d1d2...di−1 izabrani na prethodnim nivoima.Predstavnike koji ne odgovaraju odbacujemo, tj. podrezujemo drvo.

Page 28: Algoritmi Skripta

U najopstijem slucaju pretpostavljamo da se resenje sastoji od vektora (a1, a2, ..., an), konacne, ali nedefinisane duzine,koji zadovoljava dodatna resenja. Pri tome je svako ai iz nekog linearno odredjenog skupa Ai. Na taj nacin pri iscrp-nom istrazivanju mozemo razmotriti sve elemente skupa. A1 ×A2 ×Ai,i=0,1,2,... kao moguca resenja.

Za polazno resenje biramo prazan vektor () i na osnovu postojecih ogranicenja nalazimo elemente iz A1 koji sukandidati za a1. Oznacicemo taj skup sa S1. Za a1 uzimamo najmanji elemenat iz S1. Rezultat je parcijalno resenje(a1).Uopste razlicita ogranicenja koja opisuju resenja, govore nam iz kojeg skupa Sk ⊆ Ak uzimamo kandidate ak zaparcijalno resenje (a1, a2, ..., ak−1).Ako parcijalno resenje (a1, a2, ..., ak−1) ne mozemo rasiriti dodavanjem elementa ak, tada je sk = ∅. U tom slucaju sevracamo i biramo novi element ak−1. Ako ni izabrani ak−1 ni izabrani Sk−1 ne daju mogucnost rasirenja, vracamo sejos jedan korak nazad i biramo element ak−2 ∈ Sk−2 i td.

Primenjujemo opisanu metodu na resavanje problema osam kraljica. U tom problemu treba na sahovsku tablu dimen-zije n× n postaviti sto vise kraljica tako da ni jedna ne tuce drugu.Posto kraljica napada sva polja u koloni(stupcu),u redu i na dijagonali na kojoj se nalazi, jasno je da mozemo postavitinajvise n kraljica koje jedna drugu ne napadaju. Problem se svodi na :

1. Postavljanje kraljica na ploci tako da jedna drugu ne napadaju.

2. Ako resenje postoji, onda naci ukupan broj resenja.

U svakom stupcu moze se nalaziti tacno jedna kraljica, a to znaci da resenje mozemo predstaviti vektorom (a1, a2, ..., an)u kojem je ai broj reda kraljice iz stupca i.

U svakom redu moze postojati tacno jedna kraljica pa i 6= j ⇒ ai 6= aj . Kraljice ne smeju jedna drugu napa-dati po dijagonali i zbog toga moramo imati |ai − aj | 6= |i− j| za i 6= j.

Da bi smo u ovom problemu dodali ak u (a1, a2, ..., ak−1) jednostavno poredimo ak sa svakim ai, i < k. Uvek jeSn+1 = ∅ za plocu n× n. Ilustrujmo i slikom backtrack na ploci 8× 8.

U nasem resenju zadatka nismo pokusali da nadjemo((

n2

n

))nacina na koje se n kraljica moze postaviti na plocu

n× n (oko 4.4 ∗ 109 za n=8).Druga ideja mogla je koristiti cinjenicu da svaka kolona sadrzi najvise jednu kraljicu, sto bi dalo nn mogucih polozajaza istrazivanje (za n=8 oko 1.7 ∗ 107). Ako primetimo da nikoje dve kraljice ne mogu biti u jednom redu, to znaci davektor (a1, ..., an) mora biti permutacija (1,...,n) sto daje n! mogucnosti (za n=8 oko 4.0 ∗ 104 mogucnosti).Na kraju, posto dve kraljice ne mogu biti na jednoj dijagonali, broj mogucnosti se skracuje jos vise (za n=8 na oko2056 mogucnosti sto je racunarski prihvatljivo).

Page 29: Algoritmi Skripta

Proces skracivanja u problemu sa kraljicama mozemo produziti i dalje. Dva resenja mozemo smatrati ekvivalent-nim ako se jedan od njih prevodi u drugo pomocu niza rotacija i/ili simetrija.Ako utvrdimo postojanje kraljice u cosku table, tada ta kraljica napada sve ostale coskove. Zbog toga nema resenja ukojem je kraljica postavljena u vise nego jednom cosku. Ako je nadjeno resenje u kojem je kraljica na polju (1,1) tadaono moze biti prevedeno rotacijama i/ili simetrijama u ekvivalentno resenje u kojem je polje (1,1) prazno. Uopste,ako nadjemo sva neekvivalentna resenja tada mozemo konstruisati i sva ostala resenja.

Sledece usavrsavanje odnosi se na spajanje grana drveta. Ako primetimo da su dva poddrveta izomorfna, dovoljno jerazmotriti samo jedno od njih.

Metoda preuredjenja drveta korisna je u slucaju u kojem neka resenja imaju slican izgled. Drvo mozemo preureditida pre svega pretrazimo takva resenja.

Metod dekompozicije je razbijanje problema na niz problema uz moguce koristenje metoda rekurzije i/ili dinam-ickog programiranja. Resenje problema komponuje se od resenja podproblema.

Za implementaciju nasega algoritma kljucna je procedura u kojoj ispitujemo u kojem retku k-tog stupca stojikraljica. U grubim crtama ta procedura izgleda na sledeci nacin :

b o l l f l a g=true ;i n t i=1 ;whi l e ( i<k & & f l a g ){ i f ( a=a k ) | | ( | a i−a k |= | i−k | ) then f l a g=f a l s e ;i=i+1 ;}

Uz koristenje ove procedure program trosenja resenja u problemu n kraljica mozemo skicirati na sledeci nacin :

s 1 =1;k=1;whi l e k>1{ whi le s k <=n{a k<=s k ;s k=s k +1;whi l e ( s k<=n && k r a l j i c a ne moze b i t i u redu s k stupca k ){ s k=s k+1} ;i f k=n then z a p i s a t ie ( a 1 , . . . , a n ) }k=k+1;s k =1;whi l e ( s k<= && k r a l j i c a ne moze b i t i u redu s k stupca k ){ s k=s k+1}}k=k−1;}

U ovom programu umesto citavog skupa sk cuva se samo minimalan element sk. Provera uslova Sk 6= ∅ odgovarauslovu sk ≤ n. Posto sn+1 nije manje od n+1 to je sn+1 uvek prazan skup.

Dajemo za ilustraciju jos dva detaljna resenja problema n kraljica. Ideje ovih resenja razlikuju se u nekoj meri odideja za resavanje koje smo mi prethodno izlozili. Drugo resenje dato je prema ideji N. Wirth-a. Programi su testiranina TURBO C++, v.6.0 i daju resenja za n¡70.

/∗ Pocetak prvog programa ∗/

i n t n ; // za nxn tab lu .i n t f l a g ;void pr intArray ( i n t a [ ] ) ; // za stampanje konacnog r e s e n j avoid s e t P o s i t i o n ( i n t a [ ] , i n t n 1 , i n t 2 ) ; // rekurz ivna f u n k c i j ai n t main ( ){i n t ∗a ;i n t c t r =0;

Page 30: Algoritmi Skripta

p r i n t f (”\n problem n k r a l j i c a ” ) ;p r i n t f (”\n Broj redova za nxn tab lu ” ) ;s can f (”%d , &n ) ;a=( i n t ∗) ( mal loc ( s i z e o f ( i n t )∗n ) ) ;p r i n t f (”\n U svakom r e s e n j u su koord inate i−te k r a l j i c e date sa (Red , Kolona ) ) ;p r i n t f (” \n Svi su redov i i ko lone numerisani od 1 do n ” ) ;f o r ( c t r =0; ctr<n ; c t r++)g e t P o s i t i o n s ( a , 0 , c t r ) ;getchar ( ) ;getchar ( ) ;}

void pr intArray ( i n t a [ ] ){i n t i , cho i c e ;s t a t i c . i n t counter =0;counter++;p r i n t f (” \n RESENJE #%d” , counter ) ;f o r ( i =0; i<n ; i++)p r i n t f (”(%d,%d )” , i +1, a [ i ]+1) ;i f ( counter%10==0){p r i n t f (” \n Ubes i te 0 za kraj , jedan za nastavak ” ) ;s can f (”%d , &cho i c e ) ;i f ( cho i c e==0) e x i t ( 0 ) ;} ;}void g e t P o s i t i o n s ( i n t a 1 [ ] , i n t colno , i n t va l ){i n t ctr1 , c t r 2 ;a 1 [ co lno ]= va l ;i f [ co lno]==n−1{ pr in t fAr ray ( a 1 ) ; r e turn ;} ;f o r ( c t r 1 =0; ctr1<n ; ){ /∗ ova p e t l j a n a l a z i odgovarajuce bro j eve kolona u sledecem redu ∗/f o r ( c t r 2 =0; ctr<=colno ; c t r 2++)i f ( a 1 [ c t r 2 ]==ct r1 | | ( co lno+1−c t r2 )∗ ( co lno+1−c t r2 )==(ctr1−a 1 [ c t r 2 ]∗( ctr1−a 1 [ c t r 2 ] ) )goto miss1 ;g e t P o s i t i o n s ( a 1 , co lno +1, c t r1 ) ;miss1 ;c t r 1++;}}/∗ KRAJ PROGRAMA ∗/

Program za n kraljica koji umesto rekurzije koristi dva steka. Stekovi su implementirani pomocunizova (arrays).

#inc lude <s t d i o . h>#inc lude <s t d l i b . h>#inc lude <time . h>

typede f s t r u c t { i n t x , y ;} p o s i t i o n ;

void SolveProblem ( i n t n ) ;i n t n=0;void main ( ){ p r i n t f (”\n Unes i te d imenzi ju n za tab lu nxn : ” ) ;s can f (”%d”,&n ) ;p r i n t f (”\n U svakom od r e s e n j a koord inate n−te k r a l j i c e su date sa (Red , Kolona ) ” ) ;p r i n t f (”\n Redovi i ko lone su numerisani od 1 do n :\n ” ) ;SolveProblem (n ) ;

Page 31: Algoritmi Skripta

getchar ( ) ;}void SolveProblem ( i n t n){

i n t counter1 , counter2=−1,counter3=−1;s t a t i c i n t counter −0, cho i c e ;i n t d [ 1 0 0 ] [ 3 ] = { 0 } ;i n t ∗ s tack2 ;p o s i t i o n Pos i t ion1 , Pos i t ion2 , Pos i t i on3 ;p o s i t i o n ∗head−( p o s i t i o n ∗) mal loc (n∗n∗ s i z e o f ( p o s i t i o n ) ) ;s tack2=( i n t ∗) mal loc (n∗ s i z e o f ( i n t ) ) ;f o r ( counter1=n−1; counter1>=0;counter1−−){

Pos i t i on1 . x=0;Pos i t i on1 . y=counter1 ;head1[++counter2 ]= Pos i t i on1

} ;

wh i l e ( counter2>=0) {Pos i t i on1=head1 [ counter2 −−];wh i l e ( counter3>=0 && Pos i t i on1 . x<=counter3 ) {Pos i t i on2 . x=counter3 ;Pos i t i on2 . y=stack2 [ counter3 −−];d [ Pos i t i on2 . y ] [ 0 ] = 0 ;d [ Pos i t i on2 . x+ Pos i t i on2 . y ] [ 1 ] = 0 ;d [ Pos i t i on2 . x− Pos i t i on2 . y+n ] [ 2 ] = 0 ; } ;s tack2[++ counter3 ]= Pos i t i on1 . y ;d [ Pos i t i on1 . y ] [ 0 ] = 1 ;d [ Pos i t i on1 . x+ Pos i t i on1 . y ] [ 1 ] = 1 ;d [ Pos i t i on1 . x− Pos i t i on1 . y+n ] [ 2 ] = 1 ;i f ( counter3==(n−1)){

counter++ ;p r i n t f (”\n SOLUTION #%d : ” , counter ) ;f o r (” counter1 =0; counter1<=counter3 ; counter1++”)p r i n t f (”(%d,%d )” , counter1 +1, s tack2 [ counter1 ]+1) ;i f ( counter%10==0){ p r i n t f (”\n Enter1 to continue , 0 to Exit ” ) ;s can f (”%d” , & cho i c e ) ;i f ( cho i c e==0)e x i t ( 0 ) ;} ;

Po s i t i on2 . x=counter3 ;Pos i t i on2 . y=stack2 [ counter3 −−];d [ Pos i t i on2 . y ] [ 0 ] = 0 ;d [ Pos i t i on2 . x+ Pos i t i on2 . y ] [ 1 ] = 0 ;d [ Pos i t i on2 . x− Pos i t i on2 . y+n ] [ 2 ] = 0 ; }e l s e { f o r ( counter1=n−1; counter1>=0;counter1−−)i f (d [ counter1 ] [0]==0 && d [ Pos i t i on1 . x+counter1 ] [1]==0

&& d [ n+Pos i t i on1 . x+1−counter1 ] [2]==0){Pos i t i on3 . x=Pos i t i on1 . x+1;Pos i t i on3 . y=counter1 ;head1[++counter2 ]= Pos i t i on3 ;} ;

}getchar ( ) ;getchar ( ) ;r e turn0 ;}

Problem kraljica. Koliki je maksimalan broj kraljica koje se mogu postaviti na sahovsku plocu n × n tako da”nikoje dve” ne tuku jedna drugu? Odgovor : n kraljica.Broj nacina na koje se n kraljica mogu postaviti na plocu n × n da ne tuku jedna drugu je (1,0,0,2,10,4,40,92,...) za

Page 32: Algoritmi Skripta

n=1,2,3,4,5,6,7,8,...Na slici je dato 12 neekvivalentnih resenja za n=8. Od njih se rotacijama i simetrijama dobijaju svih 92 resenja.

Na datoj slici je minimalan broj kraljica da zauzimaju ili tuku sva polja ploce 8× 8.

Page 33: Algoritmi Skripta

0.30 Dodatak A.

0.30.1 Heap sort (sort drvetom)

template <c l a s s T>void heap i fy (T∗a , i n t k , i n t n){ T t= a [ k ] ;whi l e (k<n/2){ i n t j =2∗k+i ; // pretvara j u n a j s t a r i j e g potomka ki f ( j+1<n && a [ j ]<a [ j +1]) ++j ;i f ( t>a [ j ] ) break ;a [ k]=a [ j ] ;k=j ;}a [ k]= t ;}template <c l a s s T>void s o r t (T∗a , i n t n){ f o r ( i n t i=n/2−1; i>=0; i−−)heap i fy ( a , i , n ) ;f o r ( i=n−1; i >0; i−−){swap ( a [ 0 ] , a [ i ] ) ;// I n v a r i j a n t a : e l ement i a [ i : n−1] su u korektnom poretkuheap i fy ( a , o , i ) ;// I n v a r i j a n t a : podniz a [ o : n−1] j e heap}}template <c l a s s T>void swap (T&x , T&y ){T temp=x ;x=y ;y=temp ;}

0.30.2 Dinamicke strukture

Tipicna implementacija dinamickog skupa:Svaki element je predstavljen nekim objektom, a polja tog objekta mogu biti posecena i manipulisana pomocu pokazi-vaca na objekat.Razlikujemo:KEY (kljuc)Satelitski podaci //nisu koristeni u implementacijiOperacijeQueries(upitne, selektorske) operacijeModifikatorske operacijeSearch(S,k) // vraca key[x]=k ili NILInsert(S,x)Delete(S,x)Minimum(S) //vraca minimum SMaximum(S)Successor(S,x) //NIL ili neposredno veci od xPredecessor(S,x) //NIL ili manji od xDictionary(recnik)< S,Insert, Delete, Membership >Stack (Stek), LIFO propertyS [1...top [S]] , S [1] -bottom, S [to] - vrhtop [S]=0 emptyunderflow, overflow

Page 34: Algoritmi Skripta

STACK−EMPTY(S)i f top [ S]=0then return TRUEe l s e re turn FALSEPUSH(S , x )top [ S]<−top [ S]+1S [ top [ S]]<−xPOP(S)i f STACK−EMPTY(S)then e r r o r ” underf low ”e l s e top [ S]<−top [ S]−1return S [ top [ S ]+1]

Red(Queue), FIFO propertyENQUEUE (Insert)DEQUEUE (Delete)

Enqueue ( a , x )a [ t a i l [ a]]<−xi f t a i l [ a]= length [ a ]then t a i l [ a ] <−1e l s e t a i l [ a ] <− t a i l [ a ]+1Dequeue ( a )x<−a [ head [ a ] ]i f head [ a]= length [ a ]then head [ a ] <−1e l s e head [ a ] <−head [ a ]+1return x

0.30.3 Linkovane liste

Linearno uredjeni objekti - dvostruko povezana lista

• next, prev

Page 35: Algoritmi Skripta

• next[x], prev[x]

• prev[x]=NIL, head[L]=NIL

-jednostruko povezana lista: prev, nesortirana, cirkularna lista.

LIST − SEARCH (L , x )x<−head [ L ]whi l e x< >NIL and key [ x]<>kdo x<−next [ x ]r e turn x

T(n)=O(n) u najgorem slucaju (worst case)

LIST− INSERT(L , x ) , LIST − DELETE (L , x )LIST INSERT(L , x )next [ x]<−head [ L ]i f head [ L]< >NILthen prev [ head [ L]]<−xhead [ L]<−xprev [ L]<−NILLIST− DELETE (L , x )i f prev [ x]< >NILthen next [ prev [ x]]<−next [ x ]e l s e head [ L]<−next [ x ]i f next [ x]< >NILthen prev [ next [ x]]<−prev [ x ]

T(n)=O(n) in worst case.

0.30.4 Sentineli

LIST−DELETE (L , x )next [ prev [ x]]<−next [ x ]prex [ next [ x]]<−prev [ x ]

SENTINEL je uvedeni emenet da olaksa rad sa granicnim vrednostima.

Primer 0.14. nil[L] za NIL

Page 36: Algoritmi Skripta

LIST − SEARCH’x<−next [ n i l [ L ] ]whi l e x< >n i l [ L ] and key [ x]< >kdo x<−next [ x ]r e turn xLIST − INSERT (L , x )next [ x ] <−next [ n i l [ L ] ]prev [ next [ n i l [ L ] ] ] <−xnext [ n i l [ L ] ] <−xprev [ x ] <−n i l [ L ]

0.30.5 Implementacija pointera i objekata matricom

0.30.6 Implementacija pointera jednodimenzionalnim nizom

Page 37: Algoritmi Skripta

0.30.7 Alociranje i oslobadjanje elemenata.

Garbage collector-i vode racuna o neiskoristenim lokacijama.

Page 38: Algoritmi Skripta

Free objekti u jednostruko povezanoj listi, SLOBODNA LISTA. Samo next, head u free.Slobodna lista je stek.

T(n)=O(1)

ALLOCATE OBJECT ( )i f f r e e = NILthen e r r o r ” out o f space ”e l s e x<−f r e ef r e e<−next [ x ]r e turn xFREE OBJECT( x )next ( x ) <− f r e ef r e e<−x

Page 39: Algoritmi Skripta

0.30.8 Binarno drvo

p , l e f t , r i g h tp [ x]=NIL − x j e koren ( root )root [T]=NIL − prazno drvo

0.30.9 Neograniceno grananje

left-child, rightsibling representation

1 l e f t −c h i l d [ x ]pokazuje na naj−l evo dete od x2 r ight− s i b l i n g [ x ]pokazuje na rodjaka neposredno sa desne s t ranel e f t −c h i l d [ x]=NIL nema dece xr ight−s i b l i n g [ x]=NIL <= rightmost c h i l d r o d i t e l j a

levi-desni

Page 40: Algoritmi Skripta

child1,...,child kNije pogodna reprezentacija za beskonacno grananje!Druge reprezentacije:

1. Heap sa 1 array i indeksom.

2. Za drveta koja prolazimo samo prema korenu treba samo pokazivac na roditelja.

0.30.10 Hes-tabele

INSERT, SEARCH, DELETE1. Tabele sa direktnim adresiranjemKey ∈ U = {0, ...,m− 1}Svaka dva elementa imaju razlicite kljuceve.Array(niz) = Direct - address tableT do�m− 1ePozicija ili slot odgovara jednom kljucu iz univerzum U.

U = d0, 1, ..., 9eK = d2, 3, 5, 8e

DIRECT−ADDRESS−SEARCH (T, k )re turn T[ k ]DIRECT−ADDRESS−INSERT(T, x )T[ key [ x ] ] <− xDIRECT−ADDRESS−DELETE (T, x )T[ key [ x ] ] <−NIL

2. Hes tabeleDirektnim adresiranjem element sa kljucem k stavlja se u slot k Hesiranjem se on stavlja u h(k) gde je h kes funkcijakoja racuna slot za k.h= U {0, 1, ...,m− 1}k hesira slot h(k)h(k) je hes vrednost od k

Page 41: Algoritmi Skripta

k2 i k5 h e s i r a j u se u i s t i s l o tKOLIZIJA

h - mora biti deterministicka| U | > mIako dobro dizajnirana random funkcija moze minimizirati broj kolizija, mi trebamo neki metod za resavanje kolizija.

0.30.11 Resavanje kolizija uvezivanjem

h(k1)=h(k4) i h(k5)=h(k2)=h(k7)

CHAINED − HASH − INSERT (T, x )I n s e r t x o f the head o f l i s t T[ h( key [ x ] ) ]CHAINED − HASH − SEARCH (T, k )Trazi jedan element sa kljucem k u l i s t i T[ h [ k ] ]CHAINED − HASH − DELETE (T, x )Delete x i z l i s t e T[ h [ key [ x ] ] ]

Page 42: Algoritmi Skripta

Analiza hashing za ulancavanjen elemenatam slotovad= n

m faktor opterecenja <,>,= 1

Worst-case je neprihvatljivo.Lista+hashingfunkcija (racun) ∼ O(n)Awerage-caseProsto uniformno hesiranjelength(T [j]) = nj , j = 0, ...,m− 1n = n0 + ...+ nm−1E[nj ] = α = n/msrednja vrednost nj .Neka h(k) mozemo izracunati u O(1) vremenu i pristupiti slotu h(k) ⇒ pretrazivanje zavisi lineatno od duzine nh(k)liste Tdhdkee

1. Nijedan element tabele nema kljuc k

2. Pretrazivanje uspesno nalazi element sa kljucem k

Teorema 0.13.. U hes tabeli, u kojoj su kolizije resene uvezivanjem , neuspesno pretrazivanje zahteva T=O(1+α) uzpretpostavku uniformnog hesiranja.

Dokaz 0.14. Ocekivano vreme je duzina liste Tdhdkee, a ta ima duzinu E[nh(k)] = d. Broj ispitivanih elemenata jeα→ T = (1 + α).

Teorema 0.14.. U hes tabeli, u kojoj se kolizije resavaju uvezivanjem, uspesno pretrazivanje, u srednjem, zahtevaO(1 + α) vreme, uz pretpostavku uniformnog hesiranja.

Dokaz 0.15. ki = keydxie, i = 1, 2, ..., nXij = I{h(ki) = h(kj)} = 1

m ⇒ EdXije = 1m

Ocekivani broj ispitanih elemenata jeEd 1n

∑ni=1(1 +

∑nj=i+1Xij)e

= 1n

∑ni=1(1 +

∑nj=i+1Edije)

= 1n

∑ni=1(1 +

∑nj=i+1

1m )

= 1 + 1nm

∑ni=1(n− i)

= 1 + 1nm (

∑ni=1 n−

∑ni=1 i)

= 1 + 1nm (n2 − n(n+ 1)

2)

= 1 +n− 1

2m

= 1 + d2 −

d2n

=⇒ T = Θ(2 + d2 −

d2n ) = Θ(1 + α)

0.30.12 Hes funkcije

Heuristicke:hashing deljenjem i hashing mnozenjemStohasticke: univerzalno hesiranjeUniformno hesiranje:Svaki kljuc je podjednako moguce hesirati u bilo koji slot od m, nezavisno od toga gde su hesirani drugi kljucevi.Teskoce

1. Ne znamo distribuciji verovatnoca sa kojima ce kljucevi biti izvuceni.

2. Kljucevi mogu biti vuceni u zavisnosti jedan od drugog.

Ponekad znamo distribucije: kljuveci su k slucajnih brojeva nezavisno i uniformno distribuirani u 0 ≤ k < 1⇒ h(k) =bkmc zadovoljava uslov prostog uniformnog hesiranja. Praksa:

1. pt i pts slati u razlicite slotove,

Page 43: Algoritmi Skripta

2. zahtevaju se ponekad ostriji uslovi: daleke vrednosti hesirati u bliske slotove.

Kljucevi kao prirodni brojeviU = N = {0, 1, 2, ...} Ako nisu, interpretiramo ih tako.

Primer 0.15. pt=(112,116), (112*128)+116=14452 (ceo broj u osnovi 128)

Metod deljenja.h(k)=k mod m

Primer 0.16. m=12, k=100, h(k)=4⇒ mora biti m 6= 2p, jer je h(k)=p najnizih bitova.Bolje je napraviti hes funkciju zavisnu od svih bitova!m = 2p − 1 je los izbor, jer permutovanje znakova k(interpretirano u radix 2p) ne menja slot. Dokazati!Prost broj daleko od 2p je dobar izbor.

Primer 0.17. Uvezivanje za kolizije n=2000 stringova znakova (char ima 8 bitova). Nije nam problem pretrazivati usrednjem 3 elementa.⇒ m=701, h(k)=kmod701, gde je k integer!701=2001/3 je ”daleko” od 2n!

Metod mnozenja.

1. k mnozimo konstantom A, 0 < A < 1 i uzimamo funkcijski deo od kA

2. mnozimo sa m i uzimamo floor kao rezultat

⇒ h(k)= bm(kAmod1)c,sa kA mod1 ≡ kA-bkAc

Tipicno, m nije kritican, pa uzimamo m=2p, p ∈ Z, jer je implementacija na kompjuteru jednostavnija.

1. Duzina reci masine je w bita.

2. k staje u jednu rec.

3. A je decimalni deo od s2w , 0 < s < 2w.

Rezultat je r12w + r0.

4. Uzimamo p bitova najvece tezine u r0.

D.Knuth sugerise: A ≈√

5− 1

2= 0.6180339887.

Page 44: Algoritmi Skripta

Primer 0.18. k=123456, p=14, m=214=16384, w=32.

A decimalni deo s232 najblize

√5− 1

2

⇒ A= 2654435769232

k · s= 327706022297664 = (76300 ·232) + 17612864

i r1=76300, r0=17612864 ⇒ h(k)=67.

0.30.13 Univerzalno hesiranje

Da ne bi svi kljucevi bili kesirani u isti slot, treba izabrati SLUCAJNO hes funckiju. To je UNIVERZALNO HESIR-ANJE, ako je funkcija izabrana nezavisno od vrednosti kljuceva.Poredjenje sa Quick-sortom. Izbor hes funkcije iz unapred pazljivo dizajniranog skupa funkcija.H - konacna kolekcija hes funkcija.h: U → {0, 1, ...,m− 1}Univerzalna kolekcija akko ∀k, l ∈ U , broj h ∈ H za koje je h(k)=h(l) najvise H

m , tj. sanse da bude kolizija h(k) ih(l) su ≤ 1

m . Pri tome su h(k) i h(l) nezavisno i slucajno izabrani iz {0, 1, ...,m− 1}.

Teorema 0.15.. Neka je h izabrana iz univerzalne kolekcije H hes funkcija. h se koristi za hesiranje n kljuceva utabelu T duzine m, sa uvezivanjem za razresavanje kolizija.Ako k nije u tabeli, tada je ocekivana duzina Ednh(k)e liste u koju se hesira k, najvise α.Ako je k u T, tada je ocekivana duzina Ednh(k)e liste sa kljucem k najvise 1+α.

Dokaz 0.16. Za ∀k, l definisemo Xkl = I{h(k) = h(l)}k,l kolidiraju sa verovatnocom ≤ 1

m .→ Pr{h(k) = h(l)} ≤ 1

m ⇒ EdXkle ≤ 1m .

Definisemo za ∀k

Yk =∑l∈Tl 6=k

Xkl

⇒ EdYke = Ed∑l∈Tl 6=k

Xkle =∑l∈Tl 6=k

EdXkle ≤∑l∈Tl 6=k

1

m

• k /∈ T ⇒ nh(k) = Yk i

| {k | l ∈ T&l 6= k} |= n→ Ednh(k)e = EdYke ≤ n

m = α

• k ∈ T&k ∈ T dh(k)e& k nije u racunu Yk

→ nh(k) = Yk + 1∧ | {l | l ∈ T&l 6= k} |= n− 1

→ Ednh(k)e = EdYke+ 1 ≤ n− 1

m+ 1= 1 + α− 1

m < 1 + α.

Korolar.Koristenje univerzalnog hesiranja i resavanja kolizija uvezivanjem u tabeli sa m slota, zahteva T=Θ(n) za bilo kojusekvencu od n INSERT, SEARCH, DELETE operacija od kojih su njih Θ(m) INSERT.

Dokaz 0.17. | Ins |= O(m)⇒ n = O(m)⇒ α = O(1)INSERT, DELETE trebaju O(1) vreme, a takodje i SEARCH. Zbog linearnosti E za citavu sekvencu (niz) treba T=O(n)koraka.

0.30.14 Otvoreno adresiranje

Svi elementi su u samoj hes tabeli, tj. svaki unos sadrzi ili element ili NIL. Kada trazimo element, pretrazujemo samotabelu dok ne nadjemo element ili dok ne bude jasno da tabela ne sadrzi element. Tabela moze biti popunjena do kraja

Page 45: Algoritmi Skripta

bez mogucnosti daljeg unosa. ”Load faktor” (faktor popunjenosti) nikada ne moze biti veci od 1.Umesto pointera racunamo(sledimo) nizove slotova koje treba ispitati. Memorija koju bi koristili pointeri daje vecibroj slotova, potencijalno vodeci ka smanjenju kolizija i brzem pretrazivanju.INSERTh: Ux {0, 1, ...,m− 1} → {0, 1, ...,m− 1} zahtevamo:probni niz h(k,0), h(k,1),...,h(k,m-1) je permutacija {0, 1, ...,m− 1}.

HASH−INSERT(T, k )i <− 0repeat j <− h(k , i )

i f T[ j ]=NILthen T[ j ] <− k

return je l s e i <− i+1

u n t i l i=me r r o r ”hash t a b l e over f l ow ”

HASH−SEARCH (T, k )i <− 0repeat j <− h(k , i )

i f T[ j ]=kthen return ji <− i+1

u n t i l T[ j ]=NIL or i=mreturn NIL

DELETE ce imati poteskoca ako stavimo NIL u izbrisani slot i. Necemo moci izbrisati element za koji je upostavljanju i nadjen kao popunjen. Izlaz iz problema: umesto NIL stavimo DELETE.

0.30.15 Uniformno hesiranje

Za svaki element probni niz ima jednaku verovatnocu da bude jedan od m! permutacija. Tacno uniformno hesiranjeje tesko za implementaciju.Umesto pravog UH koristimo i dvostruko hesiranje, linearnu probu, kvadratnu probu.

Linearna proba.h′ : U → {0, 1, ...,m− 1} neka je pomocna hes funkcija. Linearna proba koristi h(k,i)=(h’(k)+i) mod m.Samo je m razlicitih probnih nizova odredjeno sa h(k,0).JEDNOSTAVNA JE IMPLEMENTACIJA, ali imamo PROBLEM:primarno klasterovanje! To nam povecava AWERAGE TIME.

CLUSTER: iza i popunjenih, verovatnoca popunjavanja slota i+1 da bude sledeci popunjen jei+ 1

m- KLAS-

TEROVANJE.

Kvadratna proba.

h(k, i) = (h′(k) + c1i+ c2i2)modm

Dvostruko hesiranje.Kod kvadratne probe h(k1, 0) = h(k2, 0) ⇒ h(k1, i) = h(k2, i), tzv. sekundarno klasterovanje, tj. k1 i k2 imaju istenizove.Zbog toga uvodimo dvostruko hesiranje h(k, i) = (h1(k) +h2(k)), pri cemu h2(k) mora biti relativno prost sa duzinomtable.

Primer 0.19. h1(k) = kmod 13h2(k) = 1 + (kmod 11)Za vezbu ubaciti 79,69,98,72,14,50.