w8grafy alg, studia, Semestr 2, Algorytmy i struktury danych AISD, AIDS


Dr Aleksander Klosow

PWSZ Legnica

Algorytmy i Struktury Danych

Wykład

TEORIA GRAFÓW. ALGORYTMY GRAFOWE.

[1] www.binboy.org

[2] www.algorytm.cad.pl

[3] P.Wróblewski, Algorytmy, struktury danych i techniki programowania

ALGORYTMY GRAFOWE

KLASYFIKACJA WSTĘPNA

OPERACJE NA GRAFACH

POSZUKIWANIE WIERZCHOŁKA

POSZUKIWANIE DROGI

INNE

PRZESZUKIWANIE GRAFÓW

Przeszukiwanie w głąb (DFS) Przeszukiwanie w wszerz (BFS)

0x01 graphic

0x01 graphic

Istnieją dwie taktyki 'chodzenia' po grafie BFS oraz DFS. Algorytmy te mogą być częścią innych algorytmów, n.p. poszukiwanie ścieżek, poszukiwanie wierzchołków, budowanie drzew rozpinających.

0x08 graphic
PRZESZUKIWANIE GRAFÓW

Przeszukiwanie w wszerz (BFS)

funkcja BreadthFirstSearch (Graf G, Wierzchołek s)

dla każdego wierzchołka u z G:

kolor[u] = biały

odleglosc[u] = inf

rodzic[u] = NIL

kolor[s] = SZARY

odleglosc[s] = 0

rodzic[s] = NIL

Q.push(s)

dopóki kolejka Q nie jest pusta:

u = Q.pop()

dla każdego v z listy sąsiedztwa u:

0x08 graphic
0x08 graphic
jeżeli v jest biały:

kolor[v] = SZARY

odleglosc[v] = odleglosc[u] + 1

rodzic[v] = u

Q.push(v)

kolor[u] = CZARNY

ZNALEZIENIE DROGI W GRAFIE

Dano graf: macierz sąsiedztwa - zmodyfikowana

Zadanie: znaleźć drogę od wierzchołka A do wierzchołka B

0x01 graphic

 

0

1

2

3

4

5

0

 

1

2

 

 

 

1

 

 

2

 

 

 

2

 

 

 

 

4

 

3

 

 

 

 

 

 

4

 

 

 

3

 

5

5

 

 

 

 

 

 

Rozwiązanie:

  1. Przekształcić macierz (wykorzystując domknięcie grafu wg algorytmu Roy-Warszalla)

  2. Wypisać drogę przechodząc po grafie.

ZNALEZIENIE DROGI W GRAFIE, c.d.

Etap 1. Przekształcenie macierzy wejściowej

void Mod(int g[N][N])

{

int x,y,z;

for(x=0;x<N;x++)

for(y=0;y<N;y++)

if(g[y][x])

for(z=0;z<N;z++)

if(g[y][z]==0 && g[x][z]!=0) g[y][z] = g[y][x];

}

 

0

1

2

3

4

5

0

 

1

2

2

2

2

1

 

 

2

2

2

2

2

 

 

 

4

4

4

3

 

 

 

 

 

 

4

 

 

 

3

 

5

5

 

 

 

 

 

 

ZNALEZIENIE DROGI W GRAFIE, c.d.

Etap 2. Wypisanie drogi:

void Droga(int _od, int _do, int g[N][N])

{

int k;

int x=_od, y = _do;

if(g[x][y]==0) printf("\nDroga od %d do %d: Drogi nie ma!",x,y);

else {

printf("\nDroga od %d do %d: %d ",_od,_do,_od);

k=x;

while(k!=y)

{

k = g[k][y];

printf("%d ",k);

}

}

}

ZNALEZIENIE DROGI W GRAFIE, c.d.

Program główny::

void main()

{

// jezeli istnieje krawedz (x-y) to r[x][y] = y

int r[N][N]={ {0,1,2,0,0,0},

{0,0,2,0,0,0},

{0,0,0,0,4,0},

{0,0,0,0,0,0},

{0,0,0,3,0,5},

{0,0,0,0,0,0}

};

int _od = 1, _do = 5;

clrscr();

Mod(r);

Droga(_od,_do,r);

getch();

}

0x01 graphic

ALGORYTM ROY-WARSZALLA

Algorytm Roy-Warszalla służy do wyznaczenia domknięcia przechodniego grafu.

Graf nazywamy przechodnim jeżeli każda droga o długości większej lub

równej 1 jest podtrzymywana przez jakąś krawędź.

Domknięcie grafu pozwala odpowiedzieć na pytanie:

"czy możliwe jest przejście po krawędziach grafu od jednego wierzchołka do drugiego".

 

0

1

2

3

4

5

0

 

1

1

 

 

 

1

 

 

1

 

 

 

2

 

 

 

 

1

 

3

 

 

 

 

 

 

4

 

 

 

1

 

1

5

 

 

 

 

 

 

 

0

1

2

3

4

5

0

 

1

1

1

1

1

1

 

 

1

1

1

1

2

 

 

 

1

1

1

3

 

 

 

 

 

 

4

 

 

 

1

 

1

5

 

 

 

 

 

 

0x01 graphic

Macierz sąsiedztwa

Macierz z domknięciem

Macierz z domknięciem pozwala wyciągnąć pewne wnioski:

ALGORYTM ROY-WARSZALLA

Realizacja w języku C

void Roy(int g[N][N])

{

int x,y,z;

for(x=0;x<N;x++)

for(y=0;y<N;y++)

for(z=0;z<N;z++)

if(g[y][z]==0)

g[y][z] = g[y][x]*g[x][z];

}

void main()

{

int r[N][N]={ {0,1,1,0,0,0},

{0,0,1,0,0,0},

{0,0,0,0,1,0},

{0,0,0,0,0,0},

{0,0,0,1,0,1},

{0,0,0,0,0,0}

};

clrscr();

// --------------

Pokaz(r);

Roy(r);

Pokaz(r);

// --------------

getch();

}

POSZUKIWANIE NAJKRÓTSZYCH ŚCIEŻEK

ALGORYTM FLOYDA

Algorytm Floyda służy do obliczenia najkrótszej drogi w grafie między wierzchołkami.

Nie daje odpowiedzi jaka to jest droga.

0x01 graphic

 

0

1

2

3

4

5

0

0

10

30

 

 

 

1

 

0

15

 

 

30

2

 

 

0

10

5

 

3

 

 

 

0

 

 

4

 

 

 

5

0

10

5

 

 

 

 

 

0

Macierz sąsiedztwa

 

0

1

2

3

4

5

0

0

10

25

35

30

40

1

 

0

15

25

20

30

2

 

 

0

10

5

15

3

 

 

 

0

 

 

4

 

 

 

5

0

10

5

 

 

 

 

 

0

Wynik A. Floyda

ALGORYTM FLOYDA

Realizacja w języku C

// Algorytm Floyda

#include <stdio.h>

#include <conio.h>

#define N 6

#define INF 1000

#define min(a,b) (a<=b?a:b)

void Floyd(int g[N][N])

{

int x,y,z;

for(x=0;x<N;x++)

for(y=0;y<N;y++)

for(z=0;z<N;z++)

g[y][z] = min(g[y][z],g[y][x]+g[x][z]);

}

void main()

{

int r[N][N]={

{0,10,30,INF,INF,INF},

{INF,0,15,INF,INF,30},

{INF,INF,0,10,5,INF},

{INF,INF,INF,0,INF,INF},

{INF,INF,INF,5,0,10},

{INF,INF,INF,INF,INF,0}

};

clrscr();

// --------------

Pokaz(r);

Floyd(r);

Pokaz(r);

// --------------

getch();

}

1

4

2

3

5

6

0

Q

0

1

1

4

2

3

5

6

1

1

0

Q

1

2

5

1

Q

1

4

2

3

5

6

2

0

1

1

2

2

6

2



Wyszukiwarka