Professional Documents
Culture Documents
P-08: Grafovi
doc. dr Draen
Branin
2014/15
P-08: Grafovi
Sadraj predavanja
Reprezentacija grafa
Obilazak grafa
Obuhvatno stablo
Najkraa rastojanja
grane
GRAF:
grane
neusmjerene (simetrine) i
usmjerene (asimetrine)
neusmjereni graf
usmjereni graf
vorovi
mjeoviti graf
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
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:
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
Obilazak grafa
Obilazak grafa po dubini:
strategija obilaska:
Obilazak grafa
Primjer: Obii dati graf po dubini poevi od vora 1
Rezultat obilaska:
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);
Rezultat obilaska:
124356
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
w(u, v)
( u ,v )E
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
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
izlaz iz algoritma:
d (k,j)
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
0 7 5
D 3 3 0 8
5 2 0
0 3 1
T 3 2 0 1
2 3 0
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);
}
}