Este documento descreve o algoritmo de busca em largura para grafos. Ele começa no vértice raiz e explora todos os vértices vizinhos, e então explora os vizinhos desses vértices e assim por diante até encontrar o alvo. O algoritmo usa uma fila FIFO para garantir a ordem de visita dos vértices e marca cada vértice como branco, cinza ou preto durante a busca. Sua complexidade de tempo é O(|V| + |E|) e de espaço é O(|V|) no pior caso.
2. Definição
● Na teoria dos grafos, busca em largura (ou busca
em amplitude, também conhecido em inglês por
Breadth-First Search (BFS)) é um algoritmo de
busca em grafos utilizado para realizar uma busca
ou travessia num grafo e estrutura de dados do tipo
árvore.
3. ● Intuitivamente, você começa pelo vértice raiz e
explora todos os vértices vizinhos.
● Para cada um desses vértices mais próximos,
exploramos os seus vértices vizinhos inexplorados e
assim por diante, até que ele encontre o alvo da busca.
4. Formalmente, uma busca em largura é um método de busca
não-informada (ou desinformada) que expande e examina
sistematicamente todos os vértices de um grafo direcionado
ou não-direcionado.
●
O algoritmo realiza uma busca exaustiva num grafo
passando por todas as arestas e vértices do grafo
garantindo que nenhum vértice ou aresta será visitado
mais de uma vez e, para isso, utiliza uma estrutura de
dados fila para garantir a ordem de chegada dos vértices.
●
Realizando as visitas aos vértices através da ordem de
chegada na estrutura fila e um vértice que já foi marcado
não pode retornar a esta estrutura.
5. Algoritmo
● O algoritmo Território tem um caráter "genérico": a ordem
em que os vértices saem da lista manipulada pelo algoritmo é
irrelevante. Já no algoritmo de busca em largura, a lista de
vértices obedece a política FIFO: o vértice que sai da lista é
sempre o que está lá há mais tempo. A lista se comporta,
portanto, como uma fila FIFO.
● O algoritmo pinta de preto todos os vértices do território
de um vértice r. O código abaixo supõe que os vértices do
dígrafo são 1, 2, … , n e que os arcos são representados
pelo vetor Adj[1..n] de listas de adjacência.
6. Algoritmo
Busca-em-Largura (n, Adj, r)
1 para u ← 1 até n faça
2 cor[u] ← branco
3 cor[r] ← cinza
4 F ← Cria-Fila(r)
5 enquanto F não está vazia faça
6 u ← Sai-da-Fila(F)
7 para cada v em Adj[u] faça
8 se cor[v] = branco
9 então cor[v] ← cinza
10 Entra-na-Fila(v, F)
11 cor[u] ← preto
12 devolva cor[1..n]
7. Algoritmo
O comando Cria-Fila(r) cria uma fila com um só elemento
igual a r. O comando Sai-da-Fila(F) retira o primeiro elemento
(ou seja, o elemento mais antigo) da fila F. O comando Entra-
na-Fila(v,F) insere v no fim da fila F.
A fila pode ser implementada, muito simplesmente, em
um vetor F[1..n]. O primeiro elemento da fila será F[i] e o último
será F[f−1].
8. Algoritmo
A linha 4 do algoritmo (Cria-Fila(r)) consiste simplesmente em
i ← 1
f ← 2
F[1] ← r
a linha 5 do algoritmo (enquanto F não estiver vazia faça) é
traduzida por
enquanto i < f faça
a linha 6 (u ← Sai-da-Fila( )) é implementada por
u ← F[i]
i ← i+1
a linha 10 (Entra-na-Fila(v)) é implementada por
F[f] ← v
f ← f+1
Essa implementação da fila jamais sofre overflow, pois cada vértice
do dígrafo entra na fila no máximo uma vez.
10. Exemplo
As linhas da tabela abaixo dão o estado da fila F[1..6] no
início de sucessivas iterações: as casas pretas contêm os
vértices que já saíram da fila; as casas cinza representam a
fila propriamente dita.
11. Complexidade de Tempo
Considerando um grafo representado em listas de
adjacência, o pior caso, aquele em que todos os vértices e
arestas são explorados pelo algoritmo, a complexidade de
tempo pode ser representada pela seguinte expressão:
Onde |E| significa o tempo total gasto nas operações
sobre todas as arestas do grafo onde cada operação requer
um tempo constante 0(1) sobre uma aresta, e |V| que
significa o número de operações sobre todos os vértices que
possui uma complexidade constante 0(1) para cada vértice
uma vez que todo vértice é enfileirado e desinfileirado uma
única vez.
12. Complexidade de Espaço
●
Quando o número de vértices no grafo é conhecido e
supondo-se a representação deste em listas de
adjacência, a complexidade de espaço do algoritmo pode
ser representada por 0 (|V|) onde |V| representa o
número total de vértices no grafo.
Profundidade (d) Nós Tempo Memória
2 1100 0.11 ms 107 KB
4 111.100 11 ms 10.6 MB
6 10 7 1.1 seg 1 GB
8 10 9 2 min 103 GB
10 10 11 3 horas 10 TB
12 10 13 13 dias 1 PB
14 10 15 3.5 anos 99 PB