19.04.2013 Views

Strukture podataka i algoritmi - Pmf

Strukture podataka i algoritmi - Pmf

Strukture podataka i algoritmi - Pmf

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Sveu ili te u Zagrebu<br />

PMF Matemati ki odjel<br />

<strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong><br />

Poglavlje 6 -- Algoritmi<br />

Zvonimir Bujanovi<br />

Igor Jelaska<br />

Krunoslav Pulji<br />

6.1. Divide and conquer<br />

Imamo po etni problem X.<br />

Metoda divide-and-conquer je primjenjiva ako:<br />

X se mo e podijeliti na niz manjih potproblema A, B, C, ...<br />

svaki od potproblema A, B, C... je problem istog tipa kao problem<br />

X<br />

potproblemi A, B, C... su disjunktni ili imaju vrlo maleni presjek<br />

rje enje cijelog problema X mogu e je dobiti spajanjem rje enja<br />

potproblema A, B, C...<br />

postupak rastavljanja na potprobleme i spajanja se mo e<br />

efikasno izvesti<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 3<br />

Oblikovanje algoritama<br />

obradit emo 4 pristupa rje avanju problema, tj. 4 tipa<br />

algoritama:<br />

pohlepni pristup (greedy)<br />

divide and conquer (podijeli pa vladaj)<br />

dinami ko programiranje<br />

backtracking<br />

generalno, svaki problem tra i neki svoj pristup, ne mo emo<br />

sve algoritme svrstati u ove 4 kategorije<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 2<br />

Primjer QuickSort<br />

dana je lista L=(a 1 , a 2 , ..., a n ) koju treba sortirati.<br />

promotrimo sljede u ideju za sortiranje:<br />

premjestimo sve elemente liste koji su manji od a 1 lijevo od a 1 , a<br />

sve elemente koji su ve i ili jednaki desno od a 1<br />

element a 1 je sada na svom ispravnom mjestu u sortiranoj listi<br />

neka je L 1 lista elemenata lijevo od a 1 , a L 2 lista elemenata<br />

desno od a 1<br />

ponovimo (rekurzivno!) ovaj isti postupak na listama L 1 i L 2<br />

dobili smo sortiranu polaznu listu<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 4


Primjer QuickSort<br />

po etni problem X = sortiranje liste L<br />

potproblemi:<br />

A = sortiranje liste L 1<br />

B = sortiranje liste L 2<br />

spajanje rezultata od A i B trivijalno<br />

klju no u algoritmu:<br />

efikasno izvesti podjelu na potprobleme!<br />

(tj. efikasno dovesti pivotni element a 1 na kona no mjesto)<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 5<br />

Primjer QuickSort<br />

L = (26, 5, 27, 1, 61, 11, 59, 15, 48, 19) po etna pozicija<br />

l<br />

Kursor l se pomi e do prvog broja ve eg od 26:<br />

L = (26, 5, 27, 1, 61, 11, 59, 15, 48, 19)<br />

l<br />

Kursor r se pomi e do prvog broja manjeg od 26 (ne mi e se!):<br />

L = (26, 5, 27, 1, 61, 11, 59, 15, 48, 19)<br />

l<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 7<br />

r<br />

r<br />

r<br />

Primjer QuickSort<br />

Dovo enje pivotnog elementa na pravo mjesto.<br />

Primjer: L = (26, 5, 27, 1, 61, 11, 59, 15, 48, 19)<br />

Pivotni element a 1 = 26<br />

Postavimo dva kursora:<br />

kursor l kre e od druge pozicije u listi i ide prema desno sve<br />

dok ne nai e na element koji je ve i od a 1<br />

kursor r kre e od zadnje pozicije u listi i ide prema lijevo sve<br />

dok ne nai e na element koji je manji od a 1<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 6<br />

Primjer QuickSort<br />

Elementi na kojima su kursori stali se zamijene:<br />

L = (26, 5, 19, 1, 61, 11, 59, 15, 48, 27)<br />

l<br />

Kursori se nastavljaju pomicati po istoj logici...<br />

L = (26, 5, 19, 1, 61, 11, 59, 15, 48, 27)<br />

l<br />

...sve dok se ne "prekri e":<br />

L = (26, 5, 19, 1, 15, 11, 59, 61, 48, 27)<br />

l<br />

r<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 8<br />

r<br />

r


Primjer QuickSort<br />

Kada se prekri e, zamijenimo pivotni element sa onim iznad r:<br />

L = (26, 5, 19, 1, 15, 11, 59, 61, 48, 27)<br />

Sada je pivotni element na pravom mjestu!<br />

L = (11, 5, 19, 1, 15, 26, 59, 61, 48, 27)<br />

L 1 L2<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 9<br />

}<br />

QuickSort Algoritam<br />

...<br />

while( l = end ) return;<br />

while( l


Zadatak 6.1.<br />

(11, 5, 19, 1, 15) 26 [59, 61, 48, 27] (0..4)<br />

l r<br />

(11, 5, 1, 19, 15) 26 [59, 61, 48, 27] (0..4)<br />

l r<br />

(1, 5) 11 [19, 15] 26 [59, 61, 48, 27] (0..1)<br />

l r<br />

(1, 5) 11 [19, 15] 26 [59, 61, 48, 27] (0..1)<br />

l r<br />

1, 5, 11 (19, 15) 26 [59, 61, 48, 27] (3..4)<br />

l r<br />

1, 5, 11 (19, 15) 26 [59, 61, 48, 27] (3..4)<br />

l r<br />

1, 5, 11, 15, 19, 26 (59, 61, 48, 27) (6..9)<br />

l r<br />

1, 5, 11, 15, 19, 26 (59, 27, 48, 61) (6..9)<br />

l r<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 13<br />

Sortiranje silazno?<br />

to ako trebamo silazno sortirati listu?<br />

Umjesto , koristimo relaciju ure aja .<br />

BST:<br />

a<br />

>a<br />

a<br />

Hrpa: roditelj je od djece.<br />

9<br />

5 3<br />

4 1<br />

QuickSort: l ide udesno sve dok ne nai e na<br />

manjeg od pivotnog elementa, a<br />

sve dok ne nai e na ve eg.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 15<br />

Zadatak 6.1.<br />

1, 5, 11, 15, 19, 26 (48, 27) 59, 61 (6..7)<br />

l r<br />

1, 5, 11, 15, 19, 26 (48, 27) 59, 61 (6..7)<br />

l r<br />

1, 5, 11, 15, 19, 26, 27, 48, 59, 61<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 14<br />

Zadatak 6.2. (DZ)<br />

Sortirajte silazno listu L=(5, 3, 8, 10, 4, 6, 7, 4, 2) pomo u:<br />

(a) hrpe;<br />

(b) binarnog stabla tra enja;<br />

(c) QuickSort algoritma.<br />

Listu ne smijete prvo sortirati uzlazno!<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 16


Primjer mno enje matrica<br />

Dane su matrice A i B reda N. elimo to efikasnije izra unati<br />

C= A + B.<br />

Klasi ni algoritam: c ij = k = 1..N a ik b kj<br />

Za svaki c ij treba N zbrajanja i mno enja ukupno O( N 3 )<br />

Divide-and-conquer ideja: pretp. N=2k ; podijelimo matrice A i B<br />

na (N/2) x (N/2) podmatrice:<br />

A11 A12 B11 B12 C11 C12 =<br />

A21 A22 B21 B22 C21 C22 22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 17<br />

Primjer mno enje matrica<br />

Strassenovo mno enje: 7 mno enja i 10 zbrajanja<br />

P = ( A11 + A22 ) ( B11 + B22 ) T( N ) = T( 2<br />

Q = ( A21 + A22 ) B11 R = A11 ( B12 B22 )<br />

S = A22 ( B21 B11 )<br />

T = ( A11 + A12 ) B22 U = ( A21 A11 ) ( B11 + B12 )<br />

V = ( A12 A22 ) ( B21 + B22 )<br />

k )<br />

= 7 * T( 2k-1 )<br />

= 7k * T( 1 )<br />

= 7k = 2k * a<br />

= N a<br />

a = log2 7 2.807 < 3<br />

C 11 = P + S T + V; C 12 = R + T;<br />

C 21 = Q + S; C 22 = P Q + R + U.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 19<br />

Primjer mno enje matrica<br />

Slijedi:<br />

C 11 = A 11 B 11 + A 12 B 21<br />

C 12 = A 11 B 12 + A 12 B 22<br />

C 21 = A 21 B 11 + A 22 B 21<br />

C 22 = A 21 B 12 + A 22 B 22<br />

Ukupno: 8 mno enja i 4 zbrajanja matrica reda N/2.<br />

T( p ) = broj mno enja dvaju brojeva kod mno enja matrica reda p<br />

T( N ) = 8 * T( N / 2 );<br />

T( 1 ) = 1<br />

Slijedi: T( N ) = T( 2 k ) = 8 * T( 2 k-1 ) = ... = 8 k T( 1 ) = N 3 .<br />

Ovim nismo pobolj ali slo enost.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 18<br />

Zadatak 6.3. (DZ * * * )<br />

Dane su koordinate N to aka u ravnini. Potrebno je prona i kolika<br />

je udaljenost izme u dvije najbli e to ke.<br />

(a) Napi ite o iti algoritam koji izra unava udaljenost izme u<br />

svake dvije to ke. Uvjerite se da je njegova slo enost O( N 2 ).<br />

(b) Koriste i divide-and-conquer pristup, osmislite (ili na ite na<br />

Internetu) algoritam koji tra enu udaljenost izra unava u<br />

slo enosti boljoj od O( N 2 ). [mo e se napraviti algoritam koji radi<br />

u O( N log 2 N ). ]<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 20


6.2. Dinami ko programiranje<br />

Imamo po etni problem X.<br />

Metoda dinami kog programiranja je primjenjiva ako:<br />

X se mo e podijeliti na niz manjih potproblema A, B, C, ...<br />

svaki od potproblema A, B, C... je problem istog tipa kao problem<br />

X<br />

rje enje cijelog problema X mogu e je dobiti spajanjem rje enja<br />

potproblema A, B, C...<br />

potproblemi A, B, C... nisu nu no disjunktni (mogu imati i veliki<br />

presjek), ali ukupan broj razli itih potproblema koji se javljaju<br />

prilikom rekurzivnog dijeljenja na potprobleme je malen (tj.<br />

rje enja svih potproblema odjednom stanu u memoriju)<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 21<br />

Zadatak 6.4.<br />

Rje enje. Prethodni algoritam je VRLO spor: za ra unanje npr. 33<br />

povrh 16 mu treba preko 30 sekundi (Core2Duo @ 1.83MHz)<br />

Problem velik broj puta pozove rekurziju sa jednim te istim<br />

parametrima (usporedi sa Fibonnacijevim brojevima iz Prog(C)!)<br />

Uo i: kod ra unanja "n povrh m" treba nam ukupno manje od nm<br />

razli itih vrijednosti oblika "i povrh j"!<br />

Stoga ih sve mo emo pamtiti u tablici i u rekurziju i i samo ako<br />

neki par jo nismo izra unali.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 23<br />

Zadatak 6.4.<br />

Razradite algoritam za ra unanje "n povrh m" pomo u dinami kog<br />

programiranja.<br />

Rje enje. Uvijek je potrebno prvo napisati rekurzivnu formulu<br />

kojim se problem svodi na manje potprobleme.<br />

n n n n-1 n-1<br />

=1 =1 = +<br />

0 n m m-1 m<br />

int povrh( int n, int m )<br />

{<br />

if( m == 0 || n == m ) return 1;<br />

}<br />

return povrh( n-1, m-1 ) + povrh( n-1, m );<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 22<br />

Rje enje. Top-down pristup:<br />

Zadatak 6.4.<br />

// ako je POVRH[n][m]==0, jos nije izracunat<br />

int POVRH[MAXN][MAXM] = { 0 };<br />

int povrh( int n, int m )<br />

{<br />

if( POVRH[n][m] != 0 ) return POVRH[n][m];<br />

if( m == 0 || n == m ) return POVRH[n][m] = 1;<br />

}<br />

POVRH[n][m] = povrh( n-1, m-1 ) + povrh( n-1, m );<br />

return POVRH[n][m];<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 24


Zadatak 6.4.<br />

Rje enje. Bottom-up pristup redak po redak punimo tablicu<br />

(Pascalov trokut!):<br />

int POVRH[MAXN][MAXM] = { 0 };<br />

int povrh( int n, int m ) // pretp. n >= m<br />

{<br />

int i, j;<br />

}<br />

for( i = 0; i


2<br />

8<br />

Zadatak 6.5. rje enje<br />

2<br />

0 1 2<br />

3<br />

0 1 2<br />

0 0 8 5<br />

D (0) = 1 3 0 8<br />

2 2 0<br />

5<br />

0 1 2<br />

0 0 8 5<br />

D (1) = 1 3 0 8<br />

2 5 2 0<br />

0 1 2<br />

0 0 8 5<br />

D (-1) = 1 3 0<br />

2 2 0<br />

0 1 2<br />

0 0 7 5<br />

D (2) = D = 1 3 0 8<br />

2 5 2 0<br />

Ovo je Floydov algoritam za nala enje svih najkra ih puteva u<br />

grafu. Slo enost: O( n 3 ). Bottom-up pristup je ovdje bolji.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 29<br />

Zadatak 6.5. rje enje<br />

5 1 7<br />

to ako osim duljine treba na i i sam put?<br />

Dovoljno je zapamtiti samo neki vor u najkra em putu od u do v:<br />

P[ u ][ v ] = k, ako je k neki vrh na najkra em od u do v<br />

P[ u ][ v ] = -1, ako je najkra i put od u do v ujedno i brid od u do v<br />

U primjeru gore (npr.):<br />

P[ 5 ][ 2 ] = 3; (put = [5 ... 3 ... 2])<br />

P[ 5 ][ 3 ] = 1; (put = [5 ... 1 ... 3 ... 2])<br />

P[ 5 ][ 1 ] = -1; (put = [5 1 ... 3 ... 2])<br />

3 2<br />

P[ 1 ][ 3 ] = 7; (put = [5 1 ... 7 ... 3 ... 2])<br />

P[ 1 ][ 7 ] = -1; (put = [5 1 7 ... 3 ... 2])<br />

P[ 7 ][ 3 ] = -1; (put = [5 1 7 3 ... 2])<br />

P[ 3 ][ 2 ] = -1; (put = [5 1 7 3 2])<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 31<br />

Zadatak 6.5. rje enje<br />

#define INFTY ... // neki veliki broj<br />

#define n ... // broj vrhova grafa<br />

void floyd( float A[n][n], float D[n][n] )<br />

{<br />

int u, v, k;<br />

}<br />

for( u = 0; u < n; ++u )<br />

for( v = 0; v < n; ++v )<br />

D[u][v] = ( u == v ) ? 0 : A[u][v];<br />

for( k = 0; k < n; ++k )<br />

for( u = 0; u < n; ++u )<br />

for( v = 0; v < n; ++v )<br />

if( D[u][k] + D[k][v] < D[u][v] )<br />

D[u][v] = D[u][k] + D[k][v];<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 30<br />

Zadatak 6.5. rje enje<br />

#define INFTY ... // neki veliki broj<br />

#define n ... // broj vrhova grafa<br />

void floydPamtiPut( float A[n][n], float D[n][n] )<br />

{<br />

... // (pocetak isti kao prije)<br />

for( u = 0; u < n; ++u )<br />

for( v = 0; v < n; ++v )<br />

P[u][v] = -1;<br />

}<br />

for( k = 0; k < n; ++k )<br />

for( u = 0; u < n; ++u )<br />

for( v = 0; v < n; ++v )<br />

if( D[u][k] + D[k][v] < D[u][v] ) {<br />

D[u][v] = D[u][k] + D[k][v];<br />

P[u][v] = k;<br />

}<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 32


6.3. Pohlepni pristup (greedy)<br />

Kod pohlepnog pristupa promatramo to nam je u danom trenutku najbolje<br />

("lokalno optimalno") u initi.<br />

Pohlepni <strong>algoritmi</strong> vrlo esto ne daju optimalno rje enje, ali mogu dati<br />

solidnu aproksimaciju.<br />

Primjer. Potrebno je isplatiti iznos od 62kn koriste i to je mogu e manji broj<br />

nov anica od 50, 20, 10, 5, 2 i 1kn.<br />

to je najbolje napraviti u prvom koraku? Iskoristiti najve u nov anicu<br />

50kn.<br />

Preostaje isplatiti 12kn opet iskoristimo najve u 10kn.<br />

Preostaje isplatiti 2kn iskoristimo najve u 2kn.<br />

Isplatili smo cijeli iznos koriste i 3 nov anice; lako se vidi da je to optimalno.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 33<br />

Zadatak 6.6. (DZ)<br />

Dan je broj N, te N nov anica u apoenima A[0], A[1], ..., A[N-1].<br />

Koriste i dinami ko programiranje napi ite funkciju koja kao<br />

parametar prima iznos koji treba isplatiti koriste i dane apoene, a<br />

vra a minimalan broj nov anica.<br />

Uputa. Neka je<br />

P( n, k ) = min. broj nov anica potreban da se isplati iznos od k<br />

kuna koriste i nov anice A[0], A[1], ..., A[n].<br />

Poka ite da vrijedi:<br />

P( n, k ) = min { P( n-1, k ), 1 + P( n, k A[n] ) }<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 35<br />

6.3. Pohlepni pristup (greedy)<br />

Primjer. Mo e se pokazati da pohlepni pristup funkcionira za svaki iznos<br />

kojeg treba isplatiti (ako koristimo standardni skup nov anica).<br />

to ako treba isplatiti 14kn pomo u nov anica od 8, 5 i 2kn?<br />

to ako treba isplatiti 14kn pomo u nov anica od 8, 5, 2 i 0.01kn?<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 34<br />

Zadatak 6.7.<br />

Problem trgova kog putnika:<br />

Trgova ki putnik eli posjetiti niz gradova i vratiti se u polazni. Ako<br />

znamo vrijeme putovanja izme u svaka dva grada, kako napraviti<br />

plan putovanja tako da svaki grad (osim polaznog) posjeti to no<br />

jednom i da ukupno vrijeme putovanja bude najmanje mogu e?<br />

Udaljenost dviju to aka<br />

ra unamo kao euklidsku<br />

udaljenost tih to aka u<br />

ravnini.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 36


Matrica udaljenosti:<br />

Zadatak 6.7. rje enje<br />

duljina = 50 duljina = 48.39<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 37<br />

Na po etku je T prazan graf sa<br />

vrhovima a, b, c, d, e, f.<br />

Dodajemo najkra i brid to je (d, e)<br />

duljine 3.<br />

Sada je E = { (d, e) }.<br />

Zadatak 6.7. rje enje<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 39<br />

Zadatak 6.7. rje enje<br />

Ovaj problem je NP-te ak (ne postoji polinomijalni algoritam koji ga egzaktno<br />

rje ava).<br />

Opisujemo pribli ni, pohlepni algoritam.<br />

Rje enje spremamo u graf T=( V, E ), V = vrhovi, E = bridovi.<br />

Na po etku: T = ( V, O). Neka E g= skup svih bridova u polaznom grafu.<br />

Algoritam:<br />

Ponavljaj n puta (n = broj gradova)<br />

odaberi i dodaj u skup E najkra i brid b iz skupa E g \ E sa ovim svojstvima:<br />

(a) brid b ne e prouzro iti da se u T neki vrh bude stupnja 3 ili ve eg<br />

(b) brid b ne e zatvoriti ciklus u T, osim ako se u E ve ne nalazi n-1 bridova<br />

i ako b ne spaja jedina 2 vrha stupnja 1.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 38<br />

Zadatak 6.7. rje enje<br />

Dodajemo najkra i brid koji zadovoljava<br />

(a) i (b) to je (b, c) ili (a, b) ili (e, f), svi<br />

duljine 5.<br />

Vidimo da ih sve mo emo dodati u bilo<br />

kojem redoslijedu u graf.<br />

Sada je E = { (d, e), (b, c), (a, b), (e, f) }.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 40


Zadatak 6.7. rje enje<br />

Idu najkra i brid kojeg poku avamo<br />

dodati je (a, c) duljine 7.08.<br />

Ali on bi zatvorio ciklus, tj. naru io (b).<br />

Idu i najkra i je (d, f) opet ciklus, pa<br />

ne dodajemo ni njega.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 41<br />

Zadatak 6.7. rje enje<br />

Dobili smo rje enje ukupne duljine 50, to nije optimalno.<br />

DZ: Napi ite program koji u itava koordinate N to aka u ravnini i koriste i<br />

gore opisani algoritam nalazi aproksimaciju optimalne duljine puta<br />

trgova kog putnika koji obilazi sve u itane to ke.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 43<br />

Zadatak 6.7. rje enje<br />

Idu i najkra i brid kojeg poku avamo<br />

dodati je (c, d) duljine 14.<br />

On zadovoljava (a) i (b), pa ga dodamo.<br />

Od svih preostalih bridova, jedino (a, f)<br />

zadovoljava (a) i (b).<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 42<br />

Zadatak 6.8.<br />

Mirko je dobio na dar okoladu sa m x n "kockica". On je jako praznovjeran i<br />

prije no to ju pojede, mora ju izlomiti na dijelove koji su kvadrati (tj. oblika k<br />

x k kockica). Lomljenje jednog dijela je zapravo podjela na dva manja dijela<br />

koji imaju zajedni ku stranicu:<br />

U gornjem primjeru 3 x 5 okoladu smo 3 puta lomili da bismo dobili<br />

kvadratne dijelove. Mirko eli to je mogu e prije po eti jesti okoladu, pa ga<br />

zanima koliko je najmanje lomljenja potrebno.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 44


Zadatak 6.8.<br />

(a) Neka je P( m, n ) minimalni broj lomljenja okolade sa m x n "kockica"<br />

na kvadratne dijelove. Izvedite rekurzivnu formulu za P( m, n ).<br />

(b) Koriste i dinami ko programiranje i (a), napi ite funkciju koja prima m i<br />

n i vra a minimalni broj lomljenja potreban da se dobiju kvadratni<br />

dijelovi.<br />

(c) Osmislite i opi ite odgovaraju i pohlepni algoritam. Poka ite primjerom<br />

da on ne daje optimalni broj lomljenja.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 45<br />

Zadatak 6.8. rje enje<br />

(a) Trebamo problem P( m, n ) svesti na manje potprobleme.<br />

Kako sve mo emo prelomiti m x n okoladu?<br />

"Lom" mo e biti nakon 1. retka ili nakon 2. retka... ili nakon (m-1)-retka.<br />

"Lom" mo e biti nakon 1. stupca ili nakon 2. stupca... ili nakon (n-1)-stupca.<br />

Ako prelomimo nakon i-tog retka, ukupan broj lomova je:<br />

P( i, n ) + P( m - i, n ) + 1<br />

jer su ostala dva dijela dimenzija i x n i (m - i) x n koje dalje treba lomiti.<br />

Tra imo optimalno mjesto za lom:<br />

P( m, n ) = 0, ako je m = n<br />

P( m, n ) = min { min i { P( i, n ) + P( m - i, n ) + 1 },<br />

min j { P( m, j ) + P ( m, n - j ) + 1 } }<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 47<br />

Zadatak 6.8. rje enje<br />

(c) Ako je m > n, odlomimo kvadrat dimenzija n x n (ostane (m-n) x n).<br />

Ako je n > m, odlomimo kvadrat dimenzije m x m (ostane m x (n-m)).<br />

Ina e je m = n, pa ve imamo kvadrat.<br />

int greedy( int m, int n ) {<br />

int brojLomova = 0;<br />

}<br />

while( m != n ) {<br />

if( m >= n ) { ++brojLomova; m = m n; }<br />

else if( n >= m ) { ++brojLomova; n = n m; }<br />

}<br />

return brojLomova;<br />

Nije optimalno (hint: pogledajte 5 x 6 okoladu!)<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 46<br />

Zadatak 6.8. rje enje<br />

(b) Koristimo formulu iz (a) i top-down pristup; pamtimo izra unato u polju.<br />

int P[MAXM][MAXN]; // treba staviti sve elemente na -1<br />

int coko( int m, int n ) {<br />

int i, mini = INFTY;<br />

}<br />

if( P[m][n] != -1 ) return P[m][n];<br />

if( m == n ) return P[m][n] = 0;<br />

for( i = 1; i < n; ++i )<br />

if( coko( m, i ) + coko( m, n-i ) + 1 < mini )<br />

mini = coko( m, i ) + coko( m, n-i ) + 1;<br />

for( i = 1; i < m; ++i )<br />

if( coko( i, n ) + coko( m-i, n ) + 1 < mini )<br />

mini = coko( i, n ) + coko( m-i, n ) + 1;<br />

return P[m][n] = mini;<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 48


6.4. Backtracking<br />

backtracking = "ispitivanje svih mogu ih slu ajeva / kombinacija"<br />

Primjenjiv kod te kih kombinatornih problema kod kojih ne uspijemo<br />

konstruirati efikasniji algoritam (npr. problem trgova ki putnik).<br />

Zamislimo da je tra eno rje enje oblika (x1, x2, ..., xn), gdje je xi Si, a Si neki kona an skup.<br />

Skup S = S1 x S2 x ... Sn zovemo prostor rje enja; tra imo njegov element<br />

koji je optimalan u nekom smislu.<br />

Neki elementi od S mo da ne zadovoljavaju dodatna ograni enja koje na e<br />

rje enje treba imati, pa njih niti ne uzimamo u obzir.<br />

U idu em primjeru: x 1 { 1, 2, 3 }, x 2 { 5, 7 }, x 3 { 3, 4 }.<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 49<br />

Zadatak 6.9.<br />

Napi ite program koji u itava brojeve b, a 0 , a 1 , ..., a n-1 . Program<br />

treba provjeriti mo e li se broj b dobiti kao rezultat izraza<br />

dobivenog umetanjem operacija + i izme u brojeva a 0 , ..., a n-1 (u<br />

tom poretku).<br />

Na primjer, ako je b = 5, a 0 = 6, a 1 = 2, a 2 = 4 i a 3 = 3, onda<br />

program treba ispisati "Mo e" (jer je 5 = 6 2 + 4 3).<br />

Rje enje.<br />

x 0 = znak izme u a 0 i a 1 (plus ili minus)<br />

x 1 = znak izme u a 1 i a 2 (plus ili minus)<br />

...<br />

x n 2 = znak izme u a n-2 i a n-1 (plus ili minus)<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 51<br />

6.4. Backtracking<br />

Prostor rje enja obilazimo rekurzivno postupak mo emo prikazati kao da<br />

gradimo stablo rje enja: ( vorovi "nastaju" u preorder redoslijedu)<br />

x 1 = 1 x 1 = 2 x 1 = 3<br />

x 2 = 5 x 2 = 7 x 2 = 5 x 2 = 7 x 2 = 5 x 2 = 7<br />

x 3 = 3 x 3 = 4 x 3 = 3 x 3 = 4<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 50<br />

6.4. Backtracking<br />

Stablo rje enja (n = 4). U listovima treba provjeriti je li izraz jednak x.<br />

x 0 = + x 0 = -<br />

x 1 = + x 1 = - x 1 = + x 1 = -<br />

x 2 = + x 2 = - x 2 = + x 2 = - x 2 = + x 2 = - x 2 = + x 2 = -<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 52


int b, n, a[100];<br />

char x[100];<br />

int rek( int dubina );<br />

int main( void )<br />

{<br />

int i;<br />

scanf( "%d", &b );<br />

scanf( "%d", &n );<br />

for( i = 0; i < n; ++i )<br />

scanf( "%d", &a[i] );<br />

}<br />

Zadatak 6.9. rje enje<br />

if( rek( 0 ) == 1 )<br />

printf( "Moze.\n" );<br />

else<br />

printf( "Ne moze.\n" );<br />

int suma( void )<br />

{<br />

int rez = a[0], i;<br />

for( i=0; i


Stablo rje enja (4 x 4 plo a):<br />

Zadatak 6.10. rje enje<br />

22.1.2008 <strong>Strukture</strong> <strong>podataka</strong> i <strong>algoritmi</strong> - vje be 57<br />

Zadatak 6.10. rje enje<br />

int ploca[9][9] = {0}; // 0 = prazno, 1 = ima kraljica<br />

void queens( int stupac ) // stupac = dubina<br />

{<br />

if( kraljice_se_napadaju() ) return;<br />

if( stupac == 9 ) { // napunili smo plocu<br />

ispis_ploce(); // a ne napadaju se!<br />

return; // znaci, imamo rjesenje<br />

}<br />

for( red = 1; red

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!