330 likes | 501 Views
Algoritmos em Grafos. Buscas em Grafos Prof. André Renato 1º Semestre/2012. Buscas em Grafos. Uma das operações mais comuns em estruturas de dados consiste em listar os elementos armazenados de acordo com a estruturação utilizada.
E N D
Algoritmos em Grafos Buscas em Grafos Prof. André Renato 1º Semestre/2012
Buscas em Grafos • Uma das operações mais comuns em estruturas de dados consiste em listar os elementos armazenados de acordo com a estruturação utilizada. • Em listas, é possível imprimir os elementos um após o outro, na mesma ordem em que se encontram na lista.
Buscas em Grafos • Em árvores binárias, existe três formas de se imprimir todos os elementos: em ordem, em pré-ordem e em pós-ordem. 20 15 40 19 32 45 8
Buscas em Grafos • Os algoritmos são simples e utilizam eficientemente a estrutura recursiva da árvore. • Além disso, existe um nó que é diferente dos demais e através do qual é possível o percorrimento atingindo todos os demais nós: nó raiz.
Buscas em Grafos • Em grafos, qual o nó raiz? • Como é feita a estruturação recursiva do grafo? • A segunda pergunta é de difícil resposta, pois nem sempre o grafo apresenta uma estruturação bem-definida (na verdade, quase nunca). • A primeira pergunta é mais simples: não existe uma raiz natural em um grafo.
Buscas em Grafos • Como fazer então o percorrimento? • O primeiro passo consiste em escolher um nó aleatoriamente para ser o ponto inicial do algoritmo. • Deve-se então adotar uma política para o processamento do nó inicial e, sucessivamente, dos seus adjacentes. • Existem duas políticas mais usuais, que dão origem às duas formas de buscas mais utilizadas.
Buscas em Grafos • Busca em largura • A idéia consiste em, partindo de um nó inicial v, armazenar todos os nós u adjacentes a ele. • Escolher um nó u e armazenar todos os adjacentes; • Passar para o segundo nó u e repetir o processo até que todos os nós imediatamente adjacentes a v sejam tratados. • O procedimento se repete para os nós adjacentes aos nós u armazenados.
Buscas em Grafos • Além do próprio grafo, é necessário armazenar os nós que estão sendo processados em outra estrutura de dados. Qual???
Buscas em Grafos • Ainda existe um problema: normalmente é possível partir de um nó v e atingir um nó u de duas ou mais formas diferentes. • Como evitar que este tipo de processamento repetido seja evitado sem excluir previamente nenhuma possibilidade de acesso aos nós?
Buscas em Grafos • Uma idéia é colocar nos nós um tipo de marcação que servirá para identificar se o nó já foi processado ou ainda não. • Um atributo booleano (ou inteiro) é suficiente para cada nó. • Inicialmente, todos os nós são marcados como “não-visitado”. O nó inicial é colocado na fila e marcado como visitado. • O algoritmo prossegue como descrito anteriormente.
Buscas em Grafos 2 3 5 1 7 6 8 9 4 10
Buscas em Grafos • Busca em profundidade: • A idéia agora é partir de um nó inicial v e encontrar um primeiro nó adjacente u. • Ao invés de enfileirar o nó u e buscar outro adjacente a v, mudamos imediatamente para o primeiro nó u encontrado e repetimos as operações.
Buscas em Grafos • Busca em profundidade: • Quando um nó u for totalmente explorado, voltamos o fluxo do algoritmo para o nó que alcançou u primeiramente. • Prosseguimos, então, com outro nó adjacente ainda não explorado até que todos os nós adjacente ao nó inicial tenham sido explorados. • Neste ponto, o fluxo do algoritmo volta para o inicial encerrando sua execução.
Buscas em Grafos • A estrutura de fila utilizada na busca em largura não faz mais sentido, pois os nós vão sendo processados à medida em que são encontrados. • No entanto, por precisar mudar constantemente o nó corrente e depois voltar por todos os nós processados até o nó inicial, outra estrutura é necessária.
Buscas em Grafos • Qual???? • Se vamos utilizar uma pilha, é possível pensar no algoritmo através de uma abordagem recursiva?
Buscas em Grafos 2 3 5 1 7 6 8 9 4 10
Buscas em Grafos • Os algoritmos de busca podem revelar informações importantes sobre os vértices, as arestas e o próprio grafo como todo. • Para conseguir isto, precisamos alterar levemente os algoritmos, fazendo-os armazenar informações extras durante suas execuções.
Buscas em Grafos • Busca em largura: • Distância entre os vértices: pode ser entendida como a quantidade mínima de arestas adjacentes entre dois vértices; • Para calcular a distância e quais arestas estão envolvidas, adicionaremos duas informações aos vértices: a distância corrente d e o vértice que o precede na busca pred. • Vale lembrar que a distância não leva em conta o peso das arestas.
Buscas em Grafos • As arestas indicadas pelo valor de predformam uma estrutura de dados conhecida. Qual? • Por que isso acontece?
Buscas em Grafos • Busca em profundidade: • Quando um nó é visitado, não temos a menor idéia de quando o fluxo do algoritmo voltará para ele. • Isto depende da quantidade de nós que serão alcançados através dele. Se imaginarmos que o algoritmo é executado de acordo com horizonte de tempo fictício onde cada visita a um nó demora uma unidade de tempo, podemos anotar quando o nó é começa a ser visitado e quando termina.
Buscas em Grafos • Busca em profundidade: • Se imaginarmos que o algoritmo é executado de acordo com horizonte de tempo fictício onde cada visita a um nó demora uma unidade de tempo, podemos anotar quando o nó é começa a ser visitado e quando termina. • Teremos então duas informações além de pred: o tempo de descoberta do nó desc e o tempo de finalização do nó fim.
Buscas em Grafos • Os tempos de descoberta e finalização apresentam uma estrutura de parênteses. • Se representarmos a descoberta do nó u pelo símbolo “(u” e a finalização pelo símbolo “u), a sequência de descobertas e finalizações gera uma expressão bem formada, onde os parênteses estão corretamente aninhados.
Buscas em Grafos • Exemplo de estrutura de parênteses y z s t x w v u s t z v u y w x 1 (s 2 (z 3 (y 4 (x 5 x) 6 y) 7 (w 8 w) 9 z) 10 s) 11 (t 12 (v 13 v) 14 (u 15 u) 16 t)
Buscas em Grafos • Classificação de arestas: • Pode trazer informações importantes sobre o grafo, como a existência de ciclos (que será visto posteriormente). • Arestas de árvore: são as arestas obtidas pela relação de precedência direta entre vértices do u e v do grafo, ao final da busca. • A aresta (u,v) é de árvore, se v for descoberto por esta mesma aresta.
Buscas em Grafos • Classificação de arestas: • Arestas de retorno: são as arestas (u,v) que conectam um vértice u a um vértice v já visitado anteriormente. • Arestas de avanço: são as arestas (u,v) que conectam um vértice u a um vértice v descendente não-imediato. • Arestas de cruzamento: são as demais arestas do grafo.
Buscas em Grafos y z s t x w v u s t z v u y w x
Buscas em Grafos • Ordem topológica: pode ser vista como o posicionamento dos vértices numa linha horizontal, onde todas as arestas estão da esquerda para a direita. • A ordem topológica é aplicada a grafos direcionados que não possuam ciclos.
Buscas em Grafos • Algoritmo para ordem topológica: • Executar a busca em profundidade; • Conforme os vértices são finalizados, colocá-los na frente de uma lista encadeada*; • Retornar o início da lista; • *Pode ser utilizada uma pilha.
Buscas em Grafos • Componentes fortemente conexos: são subconjuntos maximais de vértices, onde para cada par de vértices (u,v), existe uma forma de chegar de u até v e vice-versa. • Não faz sentido em grafos não-direcionados. Por quê?????
Buscas em Grafos 1 2 3 4 5 6 7 8 9
Buscas em Grafos • Algoritmo para gerar os componentes: • Executar a busca em profundidade, anotando os tempos de finalização de cada vértice; • Calcular o grafo transposto; • Aplicar a busca em profundidade no grafo transposto: • Considerar os vértices em ordem decrescente de seus tempos de finalização; • Mostrar os vértices de cada árvore como um componente fortemente conexo;
Buscas em Grafos • Colocar grafos de exemplo e pseudo-codigo no final