Está en la página 1de 25

RAUNALNITVO IN INFORMACIJSKE TEHNOLOGIJE

ALGORITMI IN PODATKOVNE STRUKTURE


NIKOLA GUID

Fakulteta za elektrotehniko, raunalnitvo in informatiko Maribor, 2011

Kazalo

9 Porena metoda 9.1 Splona metoda . . . . . . . . 9.2 Preprosti problem nahrbtnika 9.3 Primov algoritem . . . . . . . 9.4 Dijkstrin algoritem . . . . . . 9.5 Bellman-Fordov algoritem . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

. . . . .

9-1 9-1 9-2 9-4 9-9 9-18

Poglavje

Porena metoda
Porena metoda (greedy method ) je gotovo najbolj neposredna metoda nartovanja, ki jo obravnavamo. Veina problemov, ki jih reujemo s to metodo, ima n vhodov in zahteva od nas, da doloimo podmnoico, ki izpolnjuje doloene omejitve. Kakrnikoli podmnoici, ki izpolnjuje doloene omejitve, pravimo dopustna reitev (feasible solution ). Zahtevamo, da poiemo tako dopustno reitev, ki bodisi minimizira bodisi maksimizira dano kriterijsko funkcijo (objective function ). Dopustna reitev, ki optimizira kriterijsko funkcijo, je optimalna reitev (optimal solution ).

9.1

Splona metoda

Pri strategiji porena metoda reitev gradimo postopoma. Na tekoem koraku poiemo element, ki prinese najve h kriterijski funkciji. Sprejmemo ga samo, e s tem elementom razirjena mnoica ostane dopustna. Poreno metodo lahko opiemo z naslednjim psevdokodom: POZRESNA(n, a, resitev ) 1 resitev 0 2 for i 1 to n 3 do x izberi(n, a, resitev ) % Izberi naslednji element, ki e ni % v reitvi in pride na vrsto % po kriteriju optimalnosti. 4 if dopustna(x, resitev ) 5 then resitev resitev x % e je tekoi element dopusten x, ga vkljuimo % v celotno reitev. Oblika procedur izberi in dopustna je odvisna od zgleda.

9.2 Preprosti problem nahrbtnika

9-2

9.2

Preprosti problem nahrbtnika

Na razpolago imamo n predmetov. Za vsak predmet i (i = 1, 2, . . . , n) poznamo njegovo prostornino v [i] (0 < v [i] V ). Poznamo tudi vrednost predmeta c[i] (c[i] > 0). Predpostavimo, da predmete lahko poljubno reemo. x[i] naj predstavlja del predmeta i, ki ga odreemo in damo v nahrbtnik (0 x[i] 1). V nahrbtnik s prostornino V elimo vstaviti delee predmetov, tako da je izraz
n i=1

c[i]x[i]

(9.1)

maksimalen pri pogojih

n i=1

v [i]x[i] V.

(9.2)

Dopustna reitev je kakrnakoli mnoica (x[1], . . . , x[n]), ki izpolnjuje pogoj 9.2. Optimalna reitev je dopustna reitev, pri kateri ima izraz 9.1 maksimalno vrednost. Nahrbtnik bo dosegel maksimalno vrednost, e bomo v nahrbtnik vlagali najprej predmete, ki imajo najvejo vrednost glede na prostornino. To pomeni, da moramo urediti predmete po relativni vrednosti c[i]/v [i], tako da velja: c[i + 1] c[i] , v [i] v [i + 1] i = 1, 2, . . . , n 1 (9.3)

V zaetku v nahrbtnik vlagamo cele predmete. Praviloma moramo odrezati samo zadnji predmet, ki ga e damo v nahrbtnik. Delovanje procedure kae naslednji psevdokod: PREPROSTI-NAHRBTNIK(V, n,v,c,x) 1 for i 1 to n 2 do x[i] 0 % inicializiraj vrednosti x[i] 3 yV % y je prostor, ki je e na voljo 4 for i 1 to n 5 do if v [i] > y % ali je reitev dopustna? 6 then exit(for) 7 else x[i] 1 8 y y v [i] 9 if i n 10 then x[i] y/v [i] % dele predmeta, ki napolni nahrbtnik Iz procedure vidimo, da reitev x gradimo postopoma. Najprej doloimo vrednost x[1], nato x[2], itd.

9.2 Preprosti problem nahrbtnika

9-3

Zgled 9.1. Imejmo tri predmete z naslednjimi vrednostmi: c = [10 14 20] in v = [4 7 5]. Prostornina nahrbtnika naj bo V = 8. Procedura PREPROSTI-NAHRBTNIK zahteva ureditev predmetov glede na vrednost na prostorsko enoto. Izraunajmo c/v = [2.5 2 4]. To pomeni, da tretji predmet postane prvi, prvi drugi in drugi tretji. Preuredimo vektor c in v: c = [20 10 14] in v = [5 4 7]. Opiimo delovanje procedure PREPROSTI-NAHRBTNIK: 1. Vrstici 12: x[1] = 0, x[2] = 0, x[3] = 0. 2. Vrstica 3: y = 8. 3. Vrstice 48: 1. iteracija zanke for: Ker je v [1] < y (5<8), dobimo x[1] = 1 in y = 8 5 = 3. 4. Vrstice 48: 2. iteracija zanke for: Ker je v [2] > y (4<3), izstopimo iz zanke for. 5. Vrstica 9: Ker je i n (2 3), izraunamo dele drugega predmeta, ki ga postavimo v nahrbtnik: x[2] = 3/4 = 0.75. To pomeni, da je reitev problema vektor x = [1 0.75 0].

asovna zahtevnost procedure PREPROSTI-NAHRBTNIK Procedura PREPROSTI-NAHRBTNIK najve dela opravi z drugo zanko for, ki se izvede v najslabem primeru n-krat. Zato je asovna zahtevnost v najslabem primeru: T (n) = O(n).

9.3 Primov algoritem

9-4

9.3

Primov algoritem

Imejmo n kontaktov, ki jih moramo povezati med sabo, tako da uporabimo n 1 ik. Vsaka ika povezuje dva kontakta. Na cilj je, da porabimo im manj ice. Vemo, da elektrina napetost pride do kontakta, e je le-ta povezan z eno iko. V problemu oienja kontaktov lahko uporabimo model neusmerjenega grafa G = (V, E ), kjer je V mnoica vozli (vertices ) in E mnoica povezav (edges ). Vozlia ustrezajo kontaktom, ike pa povezavam. V danem grafu elimo najti aciklini podgraf G = (V, E ), tako da je E E , ki povezuje vsa vozlia grafa G. Graf G imenujemo vpeto drevo (spanning tree ). V danem grafu (slika 9.1a) je mono doloiti veliko vpetih dreves. Slike 9.1b, 9.1c in 9.1d kaejo samo tri primere vpetega drevesa, teh pa je e ve.

Slika 9.1: a) Neusmerjeni graf, b) Vpeto drevo 1, c) Vpeto drevo 2, d) Vpeto drevo 3 Uvedimo tak graf G, v katerem je za vsako povezavo (u, v ) E , pri emer sta u in v vozlii iz grafa G (u, v V ), dana vrednost c(u, v ), ki predstavlja stroek (cost ) povezave. Sedaj lahko doloimo stroek vseh povezav v vpetem drevesu T : c(T ) = c(u, v ). (9.4)
(u,v )T

Nekateri avtorji [Cormen et al., 2007] uporabljajo izraz ute (weight ) in oznako w(u, v ). Drevo z minimalnim strokom povezav c(T ) imenujemo minimalno vpeto drevo (minimum-spanning-tree ), ki ga je mogoe doloiti z razlinimi algoritmi. Najprej bomo spoznali Primov algoritem. Minimalno vpeto drevo bomo gradili postopoma. Najprej bomo vkljuili v reitev eno vejo drevesa, zatem drugo, itd. Tekoa podatkovna struktura je venomer drevo. Na vsakem koraku bomo nali eno vejo konnega minimalnega vpetega drevesa. Najprej izberemo povezavo z minimalno vrednostjo v grafu G. Oznaimo jo s (k, l), pri emer sta k in l vozlii grafa G.

9.3 Primov algoritem

9-5

K vsakemu vozliu j , ki e ni vkljueno v minimalno vpeto drevo, priredimo vrednost r[j ], ki predstavlja indeks najblijega vozlia, ki je e v minimalnem vpetem drevesu. V drevo vkljuimo takno vozlie j , katerega povezava s poljubnim e vkljuenim vozliem je minimalna (torej c(j, r[j ])=min). Br ko je novo vozlie j vkljueno v reitev (oz. v drevo), postane vrednost indeksa r[j ] = 0. To pomeni, da moramo pri vkljuitvi novega vozlia j izpolniti dva pogoja: 1. r[j ] = 0, kar pomeni, da vozlie j e ni vkljueno v drevo, in 2. c(j, r[j ])=min, izbrati tako nevkljueno vozlie j , ki minimizira ta izraz. Zapiimo proceduro Primovega algoritma: PRIM(G, C, vr, T ) 1 izberi (k, l) kot povezavo, ki ima najmanjo ceno c(u, v ) (u, v V ) 2 (k, l) T % vkljui povezavo (k, l) v reitev 3 vr c(k, l) % izraunaj vrednost vpetega drevesa 4 for i 1 to n % zanka za doloitev indeksov r[i] 5 do if c(i, l) < c(i, k ) 6 then r[i] l 7 else r[i] k 8 r[k ] = r[l] 0 % vozlii k in l sta e vkljueni v drevo T 9 for i 2 to n 1 10 do poii j , tak da je r[j ] = 0 in c(j, r[j ])=min 11 (j, r[j ]) T % vkljui povezavo (j, r[j ]) v drevo T 12 vr vr + c(j, r[j ]) % osvei vrednost vr vpetega drevesa 13 r[j ] = 0 % spremeni indeks vkljuenosti za vozlie j 14 for h 1 to n % zanka za osveitev indeksov r[j ] 15 do if r[h] = 0 and c(h, r[h]) > c(h, j ) % stara povezava ima stroek veji od nove 16 then r[h] j Procedura PRIM(G, C, vr, T ) najde vse povezave minimalnega vpetega drevesa in vrednost drevesa.

9.3 Primov algoritem

9-6

Zgled 9.2. Poglejmo kako deluje procedura PRIM na primeru grafa na sliki 9.2.

1
30 25 15 6

2
4

3
20

14

12

5
Slika 9.2: Primer neusmerjenega grafa

Iz grafa na sliki 9.2 lahko zapiemo naslednjo 0 30 15 6 30 0 25 C= 15 25 0 14 6 14 0 4 20 12

matriko povezav: 4 20 12 0

1. Vrstica 1: Izberi povezavo (2, 5) kot povezavo, ki ima najmanjo ceno c(i, j ). 2. Vrstica 2: Vkljui povezavo (2, 5) v drevo T (slika 9.3a). 3. Vrstica 3: Izraunaj vrednost vpetega drevesa (vr = 4). 4. Vrstice 47: Vsem vozliem izraunaj indeks najblijega vozlia, ki je e v minimalnem vpetem drevesu. Ti so: r[1] = 2, r[2] = 2, r[3] = 5, r[4] = 5, r[5] = 5. 5. Vrstica 8: Vozliema 2 in 5 postavimo indeks r na ni, saj sta obe vozlii e vkljueni v drevo T (r[2] = 0, r[5] = 0). 6. Vrstica 9: Vstop v prvo iteracijo druge zanke for. 7. Vrstica 10: Doloi vozlie j , ki ga vkljuimo v drevo T . Vkljuili bomo vozlie 4, saj ima le-to c(j, r[j ])=min. 8. Vrstica 11: Vkljui povezavo (4, 5) v drevo T (slika 9.3b). 9. Vrstica 12: Osvei vrednost vr vpetega drevesa. Nova vrednost je: vr = 4 + 12 = 16.

9.3 Primov algoritem

9-7

2
4

2
4 12

5 a)

5 b)

1
6

1
6 14

2
4 12

2
4

12

5 c)

5 d)

Slika 9.3: Gradnja minimalnega vpetega drevesa T : a) po izvreni prvi zanki for, b) po izvreni prvi iteraciji druge zanke for, c) po izvreni drugi iteraciji druge zanke for, d) po izvreni tretji iteraciji druge zanke for 10. Vrstica 13: Spremeni indeks vkljuenosti za vozlie 4 (r[4] = 0). 11. Vrstice 1416: Vstop v tretjo zanko for, ki osvei vrednosti nevkljuenim vozliem. V naem primeru se spremeni r[1] na 4 (saj je c[1, 2] > c[1, 4] oz. 30 > 6) in r[3] na 4 (saj je c[3, 5] > c[3, 4] oz. 20 > 14). 12. Vrstica 9: Vstop v drugo iteracijo druge zanke for. 13. Vrstica 10: Doloi vozlie j , ki ga vkljuimo v reitev. Od e nevkljuenih vozli ima vozlie 1 minimalno vrednost izraza c(j, r[j ]). 14. Vrstica 11: Vkljui povezavo (1, 4) v drevo T (slika 9.3c). 15. Vrstica 12: Osvei vrednost vpetega drevesa. Nova vrednost je: vr = 16 + 6 = 22. 16. Vrstica 13: Spremeni indeks vkljuenosti za vozlie 1 (r[1] = 0).

9.3 Primov algoritem

9-8

17. Vrstice 1416: Vstop v tretjo zanko for, ki osvei vrednosti nevkljuenim vozliem. V naem primeru se r[3] ne spremeni (saj je c[3, 4] < c[3, 1] oz. 14 < 15). 18. Vrstica 9: Vstop v tretjo (zadnjo) iteracijo druge zanke for. 19. Vrstica 10: Doloi vozlie j , ki ga vkljuimo v reitev. Vozlie 3 ima c(j, r[j ])=min. Sicer pa je to vozlie zadnjo nevkljueno vozlie. 20. Vrstica 11: Vkljui povezavo (3, 4) v drevo T (slika 9.3d). To je e konno minimalno vpeto drevo. 21. Vrstica 12: Osvei vrednost vpetega drevesa. Nova vrednost je: vr = 22 + 14 = 36. 22. Vrstica 13: Spremeni indeks vkljuenosti za vozlie 3 (r[3] = 0). 23. Vrstice 1416: Vstop v tretjo zanko for, ki osvei vrednosti nevkljuenim vozliem. V naem primeru zanka ne osveuje ve, saj ni ve izpolnjen pogoj r[j ] = 0. 24. Preglednica 9.1 povzema delovanje algoritma PRIM.

Preglednica 9.1: Rezultati delovanja procedure PRIM zap. t. vkljuene povezave 1 2 3 4 vkljuena povezava (2,5) (4,5) (1,4) (3,4) vrednost drevesa vr 4 16 22 36

4 1 3

r[h] 12345 20550 4 40 0 0

asovna zahtevnost procedure PRIM Procedura PRIM ima tri zanke for. Prva zanka for se izvede n-krat, druga (n 2)krat in tretja n-krat. Tretja zanka for je vgnezdena v drugo zanko. Vse zanke se brezpogojno izvedejo do konca, zato je skupna asovna zahtevnost: T (n) = (n) + (n2 ) = (n2 ), kar pomeni, da so zgornja, spodnja in poprena asovna zahtevnost enake. (9.5)

9.4 Dijkstrin algoritem

9-9

9.4

Dijkstrin algoritem

V tem razdelku bomo spoznali problem najkraje poti iz enega vozlia do vseh preostalih vozli v grafu. Preden se lotimo obravnave algoritma razloimo nekaj novih pojmov. V problemih najkraje poti je dan uteen usmerjen graf G = (V, E ) z uteno funkcijo w : E R, ki preslika povezave v utei (realna tevila). Denicija 9.1. Ute poti p = v0 , v1 , . . . , vk je vsota utei njenih povezav: w(p) =
k i=1

w(vi1 , vi ).

(9.6)

Denicija 9.2. Ute najkraje poti ( shortest-path weight) je denirana kot: { min{w(p) : u v }, ce je pot od u do v, (u, v ) = (9.7) , druga ce. Najkraja pot iz vozlia u do vozlia v je denirana kot katerakoli pot p z utejo w(p) = (u, v ). Utei predstavljajo razdalje (problem zemljevida), as, stroke, kazni ipd. Algoritem iskanja z razvijanjem v irino je algoritem najkrajih poti na neuteenih grah, kjer ima vsaka povezava enotsko ute. Precej konceptov iz tega algoritma se uporablja tudi v uteenih grah. V tem razdelku se bomo osredotoili na problem najkrajih poti iz enega vozlia: za dani graf G = (V, E ) elimo doloiti najkraje poti iz izhodia s V k vsakemu vozliu v V . V nekaterih problemih najkrajih poti iz enega vozlia lahko imamo povezave z negativnimi utemi. e graf G = (V, E ) ne vsebuje ciklov z negativno utejo, dosegljivih iz izhodia s, potem so najkraje poti (s, v ) do vozli v V dobro denirane, eprav imajo celo negativno ute. e obstaja cikel z negativnimi utemi, dosegljiv iz s, potem dobi najkraja pot vrednost ( (s, v ) = ). Slika 9.4 kae uinek negativnih utei na utei najkrajih poti. Iz s do a vodi samo ena pot (pot s, a), zato je (s, a) = w(s, a) = 6. Podobno velja za pot iz s do b (pot s, a, b): (s, b) = w(s, a) + w(a, b) = 6 + (2) = 4. Na drugi strani pa imamo iz s do c neskonno mnogo poti: s, c, s, c, d, c, s, c, d, c, d, c itd. Ker ima cikel c, d, c ute 5 + (4) = 1 > 0, je najkraja pot iz s v c s, c z utejo (s, c) = 3. Podobno je najkraja pot iz s v d s, c, d z utejo (s, d) = w(s, c) + w(c, d) = 3 + 5 = 8. Analogno imamo neskonno poti iz s v e: s, e, s, e, f, e. s, e, f, e, f, e itd. Ker ima cikel e, f, e ute 2 + (5) = 3 < 0, ne obstaja najkraja pot iz s v e. e se sprehodimo po ciklu z negativno utejo e, f, e poljubno krat, lahko

9.4 Dijkstrin algoritem

9-10

najdemo poti iz s v e s poljubno velikimi negativnimi utemi, zato je (s, e) = . Podobno velja za (s, f ) = . Ker je g dosegljivo iz f , lahko najdemo poti s poljubni velikimi negativnimi utemi iz s do g in (s, g ) = .

6 a 6 0 s 7 3 3 c

-2

4 b 10 8 d

5 -4 2

11 6

g -

e -

-5

f -

Slika 9.4: Negativne utei v usmerjenem grafu. Ob vsakem vozliu je prikazana njegova najkraja pot iz izhodia. Da bi razumeli algoritme najkraje poti iz enega vozlia, je koristno poznati tehnike, ki jih ti algoritmi uporabljajo, in lastnosti najkrajih poti, ki jih le-ti izkoriajo. Glavna tehnika, ki jo uporabljajo algoritmi, je relaksacija (relaxation ), tj. metoda, ki ponavljajoe zmanjuje zgornjo mejo utei najkraje poti, dokler ne postane enaka utei najkraje poti. Algoritmi najkrajih poti izkoriajo lastnost, da najkraja pot med dvema vozliema vsebuje druge najkraje poti znotraj te poti. To je princip optimalnosti, ki je znailen tako za poreno metodo kot dinamino programiranje. Principu optimalnosti pravijo nekateri tudi lastnost optimalne podstrukture (optimal-substructure property ). Izrek 9.1. Dan je uteni usmerjen graf G = (V, E ) z uteno funkcijo w : E R. Bodi p = v1 , v2 , . . . , vk najkraja pot iz vozlia v1 do vozlia vk in za poljubni i in j (1 i j k ) bodi pij = vi , vi+1 , . . . , vj delna pot ( subpath) iz vozlia vi do vozlia vj . Potem je pij najkraja pot iz vi do vj . Izrek 9.2. Dan je uteni usmerjen graf G = (V, E ) z uteno funkcijo w : E R. Predpostavljamo, da lahko najkrajo pot p iz izhodia s do vozlia v razcepimo v pot p od s do u in pot od u direktno v vozlie v (torej med vozliema u in v obstaja neposredna povezava). Potem je ute najkraje poti iz s do u enaka (s, v ) = (s, u) + w(u, v ).

9.4 Dijkstrin algoritem

9-11

Izrek 9.3. Dan je uteni usmerjen graf G = (V, E ) z uteno funkcijo w : E R. Za vse povezave (u, v ) E velja: (s, v ) (s, u) + w(u, v ). V izreku 9.2 je vozlie u vkljueno v najkrajo pot med s in v , v izreku 9.3 pa vozlie u ni nujno vkljueno v najkrajo pot med s in v . Za vsako vozlie v V vzdrujemo atribut d[v ], ki je zgornja meja utei najkraje poti od izhodia s do v . d[v ] imenujemo ocena najkraje poti (shortest-path estimate ). Ocene najkraje poti in prednike inicializiramo z naslednjo proceduro: INICIALIZACIJA(G, s) 1 for vsako vozlie v V 2 do d[v ] 3 oce[v ] NIL 4 d[s] 0

Proces relaksacije povezave (u, v ) sestoji iz testiranja, e lahko izboljamo najkrajo pot do v , tako da gremo skozi u in e nam to uspe, osveimo d[v ] in oce[v ]. Relaksacijo izvedemo z naslednjo kodo: RELAKSACIJA(u, v, w) 1 if d[v ] > d[u] + w(u, v ) 2 then d[v ] d[u] + w(u, v ) 3 oce[v ] u

Slika 9.5 prikazuje dva primera relaksacije povezave. V primeru na sliki 9.5a se ocena najkraje poti zmanja, v primeru na sliki 9.5b pa se ocena ne spremeni.

9.4 Dijkstrin algoritem

9-12

10 u

15 v RELAKSACIJA(u, v, w)

10 u

11 v RELAKSACIJA(u, v, w)

10 u

3 a)

13 v

10 u

3 b)

11 v

Slika 9.5: Relaksacija povezave (u, v ). Ocena najkraje povezave d je oznaena ob vozliu. a) Ker je pred relaksacijo d[v ] > d[u]+ w(u, v ), se vrednost d[v ] zmanja. b) Ker je pred relaksacijo d[v ] d[u] + w(u, v ), se d[v ] ne spremeni. Izrek 9.4. Dan je uteni usmerjen graf G = (V, E ) z uteno funkcijo w : E R in bodi poljubna povezava (u, v ) E . Po relaksaciji povezave (u, v ) s proceduro RELAKSACIJA(u, v, w) velja d[v ] d[u] + w(u, v ).

Dijkstrin algoritem reuje problem najkraje poti iz enega vozlia na utenem usmerjenem grafu, ko so vse utei nenegativne. Algoritem vzdruje mnoico S vozli, ki imajo e doloeno najkrajo pot iz izhodia s. Za vsa vozlia v S velja d[v ] = (s, v ). Algoritem izbere tako vozlie u (u V S ), ki ima minimalno oceno najkraje poti, vstavi u v S in relaksira vse povezave, ki izhajajo iz u. V priujoi aplikaciji vzdrujemo prednostno vrsto Q, ki vsebuje vsa vozlia (iz V S ), ki hranijo v kljuih vrednost d. Implementacija predpostavlja, da je graf podan s seznami sosedov. DIJKSTRA(G, w, s) 1 INICIALIZACIJA(G, s) 2 S 3 QV 4 while Q = 0 5 do u IZLOCI-MINIMUM(Q) 6 S S {u} 7 for za vsako vozlie v Adj [u] 8 do RELAKSACIJA(u, v, w)

9.4 Dijkstrin algoritem

9-13

V vrstici 1 postavimo zaetne vrednosti za d[v ] in oce[v ] za vsako vozlie v iz G. Vrstica 2 napravi mnoico S prazno. V vrstici 3 postavimo v prednostno vrsto Q vsa vozlia V . V iteraciji zanke while v vrsticah od 48 se izloi vozlie u, ki ima najmanjo oceno najkraje poti v V S , in ga vloi v mnoico S ( V prvi iteraciji se izloi izhodie s.). V vrsticah od 78 se relaksira vsaka povezava (u, v ), ki zapua u, in se osveijo ocene d[v ] in oce[v ]. Zgled 9.3. Delovanje Dijkstrinega algoritma na usmerjenem grafu kae slika 9.6. Ocene najkrajih poti so zapisane ob krogcih, ki predstavljajo vozlia. S pomojo poudarjene povezave lahko doloimo oeta ustreznega vozlia (oe je vozlie pri repu puice). rna vozlia so v mnoici S , bela pa v prednostni vrsti Q = V S . Vozlie, ki je pobarvano sivo, bo izbrano v naslednji iteraciji zanke while. Bodi izhodie vozlie 1. Podrobno ponazorimo delovanje algoritma: 1. Vrstica 1: Po izvritvi procedure INICIALIZACIJA(G, 1) imamo d[2] = d[3] = d[4] = d[5] = , d[1] = 0 in oce[1] = oce[2] = oce[3] = oce[4] = oce[5] = NIL. 2. Vrstica 2: S = {}. 3. Vrstica 3: Q = {1, 2, 3, 4, 5}. V prvi iteraciji while bo izbrano vozlie 1, ki ima najmanjo vrednost d izmed vseh elementov v vrsti Q. Zato vozlie 1 pobarvamo sivo. Stanje po tej izbiri kae slika 9.6a. 4. Vrstice 48: 1. iteracija while: Prednostna vrsta Q ni prazna. Iz nje izloimo vozlie 1, ki ima najmanjo vrednost d (novo stanje je Q = {2, 3, 4, 5}). V mnoico S vkljuimo vozlie 1 (S = {1}) in ga oznaimo s rno barvo. 1. iteracija for: 1. sosed od 1 je v = 2 in izvedemo RELAKSACIJA(1, 2, w). Ker je d[2] > d[1] + w(1, 2) ( > 0 + 9), postavimo d[2] = d[1] + w(1, 2) = 0 + 9 = 9 in oce[2] = 1. 2. iteracija for: 2. sosed od 1 je v = 5, izvedemo RELAKSACIJA(1, 5, w). Ker je d[5] > d[1]+ w(1, 5) ( > 0+4), postavimo d[5] = d[1]+ w(1, 5) = 0+4 = 4 in oce[5] = 1. Stanje po zakljuku 1. iteracije while kae slika 9.6b, kjer je oznaeno vozlie 1 kot rno (je tudi e razvito v celoti). Vozlie 5 je pobarvano sivo, saj ima trenutno najmanjo vrednost d v vrsti Q. 5. Vrstice 48: 2. iteracija while: Prednostna vrsta Q ni prazna. Iz nje izloimo vozlie 5, ki ima najmanjo vrednost d (novo stanje je Q = {2, 3, 4}). V mnoico S vkljuimo vozlie 5 (S = {1, 5}) in ga pobarvamo rno. 1. iteracija for: Sosed od 5 je v = 2 in izvedemo RELAKSACIJA(5, 2, w). Ker je d[2] > d[5]+ w(5, 2) (9 > 4+1), postavimo d[2] = d[5]+ w(5, 2) = 4+1 = 5 in oce[2] = 5. Vozlie 2 dobi novega oeta, tj. 5. Stanje po zakljuku 2. iteracije while kae slika 9.6c. Na sliki je vozlie 5 pobarvano rno (je

9.4 Dijkstrin algoritem

9-14

tudi e razvito) in vozlie 2 kot sivo, saj ima trenutno najmanjo vrednost d v vrsti Q. 6. Vrstice 48: 3. iteracija while: Prednostna vrsta Q ni prazna. Iz nje izloimo vozlie 2, ki ima najmanjo vrednost d (novo stanje je Q = {3, 4}). V mnoico S vkljuimo vozlie 2 (S = {1, 5, 2}) in ga pobarvamo rno. 1. iteracija for: 1. sosed od 2 je v = 3 in izvedemo RELAKSACIJA(2, 3, w). Ker je d[3] > d[2] + w(2, 3) ( > 5 + 5), postavimo d[3] = d[2] + w(2, 3) = 5 + 5 = 10 in oce[3] = 2. 2. iteracija for: 2. sosed od 2 je v = 4 in izvedemo RELAKSACIJA(2, 4, w). Ker je d[4] > d[2] + w(2, 4) ( > 5 + 4), postavimo d[4] = d[2] + w(2, 4) = 5 + 4 = 9 in oce[4] = 2. Stanje po zakljuku 3. iteracije while kae slika 9.6d. Na sliki je vozlie 2 kot rno (je e razvito) in vozlie 4 kot sivo, saj ima trenutno najmanjo vrednost d v vrsti Q. 7. Vrstice 48: 4. iteracija while: Prednostna vrsta Q ni prazna. Iz nje izloimo vozlie 4, ki ima najmanjo vrednost d (novo stanje je Q = {3}). V mnoico S vkljuimo vozlie 4 (S = {1, 5, 2, 4}) in ga pobarvamo rno. 1. iteracija for: 1. sosed od 4 je v = 1 in izvedemo RELAKSACIJA(4, 1, w). Ker ni d[1] > d[4] + w(4, 1) (ne velja 0 > 9 + 6), zakljuimo obravnavo tega soseda. 2. iteracija for: 2. sosed od 4 je v = 5, izvedemo RELAKSACIJA(4, 5, w). Ker ni d[5] > d[4] + w(4, 5) (ne velja 4 > 9 + 7), zakljuimo obravnavo tega soseda. Stanje po zakljuku 4. iteracije while kae slika 9.6e. Na sliki je oznaeno kot rno vozlie 4 in kot sivo vozlie 3, saj ima trenutno najmanjo vrednost d v vrsti Q. 8. Vrstice 48: 5. iteracija while: Prednostna vrsta Q ni prazna. Iz nje izloimo vozlie 3, ki ima najmanjo vrednost d (novo stanje je Q = {}). V mnoico S vkljuimo vozlie 3 (S = {1, 5, 2, 4, 3}) in ga pobarvamo rno. 1. iteracija for: 1. sosed od 3 je v = 2 in izvedemo RELAKSACIJA(3, 2, w). Ker ni d[2] > d[3] + w(3, 2) (ne velja 5 > 10 + 3), zakljuimo obravnavo tega soseda. 2. iteracija for: 2. sosed od 3 je v = 4 in izvedemo RELAKSACIJA(3, 4, w). Ker ni d[4] > d[3] + w(3, 4) (ne velja 9 > 10 + 2), zakljuimo obravnavo tega soseda. Stanje po zakljuku 5. iteracije while kae slika 9.6f. Na sliki so vsa vozlia oznaena rno. Ker je mnoica Q izrpana (prazna), zakljuimo proceduro. e nariemo samo poudarjene povezave v grafu na sliki 9.6f, dobimo drevo najkrajih poti iz vozlia 1 do vseh ostalih vozli v grafu (slika 9.7). Zunaj ob

9.4 Dijkstrin algoritem

9-15

Preglednica 9.2: Rezultati delovanja procedure DIJKSTRA zap. t. iteracije vrstica 3 1 2 3 4 5 izbrano vozlie 1 5 2 4 3 oe v drevesu NIL 1 5 2 2 najkraja pot 1 1, 5 1, 5, 2 1, 5, 2, 4 1, 5, 2, 3

d[1] 0! -

d[2] 9 5! -

d[3] 10 10! -

d[4] 9! -

d[5] 4! -

vozliu je oznaena dolina najkraje poti iz vozlia 1.

asovna zahtevnost Procedura IZLOCI-MINIMUM zahteva O(|V |) asa, ker pa jo izvedemo |V |-krat, je celoten as za IZLOCI-MINIMUM velikosti O(|V |2 ). Zanka for v vrsticah 78 se izvede tolikokrat, kolikor imamo povezav, tj. |E |-krat, medtem ko vsaka iteracija zahteva O(1) asa. Skupni as algoritma je torej T (n) = O(|V |2 + |E |) = O(|V |2 ), saj velja, da je v polnem usmerjenem grafu |E | = |V |(|V | 1) povezav in je |V |2 > |E |.

9.4 Dijkstrin algoritem

9-16

0 1 4 5 6 7 4 2 a) 0 1 4 4 5 7 4 6 1 4 5 3 9 2 5 3 4 5 6 7 4 9 4 1 4 5 3 9 2 3 4 5 6 7 4 4

0 1 9 1 4 5 3 2 9 3

2 b) 0 1

9 1 4 5 3 10 2 5 3

2 c) 0 1 4

2 d) 0 1

9 1 6 4 5 3 10 2 5 3 4 5 7 4 9

4 1 6 4

9 2 5 5 3 10 3

4 5 7 4 9

2 e)

2 f)

Slika 9.6: Delovanje Dijkstrinega algoritma na usmerjenem grafu: a) Stanje po izvritvi vrstice 3, b) Stanje po izvritvi 1. iteracije while, c) Stanje po izvritvi 2. iteracije while, d) Stanje po izvritvi 3. iteracije while, e) Stanje po izvritvi 4. iteracije while, f) Stanje po izvritvi 5. (zadnje) iteracije while.

9.4 Dijkstrin algoritem

9-17

Slika 9.7: Drevo najkrajih poti iz vozlia 1 do vseh ostalih vozli v grafu na sliki 9.6a

9.5 Bellman-Fordov algoritem

9-18

9.5

Bellman-Fordov algoritem

Bellman-Fordov algoritem reuje problem najkrajih poti iz enega vozlia bolj splono, torej tudi v primeru negativnih utei za povezave. Za dani uteeni usmerjeni graf G = (V, E ) z izhodiem s in uteno funkcijo w : E R vrne BellmanFordov algoritem Boolovo vrednost, ki oznauje, ali je ali ni cikla z negativno utejo, dosegljivega iz izhodia. e obstaja tak cikel, algoritem naznani, da ni reitve. e tak cikel ne obstaja, algoritem proizvede najkraje poti in njihove utei. Podobno kot Dijkstrin algoritem tudi Bellman-Fordov algoritem uporablja metodo relaksacije. Bellman-Fordov algoritem vrne TRUE, e in samo e graf ne vsebuje ciklov z negativnimi utemi, dosegljivih iz izhodia. BELLMAN-FORD(G, w, s) 1 INICIALIZACIJA(G, s) 2 for i 1 to |V | 1 3 do for za vsako povezavo (u, v ) E 4 do RELAKSACIJA(u, v, w) 5 for za vsako povezavo (u, v ) E 6 do if d[v ] > d[u] + w(u, v ) 7 then return FALSE % eden od ciklov je negativen 8 return TRUE % vsi cikli so pozitivni V vrstici 1 postavimo zaetne vrednosti za d[v ] in oce[v ] za vsako vozlie v iz G. V vrsticah 24 se izvede |V | 1 iteracij preko povezav grafa. Vsaka iteracija relaksira vsako povezavo grafa samo enkrat. Vrstice 58 preverjajo cikel z negativno utejo in vrnejo ustrezno Boolovo vrednost. Zgled 9.4. Delovanje Bellman-Fordovega algoritma na usmerjenem grafu kae slika 9.8. Izhodie s naj bo vozlie 5. Ocene najkrajih poti so zapisane zunaj ob krogcih, ki predstavljajo vozlia. S pomojo poudarjene povezave lahko doloimo oeta ustreznega vozlia (oe je vozlie pri repu puice). V tem zgledu vsaka iteracija prve zanke for relaksira povezave po naslednjem vrstnem redu: (1, 2), (1, 3), (1, 4), (2, 1), (3, 2), (3, 4), (4, 2), (4, 5), (5, 1), (5, 3). Vsi cikli imajo pozitivno vrednost, zato nam algoritem vrne vrednost TRUE. Podrobno ponazorimo delovanje algoritma: 1. Vrstica 1: Po izvritvi procedure INICIALIZACIJA(G, 5) imamo d[1] = d[2] = d[3] = d[4] = , d[5] = 0 in oce[1] = oce[2] = oce[3] = oce[4] = oce[5] = NIL. Stanje po tej izvritvi kae slika 9.8a. 2. Vrstice 24: 1. iteracija 1. zanke for: Prvo relaksacijo dobimo ele pri povezavi (5, 1) (0 + 6 < ). Tedaj se doloita nova razdalja in novi oe pri

9.5 Bellman-Fordov algoritem

9-19

vozliu 1, tj. d[1] = 6 in oce[1] = 5. Druga relaksacija se zgodi pri povezavi (5, 3) (0 + 7 < ), ko se izraunata nova razdalja in novi oe pri vozliu 3, tj. d[3] = 7 in oce[3] = 5. Stanje po zakljuku 1. iteracije 1. zanke for kae slika 9.8b. 3. Vrstice 24: 2. iteracija 1. zanke for: Prva relaksacija se izvede e pri povezavi (1, 2) (6 + 5 < ). Tedaj se doloita nova razdalja in novi oe pri vozliu 2, tj. d[2] = 11 in oce[2] = 1. Druga relaksacija se zgodi pri pri povezavi (1, 4) (6 4 < ), ko dobimo novo razdaljo in novega oeta pri vozliu 4, tj. d[4] = 2 in oce[4] = 1. Tretja relaksacija se izvede pri povezavi (3, 2) (7 3 < 11), ko dobimo ponovno novo razdaljo in novega oeta pri vozliu 2, tj. d[2] = 4 in oce[2] = 3. Stanje po zakljuku 2. iteracije 1. zanke for kae slika 9.8c. 4. Vrstice 24: 3. iteracija 1. zanke for: V tej iteraciji se izvede samo ena relaksacija in to pri povezavi (2, 1) (4 2 < 6). Tedaj se doloita nova razdalja in novi oe pri vozliu 1, tj. d[1] = 2 in oce[1] = 2. Stanje po zakljuku 3. iteracije 1. zanke for kae slika 9.8d. 5. Vrstice 24: 4. iteracija 1. zanke for: Izvede se samo ena relaksacija in to pri povezavi (1, 4) (2 4 < 2). Tedaj se doloi nova razdalja d[4] = 2, medtem ko oe od vozlia 4 ostane nespremenjen. Stanje po zakljuku 4. iteracije 1. zanke for kae slika 9.8e. 6. Vrstice 57: V tretji zanki for ne velja pri nobeni povezavi (u, v ) neenaba d[v ] > d[u] + w(u, v ). V danem grafu imamo pet ciklov, kjer se pojavijo tudi povezave z negativnimi utemi. Cikel 1, 2, 1 ima ute 5 + (2) = 3, cikel 1, 4, 2, 1 ute (4) + 7 + (2) = 1, cikel 1, 4, 5, 1 ute (4) + 2 + 6 = 4, cikel 1, 3, 2, 1 ute 8 + (3) + (2) = 3 in cikel 1, 3, 4, 2, 1 ima ute 8 + 9 + 7 + (2) = 22. 7. Vrstica 8: Bellman-Fordov algoritem nam vrne TRUE, ker ni ciklov z negativnimi vrednostmi.

9.5 Bellman-Fordov algoritem

9-20

Slika 9.8: Delovanje Bellman-Fordovega algoritma na usmerjenem grafu: a) Stanje po izvritvi vrstice 1, b) Stanje po izvritvi 1. iteracije 1. zanke for, c) Stanje po izvritvi 2. iteracije 1. zanke for, d) Stanje po izvritvi 3. iteracije 1. zanke for, e) Stanje po izvritvi 4. iteracije 1. zanke for

9.5 Bellman-Fordov algoritem

9-21

Preglednica 9.3: Rezultati delovanja procedure BELLMAN-FORD

zap. t. iteracije pred 1. it. 1 2 3 4

oce[1] NIL 5 5 2 2

oce[2] NIL NIL 3 3 3

oce[3] NIL 5 5 5 5

oce[4] NIL NIL 1 1 1

oce[5] NIL NIL NIL NIL NIL

d[1] 6 6 2 2

d[2] 4 4 4

d[3] 7 7 7 7

d[4] 2 2 -2

d[5] 0 0 0 0 0

e nariemo samo poudarjene povezave v grafu na sliki 9.8e, dobimo drevo najkrajih poti iz vozlia 5 do vseh ostalih vozli v grafu (slika 9.9). Zunaj ob vozliu je oznaena dolina najkraje poti iz vozlia 5.

Slika 9.9: Drevo najkrajih poti iz vozlia 5 do vseh ostalih vozli v grafu na sliki 9.8a

9.5 Bellman-Fordov algoritem

9-22

asovna zahtevnost Inicializacija v vrstici 1 zahteva O(|V |) asa. Prva zanka for se izvede (|V | 1)krat. V vsaki od iteracij te zanke se pa izvede e druga zanka for |E |-krat. Skupaj torej prva zanka for zahteva O(|V ||E |) asa. Tretja zanka for zahteva O(|E |) asa. Skupna asovna zahtevnost Bellman-Fordovega algoritma je: T (n) = O(|V |) + O(|V ||E |) + O(|E |) = O(|V ||E |).

Literatura

Cormen, T. H., Leiserson, C. E., and Rivest, R. L. (2007). Introduction to Algorithms. Druga izdaja, MIT Press, Cambridge. Gams, M. (1993). Urednik. Raunalniki slovarek. Cankarjeva zaloba, Ljubljana. Knuth, D. E. (1976). Big omikron and big omega and big theta. SIGACT News, (2):1824. Kononenko, I. (1996). Nartovanje podatkovnih struktur in algoritmov. Fakulteta za raunalnitvo in informatiko, Ljubljana. Kozak, J. (1997). Podatkovne strukture in algoritmi. Drutvo matematikov, zikov in astronomov Slovenije, Ljubljana. Levitin, A. (2007). The Design and Analysis of Algorithms. Druga izdaja, Pearson Education, Inc., Boston. Nilsson, N. J. (1980). Principles of Articial Intelligence. Tioga. Vilfan, B. (1998). Osnovni algoritmi. Fakulteta za raunalnitvo in informatiko, Ljubljana. Zazula, D. and Leni, M. (2006). Principi sistemske programske opreme. Fakulteta za elektrotehniko, raunalnitvo in informatiko, maribor.

También podría gustarte