Escolar Documentos
Profissional Documentos
Cultura Documentos
∗ Transparências elaboradas por Charles Ornelas Almeida, Israel Guerra e Nivio Ziviani
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos 1
Conteúdo do Capítulo
7.1 Definições Básicas 7.5 Busca em Largura
7.2 O Tipo Abstrato de Dados Grafo 7.6 Ordenação Topológica
7.2.1 Implementação por meio de Ma- 7.7 Componentes Fortemente Conectados
trizes de Adjacência
7.8 Árvore Geradora Mínima
7.2.2 Implementação por meio de Lis-
7.8.1 Algoritmo Genérico para Obter a
tas de Adjacência Usando Apon-
Árvore Geradora Mínima
tadores
7.8.2 Algoritmo de Prim
7.2.3 Implementação por meio de Lis-
tas de Adjacência Usando Ar- 7.8.2 Algoritmo de Kruskal
ranjos 7.9 Caminhos mais Curtos
7.2.4 Programa Teste para as Três Im- 7.10 O Tipo Abstrato de Dados Hipergrafo
plementações 7.10.1 Implementação por meio de Matri-
7.3 Busca em Profundidade zes de Incidência
7.4 Verificar se Grafo é Acíclico 7.10.1 Implementação por meio de Listas
7.4.1 Usando Busca em Profundidade de Incidência Usando Arranjos
7.4.1 Usando o Tipo Abstrato de Da-
dos Hipergrafo
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos 2
Motivação
• Existe um tipo abstrato chamado grafo que é usado para modelar tais
situações.
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos 3
Aplicações
Conceitos Básicos
• Grafo: conjunto de vértices e arestas.
• Vértice: objeto simples que pode ter nome e outros atributos.
• Aresta: conexão entre dois vértices.
3 aresta
0 1 4
2 vértice
• Notação: G = (V, A)
– G: grafo
– V: conjunto de vértices
– A: conjunto de arestas
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 5
Grafos Direcionados
0 1 4
3 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 6
0 1 4
3 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 7
Grau de um Vértice
Ciclos
• Em um grafo direcionado:
– Um caminho (v0 , v1 , . . . , vk ) forma um ciclo se v0 = vk e o caminho
contém pelo menos uma aresta.
– O ciclo é simples se os vértices v1 , v2 , . . . , vk são distintos.
– O self-loop é um ciclo de tamanho 1.
– Dois caminhos (v0 , v1 , . . . , vk ) e (v0′ , v1′ , . . . , vk′ ) formam o mesmo
ciclo se existir um inteiro j tal que vi′ = v(i+j) mod k para
i = 0, 1, . . . , k − 1.
Ciclos
3 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 11
Componentes Conectados
e {3}.
3 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 12
Grafos Isomorfos
0 1
4 5 s w x t
7 6 v z y u
3 2
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 14
Subgrafos
0 1 4 1 4
3 2 5 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 15
0 1 0 1
2 2
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 16
0 1 4 0 1 4
3 2 5 3 2 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.1 17
Grafos Completos
Árvores
• Árvore livre: grafo não direcionado acíclico e conectado. É comum
dizer apenas que o grafo é uma árvore omitindo o “livre”.
• Floresta: grafo não direcionado acíclico, podendo ou não ser
conectado.
• Árvore geradora de um grafo conectado G = (V, A): subgrafo que
contém todos os vértices de G e forma uma árvore.
• Floresta geradora de um grafo G = (V, A): subgrafo que contém
todos os vértices de G e forma uma floresta.
(a) (b)
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2 20
i f ( ! ListaAdjVazia(v,Grafo) )
{ Aux = PrimeiroListaAdj (v,Grafo ) ;
FimListaAdj = FALSE ;
while ( ! FimListaAdj)
ProxAdj(&v , Grafo, &u, &Peso, &Aux, &FimListaAdj ) ;
}
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.1 24
Matriz de Adjacência
0 1 4 0 1 4
3 2 5 3 2 5
0 1 2 3 4 5 0 1 2 3 4 5
0 1 1 0 1 1
1 1 1 1 1 1
2 1 1 2 1 1
3 1 3
4 4
5 5
(a) (b)
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.2.1 26
3 0 1 5
5
0 1 1 3 2 7
1
7 2
3 2 3
0 1 5
5
0 1 0 5 2 7
1
7 1 7
2
3 2
3
Busca em Profundidade
Busca em Profundidade
b( / ) b( / ) b( / )
b( / ) 2 3 b( / ) 2 3 b( / ) 2 3
b( / ) b( / ) b( / )
b( / ) c(7/ ) p(7/8)
VisitaDfs é O(|A|).
Classificação de Arestas
Classificação de Arestas
• Classificação de arestas pode ser útil para derivar outros algoritmos.
• Na busca em profundidade cada aresta pode ser classificada pela cor
do vértice que é alcançado pela primeira vez:
– Branco indica uma aresta de árvore.
– Cinza indica uma aresta de retorno.
– Preto indica uma aresta de avanço quando u é descoberto antes de
v ou uma aresta de cruzamento caso contrário.
3/6 2/9 1/10
arv arv
2 1 0
3 cruz 4 cruz 5
4/5 7/8 11/12
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.4.1 58
Busca em Largura
Busca em Largura
Ordenação Topológica
• Pode ser vista como uma ordenação de seus vértices ao longo de uma
linha horizontal de tal forma que todas as arestas estão direcionadas
da esquerda para a direita.
Ordenação Topológica
• Os grafos direcionados acíclicos são usados para indicar precedências
entre eventos.
• Uma aresta direcionada (u, v) indica que a atividade u tem que ser
realizada antes da atividade v.
1/18 16/17 19/20
0 5 9
2/15 7/12
4/5 3 1 6 8 9/10
2 4 7
3/14 6/13 8/11
9 0 5 1 2 4 6 7 8 3
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.6 74
Ordenação Topológica
0 1 0 1 0,1,2
3 2 3 2 3
2. Obtem GT .
3 2 3 2 arv
cruz
4/5 3/6 7/8 2/5
1
0 0
6 5
1 1
1 2 2 3 1 2 2 3
2 2
5 6 4 4 4
4 5 4 5
3 3
(a) (b)
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.8.1 88
• A árvore começa por um vértice qualquer (no caso 0) e cresce até que
“gere” todos os vértices em V .
1 3 1 3 1 3
2 2 2
4 5 4 5 4 5
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.8.3 101
void Kruskal ( ) ;
{
1. S = ∅ ;
2. for (v=0;v < Grafo.NumVertices) CriaConjunto ( v ) ;
3. Ordena as arestas de A pelo peso;
4. for (cada ( u, v ) de A tomadas em ordem ascendente de peso)
5. i f ( EncontreConjunto (u) ! = EncontreConjunto ( v ) )
6. { S = S+ { (u, v ) } ;
7. Uniao ( u, v ) ;
}
}
Algoritmo de Dijkstra
• Mantém um conjunto S de vértices cujos caminhos mais curtos até um
vértice origem já são conhecidos.
• Produz uma árvore de caminhos mais curtos de um vértice origem s
para todos os vértices que são alcançáveis a partir de s.
• Utiliza a técnica de relaxamento:
– Para cada vértice v ∈ V o atributo p[v] é um limite superior do peso
de um caminho mais curto do vértice origem s até v.
– O vetor p[v] contém 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 vértice v ∈ V ,
– p[u] = 0, para o vértice origem s, e
– p[v] = ∞ para v ∈ V − {s}.
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.9 110
Relaxamento
5 1 6 5 1 6 5 1 6
2 3 2 3 2 3
2 2 3 6 2 3
5 1 6 5 1 6 5 1 6
2 3 2 3 2 3
5 2 3 5 2 3 5 2 3
(a) ∅ ∞ ∞ ∞ ∞ ∞
(b) {0} 0 1 ∞ 3 10
(c) {0, 1} 0 1 6 3 10
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.9 114
5 1 6 5 1 6 5 1 6
2 3 2 3 2 3
2 2 3 6 2 3
5 1 6 5 1 6 5 1 6
2 3 2 3 2 3
5 2 3 5 2 3 5 2 3
(d) {0, 1, 3} 0 1 5 3 9
(e) {0, 1, 3, 2} 0 1 5 3 6
(f) {0, 1, 3, 2, 4} 0 1 5 3 6
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.9 115
Algoritmo de Dijkstra
• Para cada vértice v, p[v] é o caminho mais curto obtido até o momento,
de v até o vértice raiz.
0 11
00
1
00
11
h0 (x)
Arestas
00
11
00
11
(1, 2, 4, 7)
0
1
00
11
0
1
2
00
11
3
0
1
h1 (x) 11 (1, 3, 5, 8)
00
0
1
0
1
0
1
(0, 2, 5, 9)
4
0
1
5 h2 (x)
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.10 120
0 11
00
1 h0 (x) Arestas 0 1 2
00
11 Arestas
|A|=3 (1,2,4) (1,3,5) (0,2,5)
00
11
00
11
(1, 2, 4, 7)
0
1
00
11 1
0
2 0
1
00
11
3
0
1
h1 (x) 0 (1, 3, 5, 8)
1 Prim 0 1 2 3 4 5
|V|=3 2 1 5 4 6 8
0
1
0
1
0
1
(0, 2, 5, 9)
4
0
1
5 h2 (x) Prox 0 1 2 3 4 5 6 7 8
r|A|=3x3=9 −1 0 −1 −1 −1 3 −1 −1 7
(a) (b)
Projeto de Algoritmos – Cap.7 Algoritmos em Grafos – Seção 7.10.2 133
i f ( ExisteAresta(&Aresta, &Grafo) )
p r i n t f ( "Sim\n" ) ;
else p r i n t f ( "Nao\n" ) ;
p r i n t f ( " Retira aresta : " ) ;
for ( j = 0; j < Grafo. r ; j ++) scanf( "%d∗[^\n] " , &Aresta . Vertices [ j ] ) ;
getchar ( ) ;
i f ( ExisteAresta(&Aresta, &Grafo) )
{ Aresta = RetiraAresta(&Aresta, &Grafo ) ;
p r i n t f ( "Aresta retirada : " ) ;
for ( i = 0; i < Grafo. r ; i ++) p r i n t f ( "%3d" , Aresta . Vertices [ i ] ) ;
p r i n t f ( "%4d\n" , Aresta .Peso) ;
}
else p r i n t f ( "Aresta nao existe \n" ) ;
ImprimeGrafo(&Grafo ) ;
return 0;
}