You are on page 1of 22

PROGRAMIRANJE II

P-08: Grafovi

doc. dr Draen
Branin
2014/15

P-08: Grafovi

Sadraj predavanja

Osnovni pojmovi o grafovima

Reprezentacija grafa

Obilazak grafa

Obuhvatno stablo

Najkraa rastojanja

Osnovni pojmovi o grafovima

grane

GRAF:

nelinearna struktura podataka koju ini:

V - skup vorova (nodes/vertices), i

E - kolekcija grana (edges/arcs)

grane

predstavljaju binarne veze (odnose) izmeu vorova

koriste se za modelovanje proizvoljnih nelinearnih relacija

grane mogu biti:

neusmjerene (simetrine) i

usmjerene (asimetrine)

neusmjereni graf

usmjereni graf

vorovi

mjeoviti graf

sve veze u grafu su


neusmjerene

sve veze u grafu su


usmjerene

u grafu postoje i usmjerene i


neusmjerene veze

Osnovni pojmovi o grafovima


B

ulazne grane vora


(grane usmjerenog grafa
koje ulaze u dati vor)

izlazne grane vora


(grane usmjerenog grafa
koje izlaze iz datog vora)

Ulazni stepen vora (in-degree):


broj ulaznih grana u voru
indeg(B)=3

Izlazni stepen vora (out-degree):


broj izlaznih grana iz vora
outdeg(C)=5

Po definiciji, graf ine skup vorova i kolekcija


grana:

svaka grana predstavlja vezu izmeu para


vorova
izmeu neka dva vora mogu da postoje
paralelne ili viestruke veze/grane (npr.
izmeu vorova u elektr. mrei moe da
B
postoji vie A
grana)

Stepen vora (degree):


ukupan broj ulaznih i izlaznih
grana u datom voru
deg(D)=4

Petlja: grana koja poinje i


zavrava istim vorom
A

Prosti graf: graf u kojem nema


petlji i viestrukih veza

Osnovni pojmovi o grafovima


Put/Putanja (path): alternativna (naizmjenina) sekvenca povezanih
vorova i grana (vor-grana-vor-...-vor) izmeu neka dva vora u
grafu

Prosta putanja svi vorovi u


putanji su razliiti (nijedan vor
nije sadran vie puta)
Usmjerena putanja sve grane u
putanji su usmjerene i obilaze
se u odgovarajuem smjeru

Npr. putanja A-(A,D)-D-(D,E)-E je prosta (svaki vor sadran samo jednom) i


usmjerena (obje grane su usmjerene i obilaze se u adekvatnom smjeru)
Ciklus (cycle): putanja koja ima isti poetni i krajnji
vor
A

Prosti ciklus svi vorovi u ciklusu


(osim poetnog i krajnjeg) su
razliiti
Usmjereni ciklus sve grane u
ciklusu su usmjerene i obilaze se
u odgovarajuem smjeru

Npr. ciklus C-(C,D)-D-(D,E)-E-(E,C)-C je prost (svaki vor osim C je sadran


samo jednom) i usmjeren (sve grane su usmjerene i obilaze se u adekvatnom
smjeru)

Osnovni pojmovi o grafovima


Podgraf grafa G je graf P iji su vorovi i grane podskupovi vorova i grana grafa G
A

Povezani graf je graf u kojem


izmeu svaka dva vora postoji
putanja
Nepovezani graf je graf u kojem
postoje vorovi izmeu kojih ne
postoje putanje
A

Stablo je povezani graf bez ciklusa


A
B
C

D
E

Povezane komponente su
najvei povezani podgrafovi
u nepovezanom grafu

korjeno stablo
(rooted tree)

slobodno
stablo
(free tree)

Reprezentacija grafa
Matrina reprezentacija (matrica susjednosti)
Sadraj matrice definie se na sljedei nain

1, (i, j ) E
a[i ][ j ]
0, (i, j ) E

usmjereni graf

neusmjereni graf

Reprezentacija grafa
Teinski graf
Grane imaju teinu (npr. cijena, duina, ...)
50

C
50

80

70
B

A
70
B

50

3
0

20

w(i, j ), (i, j ) E
0, (i, j ) E

a[i ][ j ]

20

7
0
0

5
0
0

0
5
0
2
0
0

2
0
2
0
0

6
0
0

8
0
6
0
5
0
0

7
0
5
0
8
0
0

C
50

80

60

Sadraj matrice susjednosti


za teinske grafove

60

20

3
0

20

2
3

2
0
0

3
0

0
3
0
0

Reprezentacija grafa
Ulanana reprezentacija (lista susjednosti)
Graf se predstavlja pomou:

vektora zaglavlja za svaki vor grafa

ulanane liste za svaki vor grafa

svaki element u listi reprezentuje jednu granu

usmjereni graf

neusmjereni graf

Obilazak grafa
Obilazak (eng. traversal) grafa:

sistematina procedura kojom se svaki vor u grafu posjeti (obradi) samo jednom

na neki vor moe da se naie vie puta, ali se samo prvi put posjeti (obradi):

graf nema neki specifian vor (kao to korjeno stablo ima korijen) od kojeg bi zapoeo
obilazak

ako se neki vor ne posjeti zbog nedostinosti, nastavlja se sa nekim neposjeenim

obilazak moe da zapone od:

eksplicitno zadatog vora

sluajno izabranog vor

poredak (rezultat obilaska) zavisi od:

izbora poetnog vora

strategije (algoritma) obilaska

osnovni algoritmi za obilazak grafa zasnovani na susjednosti:

obilazak po irini (BFS)

obilazak po dubini (DFS)

Obilazak grafa
Obilazak grafa po dubini:

procedura veoma slina preorder obilasku korjenog stabla

strategija obilaska:

posjeti poetni vor

posjeti jednog njegovog susjeda

posjeti neposjeenog susjeda prethodnog vora

ako nema neposjeenog susjeda, vrati se na posljednjeg prethodnika koji ima


neposjeenog susjeda

potreban pomoni niz koji sadri informaciju o posjeenim vorovima, na poetku:


for i=1 to n do
visit[i]=FALSE

rekurzivni obilazak od nekog vora u:


DFS(u)
visit[u]=TRUE
OBRADA(u)
for { v, (u,v)E } do
if visit[v]=FALSE then DFS(v)

Obilazak grafa
Primjer: Obii dati graf po dubini poevi od vora 1

v[1] v[2] v[3] v[4] v[5] v[6]


F

v[1] v[2] v[3] v[4] v[5] v[6]


T

v[1] v[2] v[3] v[4] v[5] v[6]

v[1] v[2] v[3] v[4] v[5] v[6]

v[1] v[2] v[3] v[4] v[5] v[6]

v[1] v[2] v[3] v[4] v[5] v[6]


T

Rezultat obilaska:

v[1] v[2] v[3] v[4] v[5] v[6]


T

Obilazak grafa
/* obilazak grafa po dubini */
#include <stdio.h>
#define MAX 10
typedef struct G { int n; char nodes[MAX]; int ms[MAX][MAX]; }
GRAF;
void DFS(GRAF *g)
{
int visit[MAX]={};
void dfs_visit(int u)
{
int v;
printf("%c",g->nodes[u]);
visit[u]=1;
for (v=0; v<g->n; v++)
if (g->ms[u][v] && !visit[v]) dfs_visit(v);
}
dfs_visit(0);
}
void main()
{
GRAF g = { 6, {'1','2','3','4','5','6'},
{ {0,1,1,1,0,0}, {1,0,0,1,0,0}, {1,0,0,1,1,0},
{1,1,1,0,1,0}, {0,0,1,1,0,1},
{0,0,0,0,1,0} }};
DFS(&g);

GRAF je struktura koja


reprezentuje graf:
n broj vorova
nodes nazivi vorova
ms matrica
susjednosti
DFS je funkcija za
obilazak grafa (uvijek
od vora 0):
visit pomoni niz
dfs_visit obilazi graf
GRAF g reprezentuje
graf iz prethodnog
primjera

Rezultat obilaska:
124356

Obuhvatno stablo (stablo


razapinjanja)
obuhvatno stablo
Obuhvatno stablo S(U,E) povezanog neusmjerenog grafa G(V,E): (eng. spanning tree)
sadri sve vorove grafa (U=V)
sadri odreen broj grana iz grafa tako da su svi vorovi povezani, ali bez
ciklusa (EE)
A

Obuhvatno stablo = slobodno stablo

broj grana: n-1 (n broj vorova)

moe da se generie prilikom DFS ili BFS obilaska


(kad se doe do neposjeenog vora, u skup E se ukljui dolazna grana)

Obuhvatno stablo (stablo


razapinjanja)
Primjer: Formirati obuhvatno stablo obilaskom grafa po dubini poevi od vora 1

v[1] v[2] v[3] v[4] v[5] v[6]

v[1] v[2] v[3] v[4] v[5] v[6]


T

v[1] v[2] v[3] v[4] v[5] v[6]


T

v[1] v[2] v[3] v[4] v[5] v[6]


T

v[1] v[2] v[3] v[4] v[5] v[6]


T

v[1] v[2] v[3] v[4] v[5] v[6]

Obuhvatno stablo (stablo


razapinjanja)
/* formiranje obuhvatnog stabla obilaskom grafa po dubini */

Rezultat:

#include <stdio.h>
0 1 0 0
#define MAX 10
typedef struct G { int n; char nodes[MAX]; int ms[MAX][MAX]; } GRAF;
1 0 0 1
void ST_DFS(GRAF *g, GRAF *st)
0 0 0 1
{
0 1 1 0
int visit[MAX]={};
0 0 1 0
void dfs_visit(int u)
0 0 0 0
{
int v;
visit[u]=1;
for (v=0; v<g->n; v++)
if (g->ms[u][v] && !visit[v]) { st->ms[u][v]=st->ms[v][u]=1; dfs_visit(v); }
}
dfs_visit(0);
}
void main()
{
int i,j;
GRAF g = { 6, {'1','2','3','4','5','6'},
{ {0,1,1,1,0,0},{1,0,0,1,0,0},{1,0,0,1,1,0},{1,1,1,0,1,0},{0,0,1,1,0,1},
{0,0,0,0,1,0} }};
GRAF st = { 6, {'1','2','3','4','5','6'} };
ST_DFS(&g, &st);
for (i=0; i<st.n; i++) { printf("\n"); for (j=0; j<st.n; j++) printf("%d ", st.ms[i]
[j]); }
}

0
0
1
0
0
1

0
0
0
0
1
0

Minimalno obuhvatno stablo


Minimalno obuhvatno stablo S(U,E) je obuhvatno stablo minimalne
cijene/teine
cijena stabla:

w(u, v)

( u ,v )E

PRIM-ov ALGORITAM za MST

inkrementalno gradi MST, poevi od inicijalnog vora, dodavanjem


po jednu granu i jedan vor

Bira granu najmanje teine meu granama koje povezuju vorove


ve ukljuene u MST i vorove koji jo nisu
PRIM(G,s)
U={s}
E=
while (UV) do
find(u,v) min {w(u,v) : (uU)(v(V-U))}
U=U+{v}
E=E+{(u,v)}
end_while
MST=(U,E)

(minimal spanning tree MST)

Minimalno obuhvatno stablo


Primjer: Formirati minimalno obuhvatno stablo primjenom Primovog algoritma

50

50

80

70
B

20

60

70
B

50

50

80

60

70
B

50

E
3
0

20

70
B

50

80

60

60

50

60

20

C
50

80

E
3
0

20

70
B

50

60

A
3
0

20
F

70
B

50

50

80

60

50

E
3
0

20

20

20

80

20

3
0

20

20

20

3
0

20

50

50

3
0

20
F

20

E
3
0

20
B

60

Najkraa rastojanja
CILJ: Odrediti najkrae rastojanje (najkrai put) izmeu dva vora u grafu
teina grane reprezentuje rastojanje izmeu dva vora - w(i,j)
duina puta od vora x do vora y:

w( x, y )

w(i, j )

x y

najkrae rastojanje od vora x do vora y:

d ( x, y ) min w( x, y ) min w(i, j )


x y

ako vor y nije dostian iz vora x (ne postoji putanja), tada je w(x,y)=

w (i,j)
x

d (x,i)

j
w (i,j)

d (j,v)

Najkraa rastojanja
FLOYD-ov algoritam za najkrae rastojanje izmeu vorova u
grafu
ulaz u algoritam: matrica teina W

0, i j

w[i ][ j ] w(i, j ), (i, j ) E


, (i, j ) E

izlaz iz algoritma:

Osnovna ideja Floyd-ovog


algoritma:
Za svaki par vorova (i,j) treba
provjeriti da li je put preko nekog
drugog vora k krai
d (i,k)

d (k,j)

matrica najkraih rastojanja D


matrica prethodnika T

inicijalizacija matrice prethodnika

0, i j w(i, j )
i, i j w(i, j )

t[i ][ j ]

d (i,j)

d(i,j)>d(i,k)+d(k,j)
d(i,j)=d(i,k)+d(k,j)
t(i,j)=t(k,j)

Najkraa rastojanja
Primjer: Odrediti najkraa rastojanja u grafu primjenom Floyd-ovog algoritma

8
3

1
5

2
2

8
3

1
5

2
2

8
3

1
5

2
2

8
3

1
5

2
2

0 8 5
D 0 3 0
2 0

0 1 1
T 0 2 0 0
0 3 0

0 8 5
D1 3 0 8
2 0

0 1 1
T 1 2 0 1
0 3 0

0 8 5
D 2 3 0 8
5 2 0

0 1 1
T 2 2 0 1
2 3 0

Posljednji vor u putanji: 1

0 7 5
D 3 3 0 8
5 2 0

0 3 1
T 3 2 0 1
2 3 0

Posljednji vor u putanji: 3

Rekonstrukcija putanje:
Npr. (1,2):
Posljednji vor u putanji: 2
vor prije vora 2: t[1][2]=3
vor prije vora 3: t[1][3]=1
Putanja: 132
Npr. (2,1):
vor prije vora 1: t[2][1]=2
Putanja: 21
Npr. (2,3):
vor prije vora 3: t[2][3]=1
vor prije vora 1: t[2][1]=2
Putanja: 213

Najkraa rastojanja
/* Floydov algoritam za min rastojanja
*/
void FLOYD()
{
int i,j,k;
for (k=1; k<=n; k++)
for (i=1; i<=n; i++)
for (j=1; j<=n; j++)
if (d[i][j]>d[i][k]+d[k][j])
{
d[i][j]=d[i][k]+d[k][j];
t[i][j]=t[k][j];
}
}

/* rekonstrukcija putanje */
void putanja(int i, int j)
{
if (i==j)
printf("%d",i);
else
if (t[i][j]==0)
printf("Nema
putanje\n");
else
{
putanja(i,t[i][j]);
printf("%d",j);
}
}

You might also like