Sie sind auf Seite 1von 85

Teoria dos Grafos

Buscas em grafos
Profª. Dayse Silveira de Almeida
daysesa@ufg.br

Universidade Federal de Goiás (UFG)/Regional Catalão


Curso de Ciência da Computação
2019.2
2/69

Créditos
• Animações baseadas no material do MIT’s Open
Courseware do Prof. Jim Orlin do Massachusetts Institute
of Technology
3/69

Roteiro
• Introdução
• Representação de grafos
• Busca em largura
• Busca em profundidade
4/69

Introdução
• Muitas aplicações em computação necessitam considerar
o conjunto de conexões entre pares de objetos
• Relacionamentos derivados dessas conexões podem ser
usados para responder:
• Existe um caminho para ir de um objeto a outro?
• Qual é a menor distância entre um objeto e outro?
• Quantos outros objetos podem ser alcançados a partir de um
determinado objeto?

• Tais situações podem ser modeladas usando grafos.


5/69

Representação de Grafos
• Definição: um grafo é constituído de um conjunto de
vértices e um conjunto de arestas conectando pares de
vértices, ou seja, G=(V, A)

• Duas maneiras para representar G=(V, A):


• Coleção de listas de adjacências – modo compacto para
representar grafos esparsos
• |A| é muito menor que |V|2

• Matriz de adjacências – quando o grafo é denso ou quando é


necessário saber com rapidez se existe uma aresta conectando
dois vértices
• |A| está próximo de |V|2
6/69

Representação de Grafos
Lista de Adjacências
• Consiste em um vetor adj de |V| listas, uma para cada
vértice V
• Para cada u Є V, adj[u] contém ponteiros para todo v, tal
que (u,v) Є A

1 2 5 /
1 2 2 1 5 3 4 /
3 3 2 4 /
5 4 4 2 5 3 /
5 4 1 2 /
7/69

Representação de Grafos
Matriz de Adjacências
• Supomos que os vértices são numerados 1, 2, ..., |V| de
alguma maneira
• A representação de um grafo consiste em uma matriz |V|
x |V| M = (aij) tal que
• aij = 1 se (i, j) Є A
0 em caso contrário
1 2 3 4 5
1 2 1 0 1 0 0 1
2 1 0 1 1 1
3 3 0 1 0 1 0
4 0 1 1 0 1
5 4 5 1 1 0 1 0
8/69

Representação de Grafos
Lista e Matriz de Adjacências
• Lista
• Orientado: soma dos comprimentos das listas de adjacências é |A|
• Não orientado: 2|A|
• Quantidade de memória: Θ (V + A)
• Matriz = Θ (V2)

1 2 4 / 1 2 3 4 5 6
1 2 3 2 1 0 1 0 1 0 0
5
2 0 0 0 0 1 0
3 6 5 / 3 0 0 0 0 1 1
4 0 1 0 0 0 0
5 4 6 4 5
2 0 0 0 1 0 0
6 0 0 0 0 0 1
5 4
6 6
9/69

Busca em Largura
• A busca em largura (breadth-first search) expande a
fronteira entre vértices descobertos e não descobertos
uniformemente através da largura da fronteira.

• O algoritmo descobre todos os vértices a um distância k


do vértice origem antes de descobrir qualquer vértice a
uma distância k+1.
10/69

Busca em Largura
• Algoritmo para caminhar em grafo
• Base para algoritmos importantes em grafos:
• Algoritmo de Prim para obter a árvore espalhada mínima
• Algoritmo de Dijkstra para obter os caminhos mais curtos de um
vértice a todos os outros

• Dado um grafo G = (V, A) e um vértice de origem s;


• Explora sistematicamente as arestas até descobrir cada vértice
acessível a partir de s
• Descobre todos os vértices a uma distância k de s
• Descobre todos os vértices a uma distância k+1 de s
• G pode ser direcionado ou não
11/69

Busca em Largura
• Para acompanhar o processo do algoritmo, cada vértice é
marcado com as cores VERDE, AMARELO e VERMELHO
• Início – todos os vértices são VERDES
• Vértice descoberto na primeira vez – AMARELO
• Vértices VERMELHOS têm todos os vértices adjacentes, descobertos
(AMARELOS ou VERMELHOS)
• AMARELOS – fronteira entre os vértices descobertos e os não
descobertos

• Produz a árvore de busca em largura com raiz s e todos os


vértices acessíveis
• Se um vértice VERDE v é descoberto a partir de um vértice u já
descoberto, v e a aresta (u, v) são adicionados à árvore
• u é predecessor ou pai de v
12/69

Busca em Largura
• Algoritmo para G = (V, A):

• Lista de adjacências
• cor[u] – armazena a cor de cada u Є V
• π[u] – armazena o predecessor de u
• d[u] – armazena a distância de s até u
• Q – estrutura tipo fila
13/69

Busca em Largura
Algoritmo BL
1. para cada vértice u Є V[G] – {s} faça
2. cor[u] := VERDE
3. d[u] := ∞
4. π[u] := NULL
5. fim para
6. cor[s] := AMARELO
7. d[s] := 0
8. π[s] := NULL
9. Q := Ø
10. ENFILEIRA(Q,s)
11. enquanto Q ≠ Ø faça
12. u := DESENFILEIRA(Q)
13. para cada v := ajd[u] faça
14. se cor[v] == VERDE então
15. cor[v] := AMARELO
16. d[v] := d[u] + 1
17. π[v] := u
18. ENFILEIRA(Q, v)
19. fim se
20. fim para
21. cor[u] := VERMELHO
22. fim enquanto
14

Inicializar
2 4 8

0 1 5 7

Marcar todos
cor[1] := os
AMARELO
vértices como 9
d[1] := 0 3 6
VERDE
π[1] := NULL
Marcar vértice s
Q := {1}

Q 1
15

Selecionar um vértice u em Q
2 4 8

0 1 5 7

Em busca em
largura, u é o 9
primeiro elemento 3 6
em Q

Q 1
16

Se vértice v é adj[u]
1 4
2 8

0 1 5 7

Marcar
d[2] vértice
:= d[1]
Selecionar + 1v
uma
(u,v)
π(v) admissível
:= u v a Q 9
Adicionar 3 6

Q 1 2
17

Se vértice v é adj[u]
1 4
2 8

0 1 5 7
1
Marcar
d[5] := vértice
Selecionar 1 v
0 +uma
(u,
π(v)v):=
admissível
u 9
Adicionar v a Q 3 6

Q 1 2 5
18

Se vértice v é adj[u]
1 4
2 8

0 1 5 7
1
Marcar
d[3] := vértice
1 v
0 + uma
Selecionar
(u,v) admissível
π(v) := u v a Q 9
Adicionar 3 6
1

Q 1 2 5 3
19

Se vértice v é adj[u]
1 4
2 8

0 1 5 7
1

Remover vértice u 3 6 9
de Q 1

Q 1 2 5 3
20

Selecionar vértice u
1 4
2 8

0 1 5 7
1

O primeiro 3 6 9
elemento em Q é 1
vértice u

Q 1 2 5 3
21

Se vértice v é adj[u]
2
1 4
2 8

0 1 5 7
1

Marcar
d[4] vértice
:= d[2]
Selecionar + 1v =
uma
π(v)v):=
2(u, u
admissível 9
3 6
1
Adicionar v a Q

Q 1 2 5 3 4
22

Se vértice u não tem aresta admissível


2
1 4
2 8

0 1 5 7
1

Remover vértice u
de Q 9
3 6
1

Q 1 2 5 3 4
23

Selecionar um vértice
2
1 4
2 8

0 1 5 7
1

O primeiro
elemento em Q é 9
3 6
o vértice 5 1

Q 1 2 5 3 4
24

Se vértice v é adj[u]
2
1 4
2 8

0 1 5 7
1

Selecionar
d[5]uma
d[6] := vértice
Marcar + v1 =
(u,
2 v) admissível 9
π(6) := 5 3 6
Adicionar v a Q 1 2

Q 1 2 5 3 4 6
25

Se vértice u não tem aresta admissível


2
1 4
2 8

0 1 5 7
1

Remover vértice u
de Q 9
3 6
1 2

Q 1 2 5 3 4 6
26

Selecionar vértice 3
2
1 4
2 8

0 1 5 7
1
Remover vértice
Vértice 3 não tem3
de
adjQ
admissível
3 6 9
1 2

Q 1 2 5 3 4 6
27

Selecionar um vértice
2
1 4
2 8

0 1 5 7
1

v:=4
3 6 9
1 2

Q 1 2 5 3 4 6
28

Se vértice v é adj[u]
2
1
2 4 8 3

0 1 5 7
1
d[8] := vértice
Marcar 3 umav
Selecionar
(u,
π(v)v):=
admissível
u 8aQ 9
Adicionar 3 6
1 2

Q 1 2 5 3 4 6 8
29

Se vértice u não tem aresta admissível


2
1
2 4 8 3

0 1 5 7
1

Remover vértice 4
de Q 9
3 6
1 2

Q 1 2 5 3 4 6 8
30

Selecionar vértice u
2
1
2 4 8 3

0 1 5 7
1

u := 6

3 6 9
1 2

Q 1 2 5 3 4 6 8
31

Se vértice v é adj[u]
2
1
2 4 8 3

0 1 5 7 3
1
d[7] := vértice
3 umav
Selecionar
Marcar
(u, v) admissível 9
π(7) := 6 7 a Q
Adicionar 3 6
1 2

Q 1 2 5 3 4 6 8 7
32

Se vértice v é adj[u]
2
1
2 4 8 3

0 1 5 7 3
1
Marcar
d[9] := vértice
3 umav
Selecionar
(u,
π(v)v):=
admissível
u 9aQ 9
adicionar 3 6
1 2 3

Q 1 2 5 3 4 6 8 7 9
33

Se vértice u não tem aresta admissível


2
1
2 4 8 3

0 1 5 7 3
1

Remover vértice u
de Q 9
3 6
1 2 3

Q 1 2 5 3 4 6 8 7 9
34

Selecionar vértice 8
2
1
2 4 8 3

0 1 5 7 3
1

Vértice 8 não uma


aresta adjacente 9
admissível; 3 6
1 2 3
remover 8 de Q

Q 1 2 5 3 4 6 8 7 9
35

Selecionar vértice 7
2
1
2 4 8 3

0 1 5 7 3
1

Vértice 7 não uma


aresta adjacente 9
admissível; 3 6
1 2 3
reomover 7 de Q

Q 1 2 5 3 4 6 8 7 9
36

Selecionar vértice 9
2
1
2 4 8 3

0 1 5 7 3
1

Vértice 9 não uma


aresta adjacente 9
admissível; 3 6
1 2 3
remover 9 de Q

Q 1 2 5 3 4 6 8 7 9
37

Selecionar vértice 9
2
1
2 4 8 3

0 1 5 7 3
1

Vértice 9 não uma


aresta adjacente 9
admissível; 3 6
1 2 3
remover 9 de Q

Q 1 2 5 3 4 6 8 7 9
38/69

Busca em Largura - Complexidade


• Cada vértice é colocado e retirado da fila uma vez – o tempo
dedicado a operações de fila é O(V)

• Lista de adjacências:
• A lista de adjacências de cada vértice ser examinada somente quando
o vértice é desinfileirado - a lista de adjacências de cada vértice é
examinada no máximo uma vez: d1+...+dn = |A|
• A soma dos comprimentos de todas as listas é O(A) - é gasto no
máximo O(A) na varredura total das listas
• Tempo de execução de BL é O(|V|+|A|).

• Se uma matriz de adjacências é utilizada, é necessário O(|V|)


para cada nó visitado.
• O tempo total é O(|V|+|V|2).
39/69

Exercícios
1. Faça a busca em largura no grafo abaixo a partir do
vértice a.
40/69

Exercícios
2. Mostre os valores de d (distância) e π (predecessor)
que resultam da execução da busca em largura no
grafo direcionado da figura abaixo, usando o vértice 3
como origem.
41/69

Exercícios
3. Faça uma busca em largura a partir do vértice 0 no
grafo não-dirigido definido pelas arestas 0-1 1-2 1-4 2-
3 2-4 2-9 3-4 4-5 4-6 4-7 5-6 7-8 7-9. Imagine que o
grafo é representado por sua matriz de adjacências e
portanto os vizinhos de cada vértice estão em ordem
crescente de nomes. Diga em que ordem os vértices
foram descobertos.
42/69

Exercícios
4. Faça uma busca em largura a partir do vértice 0 do
grafo não-dirigido definido pelas arestas 0-2 2-6 6-4 4-
5 5-0 0-7 7-1 7-4 3-4 3-5. Suponha que o grafo é
representado por sua matriz de adjacências. Repita a
busca começando pelo vértice 4.
43/69

Busca em Profundidade
• A busca em profundidade (depth-first search) é um algoritmo
para caminhar no grafo.

• Estratégia:
• Buscar, sempre que possível, o vértice mais profundo no grafo
• As arestas são exploradas a partir do vértice v mais recentemente
descoberto que ainda possui arestas não exploradas saindo dele
• Quando todas as arestas adjacentes a v tiverem sido exploradas, a
busca anda para trás para explorar vértices que saem do predecessor
de v
• O processo continua até que sejam descobertos todos os vértices a
partir do vértice original

• Base para algoritmos importantes:


• Verificação de grafos acíclicos
• Ordenação topológica
• Componentes fortemente conectados
44/69

Busca em Profundidade
BP(G)
1. para cada vértice u := V[G] faça
2. cor[u] = VERDE
3. π[u] := NULL
4. fim para
5. para cada vértice u Є V[G] faça
6. se cor[u] == VERDE então
7. next := 1
8. BP-visita(u, next)
9. fim se
10. fim para

BP-visita(u, next)
1. cor[u] := AMARELO
2. order[u] := next
3. para cada v Є ajd[u] faça
4. se cor[v] == VERDE então
5. π[v] := u
6. next := next + 1
7. BP-visita(v, next)
8. fim se
9. fim para
10. cor[u] := VERMELHO
45

Inicializar
2 4 8

1 1 5 7

π[1] = 0todos os
Marcar
vértices; 9
next := 1 3 6
Marcar
order[u]vértice
= next u
P := {1}

P 1
46

Selecionar um vértice u em P
2 4 8

1 1 5 7

Na busca em
profundidade, u é o 9
último elemento em 3 6
P

P 1
47

Se vértice u é adjacente a um vértice admissível


2 4
2 8

1 1 5 7

Marcar
next := vértice
Selecionar uma
next +v1
(u,
π(v)v):=
admissível
u 9
order[v] := next 3 6

Adicionar v a P

P 1 2
48

Selecionar o último vértice em Q


2 4
2 8

1 1 5 7

3 6 9
Vértice 2 é
selecionado

P 1 2
49

Se vértice u é adjacente a um vértice admissível


2 4 3
2 8

1 1 5 7

next := vértice
Marcar next
Selecionar + v1
uma
π(v)
(u, v):=admissível
u next
order[v]:= 9
3 6
Adicionar v a P

P 1 2 4
50

Selecionar o último vértice em Q


2 4 3
2 8

1 1 5 7

Selecionar o
último vértice em 9
P 3 6

P 1 2 4
51

Se vértice u é adjacente a um vértice admissível


2 4 3
2 8 4

1 1 5 7

Selecionar
Marcar
next := vértice
nextuma
+ v1
(u, v) admissível 9
pred(v) :=:=
order[v] u next 3 6

Adicionar v a P

P 1 2 4 8
52

Selecionar o último vértice em Q


2 4 3
2 8 4

1 1 5 7

Selecionar o
último vértice em 9
P 3 6

P 1 2 4 8
53

Se vértice u não tem adjacente admissível


2 4 3
2 8 4

1 1 5 7

Remover vértice v
de P 9
3 6

P 1 2 4 8
54

Selecionar o último vértice em Q


2 4 3
2 8 4

1 1 5 7

Selecionar o
último vértice de 9
P 3 6

P 1 2 4 8
55

Se vértice u é adjacente a um vértice admissível


2 4 3
2 8 4

5
1 1 5 7

Marcar
next :=vértice
Selecionarnext
uma+v1
(u,
π(v)v):=
admissível
u 9
order[v] := next 3 6
Adicionar v a P

P 1 2 4 8
5
56

Selecionar o último vértice em Q


2 4 3
2 8 4

5
1 1 5 7

Selecionar o
último vértice em 9
P 3 6

P 1 2 4 8
5
57

Se vértice u é adjacente a um vértice admissível


2 4 3
2 8 4

5
1 1 5 7

next :=vértice
Marcar next
Selecionar +v1
uma
(u, v) admissível
π(v) := u := next 9
order[v] 3 6
Adicionar v a P 6

P 1 2 4 8
5 6
58

Selecionar o último vértice em Q


2 4 3
2 8 4

5
1 1 5 7

Selecionar vértice
6 9
3 6
6

P 1 2 4 8
5 6
59

Se vértice u é adjacente a um vértice admissível


2 4 3
2 8 4

5
1 1 5 7

Marcar
next :=vértice
Selecionar uma
next +v1
(u, v) admissível
π(v) := u := next
order[v] 3 6 9
6 7
Adicionar v a P

P 1 2 4 8
5 6 9
60

Selecionar o último vértice em Q


2 4 3
2 8 4

5
1 1 5 7

Selecionar vértice
9 9
3 6
6 7

P 1 2 4 8
5 6 9
61

Se vértice u é adjacente a um vértice admissível


2 4 3
2 8 4

5
1 1 5 7 8

Marcar
next :=vértice
next
Selecionar +v1
uma
(u, v) admissível
π(v) := u := next 9
order[v] 3 6
6 7
Adicionar v a P

P 1 2 4 8
5 6 9 7
62

Selecionar o último vértice em Q


2 4 3
2 8 4

5
1 1 5 7 8

Selecionar vértice
7 9
3 6
6 7

P 1 2 4 8
5 6 9 7
63

Se vértice u não tem adjacente admissível


2 4 3
2 8 4

5
1 1 5 7 8

Remover vértice 7
de P 9
3 6
6 7

P 1 2 4 8
5 6 9 7
64

Selecionar vértice 9
2 4 3
2 8 4

5
1 1 5 7 8

Remover
Mas vértice
vértice
9 não9
de
é adjacente
P a um 9
vértice admissível 3 6
6 7

P 1 2 4 8
5 6 9 7
65

Selecionar vértice 6
2 4 3
2 8 4

5
1 1 5 7 8

Remover
Mas vértice
vértice
6 não6
de
é adjacente
P a um 9
vértice admissível 3 6
6 7

P 1 2 4 8
5 6 9 7
66

Selecionar vértice 5
2 4 3
2 8 4

5
1 1 5 7 8

Remover vértice
Mas vértice 5 não5
de P
é adjacente a um
3 6 9
vértice admissível
6 7

P 1 2 4 8
5 6 9 7
67

Selecionar vértice 4
2 4 3
2 8 4

5
1 1 5 7 8

Mas vértice
Remover 4 não4
vértice
tem
de Pum vértice 9
adjacente 3 6
admissível 6 7

P 1 2 4 8
5 6 9 7
68

Selecionar vértice 2
2 4 3
2 8 4

5
1 1 5 7 8

Remover
Mas vértice
vértice
2 não2
de
temP um vértice 9
adjacente 3 6
admissível 6 7

P 1 2 4 8
5 6 9 7
69

Selecionar vértice 1
2 4 3
2 8 4

5
1 1 5 7 8

Selecionar
next uma
:=vértice
Marcar next +v1
(u, v) admissível 9
π(v) := u := next
order[v] 3 6
9 6 7
Adicionar v a P

P 1 2
3 4 8
5 6 9 7
70

Selecionar vértice 3
2 4 3
2 8 4

5
1 1 5 7 8

Mas
Remover
vértice
vértice
3 não3
tem
de Pum vértice 9
adjacente 3 6
admissível 9 6 7

P 1 2
3 4 8
5 6 9 7
71

Selecionar vértice 1
2 4 3
2 8 4

5
1 1 5 7 8

Mas
Remover
vértice
vértice
1 não
tem
1 deadjacente
P 9
admissível 3 6
9 6 7

P 1 2
3 4 8
5 6 9 7
72

P está vazia
2 4 3
2 8 4

5
1 1 5 7 8

O algoritmo
finaliza! 9
3 6
9 6 7

P 1 2
3 4 8
5 6 9 7
73

A Árvore de Busca em Profundidade


1 1

2 2 3 9
Note que cada
sub-árvore tem
vértices rotulados
4 3
consecutivamente

4 8 5 5

6 6

9 7

7 8
74/69

Busca em Profundidade - Complexidade


• O procedimento BP requer O(|V|) para inicializar o vetor
cor.

• Quando uma lista de adjacências é utilizada, BP-visita


requer O(|A|).
• Portanto, a busca profundidade requer O(|V|+|A|).

• Quando uma matriz de adjacências é utilizada, o


procedimento BP-visita requer O(|V|2).
• Logo a busca em profundidade requeria O(|V|+|V|2).
75/69

Exercícios
5. Mostre a árvore de busca em profundidade gerada a
partir da execução do algoritmo de busca em
profundidade iniciando no vértice 1 do grafo abaixo.
76/69

Exercícios
6. Faça a busca em profundidade no grafo abaixo a partir
do vértice V3.
77/69

Exercícios
7. Mostre como a busca em profundidade funciona para o
grafo da figura abaixo, usando o vértice 1 como origem.
78/69

Exercícios
8. Aplique o algoritmo de busca em profundidade no grafo
não-dirigido definido pelas arestas 0-2 0-5 1-2 3-4 4-5
3-5 e faça o rastreamento de sua execução.

9. Faça o rastreamento da execução do algoritmo de


busca em profundidade sobre o grafo não-dirigido
definido pelas arestas 3-7 1-4 7-8 0-5 5-2 3-8 2-9 0-6 4-
9 2-6 6-4.
79/69

Exercícios
10. Faça uma busca em profundidade no grafo da figura.
Suponha que o grafo é representado por sua matriz de
adjacências.
80/69

Exercícios
1. Dada a representação por listas de adjacências de um
grafo direcionado, qual o custo para obter o número de
arestas que incidem nele? E o número de arestas que
saem dele?

2. Implementar a busca em profundidade e largura na


linguagem de programação de sua preferência
utilizando as operações do TAD Grafo implementadas.

3. Implemente um algoritmo para verificar se um grafo é


acíclico. Use o algoritmo para realizar busca em
profundidade.
81/69

Busca em Profundidade em C
82/69

Busca em Profundidade em C
83/69

Busca em Largura em C
84/69

Busca em Largura em C
85/69

Referências Bibliográficas
• Cormen, T. H., Leiserson, C. E., Rivest, R. L., e Stein, C.,
Algoritmos – Teoria e Prática, tradução da 2ª Edição
Americana, Elsevier, 2002.

• Ziviani, N., Projeto de Algoritmos, 3ª Edição, Cengage


Learning, 2011.

Das könnte Ihnen auch gefallen