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