460 likes | 605 Views
Algoritmos em Grafos. Árvores Geradoras. Prof. André Renato 1º Semestre / 2012. Algoritmos em Grafos. Vamos voltar a falar em árvores: Como definir a estrutura de dados “árvore”? Quais os elementos que compõem uma árvore?
E N D
Algoritmos em Grafos Árvores Geradoras Prof. André Renato 1º Semestre / 2012
Algoritmos em Grafos • Vamos voltar a falar em árvores: • Como definir a estrutura de dados “árvore”? • Quais os elementos que compõem uma árvore? • Em relação ao número de filhos de cada nó, como podem ser as árvores?
Algoritmos em Grafos • Se pensarmos nas árvores como grafos acíclicos (sem ciclos) não-direcionados, qual a quantidade de arestas que podemos ter? • Qual seria a raiz da árvore?
Algoritmos em Grafos • No processo de confecção de circuitos eletrônicos, é muito comum precisar fazer com que diversos pinos (partes do circuito) sejam eletricamente equivalentes. • Isto equivale a dizer que estes pinos precisam estar conectados entre si, através de fios.
Algoritmos em Grafos • Deverão ser utilizados n-1 fios, para conectar n pinos. • A colocação dos fios deve ser tal que seja gasta a menor quantidade possível de fios. • Este problema pode ser modelado através de grafos.
Algoritmos em Grafos • Os pinos são os vértices; • As possíveis conexões entre pinos são as arestas; • O peso (custo) associado às arestas é a quantidade de fio necessária para a ligação; • Nós desejamos encontrar um subconjunto acíclico de arestas de forma que a soma de todos os custos seja a mínima possível.
Algoritmos em Grafos • O resultado é uma árvore que conecta todos os vértices, chamada de árvore geradora, uma vez que ela gera o grafo G. • O problema é chamado de Problema da Árvore Geradora Mínima (AGM), ou Problema da Árvore Geradora de Custo Mínimo.
Algoritmos em Grafos • Existem dois algoritmos mundialmente famosos para este problema; • Prim; • Kruskal; • A utilização de um ou de outro vai depender de características do grafo, como sua esparsidade, por exemplo.
Algoritmos em Grafos • Ambos utilizam a estratégia gulosa de escolher primeiro as arestas de menor custo possível; • Em ambos está presente, direta ou indiretamente, a preocupação de não formar ciclos com as escolhas realizadas.
Algoritmos em Grafos • Algoritmo de Kruskal: • A idéia por trás deste algoritmo é ordenar todas as arestas em ordem não-decrescente de peso; • Escolher as arestas pela ordem, de forma que possam ser colocadas na resposta sem formar ciclos.
Algoritmos em Grafos • Colocar as arestas em ordem e armazená-las em uma lista é um problema simples de estrutura de dados. • O problema maior está em saber, de forma eficiente, se uma aresta, ao ser colocada na resposta formará ou não um ciclo. • Idéias????
Algoritmos em Grafos • Uma solução simples consiste em guardar um código para cada vértice; • Inicialmente, cada vértice possui um código distinto, que pode ser até o número do próprio vértice;
Algoritmos em Grafos • Se dois vértices são adjacentes na solução do problema, o código dos dois deverá ser o mesmo. • Logo, quando uma aresta (v1,v2) for testada, ela poderá ser colocada na resposta se codigo(v1)≠codigo(v2);
Algoritmos em Grafos • Quando a aresta for inserida, todos os vértices v que tenham codigo(v) = v1 deverão receber o código v2 ou vice-versa; • Um vetor de números inteiros de tamanho n é suficiente para este propósito;
Algoritmos em Grafos • Antes de explicitar o pseudo-código do algoritmo, vamos a um exemplo gráfico; • As arestas em vermelho fazem parte da solução final do problema (árvore geradora mínima); • As demais estruturas serão atualizadas conforme as explicações dadas;
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 1 2 2 4 4 6 7 7 8 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 2 2 4 4 6 7 7 8 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 2 4 4 6 7 7 8 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 4 4 6 7 7 8 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 4 6 7 7 8 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 6 7 7 8 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 7 7 8 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 7 8 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 8 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 8 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 9 10 11 14
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8 Arestas: 10 11 14
Algoritmos em Grafos • Pseudo-código Kruskal: • Para cada vértice v: • codigo(v) := v; • Ordenar as arestas na lista L (não-decrescente); • Retirar a aresta (v1,v2) da frente da lista; • Se codigo(v1) ≠ codigo(v2) então: • Inserir a aresta na solução; • Para cada vértice v: • Se codigo(v) = codigo(v2) então codigo(v) := codigo(v1)
Algoritmos em Grafos • Qual a complexidade do algoritmo de Kruskal? • Para fazer a atualização dos códigos é possível utilizar uma estrutura de dados chamada de heaps de Fibonacci. • Com ela, o processo de atualização dos códigos diminui a complexidade para O(lg n);
Algoritmos em Grafos • O algoritmo de Prim monta a árvore geradora mínima, partindo de um nó previamente estabelecido; • Os demais nós vão sendo incorporados de forma a se conectar com a árvore com o menor custo possível;
Algoritmos em Grafos • Estes nós que ainda não foram incorporados, ficam em uma lista ordenada; • A ordenação da lista é feita de acordo com a menor distância que cada vértice tem para a árvore parcial que está sendo montada;
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos 8 7 2 5 7 9 4 2 1 11 4 4 14 9 7 6 10 8 1 2 3 6 8
Algoritmos em Grafos • Pseudo-código do algoritmo de Prim: • Para cada vértice v: • dist[v] := ;* • dist[r] := 0; • Insere, em uma lista de prioridade L, todos os vértices de acordo com dist[]; • Enquanto L não estiver vazia: • u := elemento de menor dist[] de L; • Para todos os vértices v adjacente a u, que estão em L: • Se w(u,v) < dist[v] então • dist[v] := w(u,v); //atualizar L*
Algoritmos em Grafos • Complexidade do algoritmo? • Utilizando heaps de Fibonacci, reduz para O(E + V lgV)
Algoritmos em Grafos • Os resultados dos algoritmos deverão ter o mesmo valor, embora possam apresentar arestas distintas. • O algoritmo de Prim utiliza a idéia de escolher um vértice inicial para a geração da árvore. • Se o algoritmo for modificado para anotar a qual predecessor os vértices estão associados, é possível obter a árvore geradora de forma mais direta;