Escolar Documentos
Profissional Documentos
Cultura Documentos
Cap 7
Cap 7
7 Algoritmos em Grafos
Motivao
Muitas aplicaes em computao
necessitam considerar conjunto de conexes
entre pares de objetos:
Existe um caminho para ir de um objeto a
outro seguindo as conexes?
Algoritmos em Grafos
Transparncias
Aplicaes
Alguns exemplos de problemas prticos que
podem ser resolvidos atravs de uma
modelagem em grafos:
Ajudar mquinas de busca a localizar
informao relevante na Web.
Conceitos Bsicos
Grafo: conjunto de vrtices e arestas.
Vrtice: objeto simples que pode ter nome e
outros atributos.
Aresta: conexo entre dois vrtices.
3
aresta
1
vrtice
Notao: G = (V, A)
G: grafo
V: conjunto de vrtices
A: conjunto de arestas
Grafos Direcionados
Grafos No Direcionados
Self-loops no so permitidos.
Grau de um Vrtice
Em grafos no direcionados:
O grau de um vrtice o nmero de
arestas que incidem nele.
Um vrice de grau zero dito isolado ou
no conectado.
0
Um caminho de comprimento k de um
vrtice x a um vrtice y em um grafo
G = (V, A) uma seqncia de vrtices
(v0 , v1 , v2 , . . . , vk ) tal que x = v0 e y = vk , e
(vi1 , vi ) A para i = 1, 2, . . . , k.
O comprimento de um caminho o nmero
de arestas nele, isto , o caminho contm os
vrtices v0 , v1 , v2 , . . . , vk e as arestas
(v0 , v1 ), (v1 , v2 ), . . . , (vk1 , vk ).
Se existir um caminho c de x a y ento y
alcanvel a partir de x via c.
Em grafos direcionados
O grau de um vrtice o nmero de
arestas que saem dele (out-degree) mais
o nmero de arestas que chegam nele
(in-degree).
Ex.: O vrtice 2 tem
in-degree 2, out-degree
2 e grau 4.
Ciclos
Ciclos
Em um grafo direcionado:
Em um grafo no direcionado:
10
Componentes Conectados
Um grafo no direcionado conectado se
cada par de vrtices est conectado por um
caminho.
Os componentes conectados so as pores
conectadas de um grafo.
Um grafo no direcionado conectado se ele
tem exatamente um componente conectado.
Ex.: Os componentes so: {0, 1, 2}, {4, 5} e {3}.
0
11
12
Grafos Isomorfos
Um grafo G0 = (V 0 , A0 ) um subgrafo de
G = (V, A) se V 0 V e A0 A.
13
Subgrafos
G = (V, A) e G0 = (V 0 , A0 ) so isomorfos se
existir uma bijeo f : V V 0 tal que
(u, v) A se e somente se (f (u), f (v)) A0 .
14
15
Em um grafo no direcionado, u e v so
vizinhos se eles so adjacentes.
0
16
18
rvores
(a)
(b)
17
Grafos Completos
19
20
21
22
Matriz de Adjacncia
A matriz de adjacncia de um grafo
G = (V, A) contendo n vrtices uma matriz
n n de bits, onde A[i, j] 1 (ou verdadeiro)
se e somente se existe um arco do vrtice i
para o vrtice j.
Para grafos ponderados A[i, j] contm o
rtulo ou peso associado com a aresta e,
neste caso, a matriz no de bits.
23
24
0 1 2 3 4 5
0
1
1
1
1 1
2
1 1
3 1
4
5
0 1 2 3 4 5
0
1 1
1 1
1
2 1 1
3
4
5
(a)
(b)
26
: TipoPeso;
end;
MaxNumArestas = 4500;
type
TipoValorVertice = 0..MaxNumVertices;
TipoPeso
= integer ;
TipoGrafo = record
end; { ExisteAresta }
of TipoPeso;
NumVertices: 0 . .MaxNumVertices;
NumArestas : 0 . .MaxNumArestas;
end;
Apontador = TipoValorVertice ;
var i , j : integer ;
begin
for i := 0 to Grafo.NumVertices do
for j := 0 to Grafo.NumVertices do Grafo.mat[ i , j ] : = 0 ;
end;
25
27
28
var Peso
29
: TipoPeso;
begin
begin
i f Grafo.Mat[V1, V2] = 0
end;
end; { RetiraAresta }
end
else Aux : = Aux + 1;
i f Aux = Grafo.NumVertices
end; { LiberaGrafo }
end; { PrimeiroListaAdj }
procedure ImprimeGrafo ( var Grafo : TipoGrafo ) ;
{Operador para obter a l i s t a de adjacentes}
var i , j : integer ;
begin
write(
for i := 0 to Grafo.NumVertices1 do
begin
begin
Adj
write( i : 3 ) ;
writeln ;
end;
end; { ImprimeGrafo }
end; { ProxAdj }
30
5
0
1
7
2 7
0
1
7
1 5
1 3
2 7
1 7
1 5
0 5
5
0
);
31
32
33
type
TipoValorVertice = 0..MaxNumVertices;
TipoPeso
= integer ;
TipoItem
= record
var x : TipoItem ;
begin
x . Vertice : = V2; x .Peso : = Peso;
Vertice : TipoValorVertice ;
Peso
: TipoPeso;
end; { InsereAresta }
end;
Apontador
= ^Celula ;
Celula
= record
Item : TipoItem ;
var Aux: Apontador;
Prox : Apontador;
EncontrouAresta : boolean;
end;
TipoLista
begin
= record
Primeiro : Apontador;
EncontrouAresta : = false ;
Ultimo : Apontador;
end;
begin
TipoGrafo = record
Aux : = Aux^.Prox;
NumVertices : TipoValorVertice ;
end;
NumArestas: 0 . .MaxNumArestas;
ExisteAresta : = EncontrouAresta;
end;
end; { ExisteAresta }
34
var Peso
: TipoPeso;
EncontrouAresta : boolean;
x : TipoItem ;
begin
AuxAnterior : = Grafo. Adj [V1] . Primeiro ;
: TipoValorVertice ;
: TipoValorVertice ;
var Peso
: TipoPeso;
var Prox
: Apontador;
:= Prox^.Item . Vertice ;
:= Prox^.Item .Peso;
Prox
:= Prox^.Prox;
EncontrouAresta : = true ;
: TipoGrafo;
var Adj
Peso
Grafo.NumArestas : = Grafo.NumArestas 1;
end;
AuxAnterior : = Aux; Aux : = Aux^.Prox;
end;
end; { RetiraAresta }
35
36
37
begin
V
7
for i := 0 to Grafo.NumVertices1 do
begin
Cab
Prox
Peso
4
6
2
3
1
1
2
4
5
0
0
0
6
0
5
3
7
Cab
Prox
Peso
4
6
7
3
1
0
2
1
4
5
7
0
0
6
0
0
5
5
7
7
0
1
2
3
4
5
6
5
0
end;
end; { LiberaGrafo }
0
1
2
3
4
5
6
7
begin
write( Vertice , i :2 , : ) ;
i f not Vazia(Grafo. Adj [ i ] )
then begin
Aux : = Grafo. Adj [ i ] . Primeiro^.Prox;
while Aux <> n i l do
begin
write(Aux^.Item . Vertice :3 , ( ,Aux^.Item .Peso, ) ) ;
Aux : = Aux^.Prox;
end;
end;
writeln ;
end;
end; { ImprimeGrafo }
38
MaxNumArestas = 4500;
var Peso
MaxTam
= MaxNumVertices+2MaxNumArestas;
: TipoPeso;
type
TipoValorVertice = 0..MaxNumVertices;
begin
Pos:= Grafo. ProxDisponivel ;
TipoPeso
= integer ;
TipoTam
= 0..MaxTam;
TipoGrafo = record
Cab
Prox
Peso
else begin
Grafo. ProxDisponivel : = Grafo. ProxDisponivel + 1;
Grafo.Prox[Grafo.Cab[V1] ] : = Pos;
Grafo.Cab[Pos] : = V2;
ProxDisponivel : TipoTam;
NumVertices
: 0 . .MaxNumVertices;
NumArestas
: 0 . .MaxNumArestas;
end;
Apontador = TipoTam;
Grafo.Prox[Pos] : = 0 ;
Grafo.Cab[V1] : = Pos;
Grafo.Peso[Pos] : = Peso;
end;
end; { InsereAresta}
function ExisteAresta ( Vertice1 , Vertice2 : TipoValorVertice ;
var Grafo : TipoGrafo ) : boolean;
begin
Aux : = Grafo.Prox[ Vertice1 ] ; EncontrouAresta : = false ;
while (Aux < > 0) and ( EncontrouAresta = false ) do
begin
Grafo.Prox[ i ] : = 0 ; Grafo.Cab[ i ] : = i ;
Aux : = Grafo.Prox[Aux] ;
end;
end;
end;
ExisteAresta : = EncontrouAresta;
end; { ExisteAresta }
39
40
41
begin
begin
EncontrouAresta : = false ;
end; { ListaAdjVazia }
i f V2 = Grafo.Cab[Aux]
begin
end;
i f EncontrouAresta
end; { PrimeiroListaAdj }
: TipoValorVertice ;
end; { RetiraAresta }
: TipoGrafo;
var Adj
: TipoValorVertice ;
var Peso
: TipoPeso;
var Prox
: Apontador;
var i : integer ;
begin
begin
Adj
writeln (
Prox : = Grafo.Prox[Prox ] ;
i f Prox = 0 then FimListaAdj : = true ;
end; { ProxAdj }
Busca em Profundidade
for i := 0 to Grafo.NumVertices+2Grafo.NumArestas1 do
end; { ImprimeGrafo }
42
Busca em Profundidade
43
44
var Tempo
: TipoValorTempo;
: TipoValorVertice ;
Peso
: TipoPeso;
d, t
Aux
: Apontador;
Cor
: TipoValorVertice ;
begin
45
begin
then begin
for x := 0 to Grafo.NumVertices1 do
Antecessor[ x] := 1; end;
begin
for x := 0 to Grafo.NumVertices1 do
i f Cor[ v ] = branco
end; { BuscaEmProfundidade }
t [u] : = Tempo;
46
b( / )
c(1/ )
b( / )
b( / )
b( / ) 2
p(2/5)
p(1/6)
p(2/5)
b( / )
b( / ) 2
(a)
47
b( / )
b( / )
p(3/4) 2
(b)
p(3/4) 2
(g)
(f)
c(1/ )
c(2/ )
c(1/ )
c(2/ )
p(1/6)
p(2/5)
p(1/6)
p(2/5)
b( / )
b( / ) 2
b( / )
c(3/ ) 2
(c)
(d)
c(1/ )
c(2/ )
1
b( / )
p(3/4) 2
(e)
c(7/ )
p(3/4) 2
(h)
p(7/8)
p(3/4) 2
(i)
48
Existem:
1. Arestas de rvore: so arestas de uma
rvore de busca em profundidade. A aresta
(u, v) uma aresta de rvore se v foi
descoberto pela primeira vez ao percorrer a
aresta (u, v).
2/9
arv
arv
ret
arv
1/10
arv
cruz
avan
3
4/5
cruz
4
7/8
cruz
3/6
50
Classificao de Arestas
5
11/12
49
Classificao de Arestas
51
52
Busca em Largura
53
Busca em Largura
54
: TipoValorVertice ;
Cor[u] : = cinza ;
Dist
FFVazia ( Fila ) ;
Cor
var x
Dist [u] : = 0 ;
Item . Vertice : = u;
begin
for x := 0 to Grafo.NumVertices1 do
then begin
begin
Cor[ x ] : = branco ;
Dist [ x ] : = i n f i n i t o ;
u : = Item . vertice ;
Antecessor[ x] := 1;
end;
begin
for x := 0 to Grafo.NumVertices1 do
i f Cor[ v ] = branco
end; { BuscaEmLargura }
then begin
Cor[ v ] : = cinza ;
Antecessor[ v ] : = u;
Item . Vertice : = v ;
55
56
(b)
(a)
57
(e)
(f)
c(0)
b( )
b( )
p(0)
c(1)
b( )
p(0)
p(1)
b( )
p(0)
p(1)
c(0)
b( )
b( )
b( )
c(1)
b( )
b( )
p(1)
p(2)
b( )
p(1)
p(2)
b( )
F 0
0
F 1 3
1 1
(c)
(d)
F 4
0
(h)
(g)
p(0)
p(1)
b( )
p(0)
p(1)
b( )
p(0)
p(1)
p(0)
p(0)
p(1)
p(0)
c(1)
c(2)
b( )
p(1)
c(2)
b( )
p(1)
p(2)
c(1)
p(1)
p(2)
p(1)
F 3 2
1 2
F 2
2
F 5
1
58
59
60
Ordenao Topolgica
Ordenao Topolgica
Ordenao Topolgica
Algoritmo para ordenar topologicamente um
grafo direcionado acclico G = (V, A):
1. Chama BuscaEmProfundidade(G) para
obter os tempos de trmino t[u] para cada
vrtice u.
2. Ao trmino de cada vrtice insira-o na
frente de uma lista linear encadeada.
3. Retorna a lista encadeada de vrtices.
A Custo O(|V | + |A|), uma vez que a busca
em profundidade tem complexidade de tempo
O(|V | + |A|) e o custo para inserir cada um
dos |V | vrtices na frente da lista linear
encadeada custa O(1).
1/18
16/17
4/5 3
61
62
19/20
9
2/15
7/12
3/14
6/13
8/11
9/10
63
64
0,1,2
(a)
(b)
65
(c)
66
67
2. Obtem GT .
3. Chama BuscaEmProfundidade(GT ),
realizando a busca a partir do vrtice de
maior t[u] obtido na linha 1. Inicie uma nova
busca em profundidade a partir do vrtice de
maior t[u] dentre os vrtices restantes se
houver.
4. Retorne os vrtices de cada rvore da
floresta obtida como um componente
fortemente conectado separado.
2/7
1/6
0
cruz
3
4/5
2
3/6
(a)
ret
arv
cruz
arv cruz
1
arv
3
2
cruz
7/8
2/5
(b)
3/4
ret
2
arv
1
(c)
68
69
FGVazio(GrafoT) ;
GrafoT.NumVertices : = Grafo.NumVertices;
GrafoT.NumArestas
type
:= Grafo.NumArestas;
TipoTempoTermino = record
for v := 0 to Grafo.NumVertices1 do
then begin
NumRestantes: TipoValorVertice ;
end;
FimListaAdj : = false ;
begin
begin
i :=0;
end;
end;
for i := 0 to Grafo.NumVertices1 do
end; { GrafoTransposto }
i f TT.Restantes[ i ]
then i f Temp < TT. t [ i ]
then begin Temp : = TT. t [ i ] ; MaxTT : = i ; end;
end; { MaxTT }
70
: TipoPeso;
Tempo
: TipoValorTempo;
Aux
: Apontador;
x , VRaiz
: TipoValorVertice ;
: TipoValorVertice ;
d, t
Cor
Tempo := 0;
then begin
for x := 0 to Grafo.NumVertices1 do
begin Cor[ x ] : = branco ;
begin
Antecessor[ x] := 1; end;
TT.NumRestantes : = Grafo.NumVertices;
for x := 0 to Grafo.NumVertices1 do
TT.Restantes[ x ] : = true ;
while TT.NumRestantes > 0 do
begin
Antecessor[ v ] : = u;
VisitaDfs (v ) ;
VisitaDfs (VRaiz) ;
end;
end;
end; { BuscaEmProfundidadeCfc }
end;
end;
Cor[u] : = preto ; Tempo : = Tempo + 1;
t [u] : = Tempo;
71
72
73
74
6
1
5
3
2
5
4
(a)
2
4
S := S + {(u, v)}
5 return S ;
4
4
(b)
75
76
77
Um corte (V 0 , V V 0 ) de um grafo no
direcionado G = (V, A) uma partio de V .
p
0
p
V
V V
5
2
p
3
V V
2
4
b
6 4
5
3
78
(b)
0
79
0
0
5
1
2
4
(c)
2
1
(d)
0
0
0
2
2
1
2
1
3
2
1
2
1
6
(e)
(f)
2
1
2
1
2
1
4
2
1
5
80
begin
if n < 1
81
else begin
RetiraMin : = A[ 1 ] ;
Pos
A[ 1 ] : = A[n ] ;
: Vetor ;
n : = n 1;
u, v
: TipovalorVertice ;
Pos[A[n ] . chave] : = 1 ;
Refaz ( 1 , n, A) ;
end;
end; { Retira }
label 999;
var i : Indice ;
j : integer ;
x : Item ;
begin
var x : Item ;
i : = Esq;
j := 2 i ;
x : = A[ i ] ;
begin
begin
i f j < Dir
else begin
A[ i ] : = A[ j ] ;
i := j ;
Pos[A[ j ] .Chave] : = i ;
do begin
j := 2 i ;
x : = A[ i div 2 ] ;
end;
A[ i div 2 ] : = A[ i ] ;
A[ i ] : = x ; Pos[ x .Chave] : = i ;
end; { Refaz }
i : = i div 2;
end;
end;
end; { DiminuiChave }
82
FimListaAdj : = false ;
83
84
85
(a)
(b)
0
6
1
5
3
1
2
2
5
(c)
(e)
4
4
2
4
2
5
(f)
0
86
(d)
0
6
4
2
5
87
88
89
Primeiro refinamento:
procedure Kruskal ;
1.
S := ;
2.
3.
4.
5.
6.
S := S + {(u, v)} ;
7.
Uniao ( u, v ) ;
end;
end;
90
Pk
i=1
p(vi1 , vi )
min p(c) : u ; v
se existir caminho de u a v
caso contrrio
91
92
93
Algoritmo de Dijkstra
Mantm um conjunto S de vrtices cujos
caminhos mais curtos at um vrtice origem
j so conhecidos.
Produz uma rvore de caminhos mais curtos
de um vrtice origem s para todos os vrtices
que so alcanveis a partir de s.
Utiliza a tcnica de relaxamento:
Para cada vrtice v V o atributo p[v]
um limite superior do peso de um caminho
mais curto do vrtice origem s at v.
O vetor p[v] contm uma estimativa de um
caminho mais curto.
O primeiro passo do algoritmo inicializar os
antecessores e as estimativas de caminhos
mais curtos:
Antecessor[v] = nil para todo vrtice
v V,
p[u] = 0, para o vrtice origem s, e
p[v] = para v V {s}.
94
Relaxamento
O relaxamento de uma aresta (u, v) consiste
em verificar se possvel melhorar o melhor
caminho at v obtido at o momento se
passarmos por u.
Se isto acontecer, p[v] e Antecessor[v] devem
ser atualizados.
i f p[ v] > p[u] + peso da aresta ( u, v)
then p[ v ] = p[u] + peso da aresta ( u, v)
Antecessor[ v ] : = u
95
96
(a)
(b)
for v := 0 to Grafo.NumVertices1 do
2.
p[ v ] : = I n f i n i t o ;
3.
Antecessor[ v] := 1;
4.
97
1
1
10
0
0
1
1
10
10
4
p[Raiz ] : = 0 ;
5.
S := ;
7.
5
2
8.
u : = RetiraMin(A) ;
S := S + u
10.
for v ListaAdjacentes [u ] do
12.
1
1
2
6
10
4
10
Antecessor[ v ] : = u
6
3
(c)
11.
13.
6
3
6
3
Iterao
d[0]
d[1]
d[2]
d[3]
d[4]
(a)
(b)
{0}
10
(c)
{0, 1}
10
98
(e)
0
0
1
1
3
1
5
2
5
10
9
4
10
6
4
3
1
2
(f)
Algoritmo de Dijkstra
0
0
6
2
0
0
1
1
1
2
6
4
5
5
10
6
2
Iterao
d[0]
d[1]
d[2]
d[3]
d[4]
(d)
{0, 1, 3}
(e)
{0, 1, 3, 2}
(f)
{0, 1, 3, 2, 4}
99
100
101
..
.
: Vetor ;
u, v
: TipovalorVertice ;
begin
u : = RetiraMinInd(A) .Chave;
ItensHeap[u] : = false ;
i f not ListaAdjVazia (u,Grafo)
then begin
FimListaAdj : = false ;
begin { Dijkstra }
then begin
for u := 0 to Grafo.NumVertices do
begin {Constroi o heap com todos os valores igual a I n f i n i t o }
p[ v ] : = p[u] + Peso;
Antecessor[u] := 1; p[u] : = I n f i n i t o ;
end;
end;
end;
p[Raiz ] : = 0 ;
end;
Constroi(A) ;
end; { Dijkstra }
..
.
Antecessor[ v ] : = u;
102