Teoria dos Grafos Aula 8 Aula passada Grafos com pesos, caminhos e distâncias Ideia e algoritmo de Dijkstra Dijkstra o próprio Aula de hoje Corretude de Dijkstra Fila de prioridades e Heap Dijkstra eficiente
Discipline in Thought Ciência da computação não é mais sobre computadores do que astronomia é sobre telescópios Falta coragem nas universidades para ensinar ciências duras. Elas continuarão a enganar os alunos e cada etapa na infantilização do currículo será celebrada como progresso educacional Elegância (na arte de programar) não é um luxo dispensável, mas fator que decide entre sucesso e falha Elegância demanda trabalho duro para produzir e uma boa educação para apreciar. Por isto encontrou poucos adeptos Quais são suas impressões?
Algoritmo de Dijkstra Ideias: Manter dois conjuntos de vértices (explorados e não-explorados) Manter comprimento do menor caminho conhecido até o momento para cada vértice Adicionar o vértice de menor caminho (explorar) Atualizar distâncias Como tornar a ideia em algoritmo?
Algoritmo de Dijkstra 1.Dijkstra(G, s) 2.Para cada vértice v 3. dist[v] = infinito 4.Define conjunto S = 0 // vazio 5.dist[s] = 0 6.Enquanto S!= V 7. Selecione u em V-S, tal que dist[u] é mínima 8. Adicione u em S 9. Para cada vizinho v de u faça 10. Se dist[v] > dist[u] + w((u,v)) então 11. dist[v] = dist[u] + w((u,v))
Analisando o Algoritmo Provar que algoritmo sempre produz resultado correto caminho mínimo entre dois vértices Teorema: Considere um vértice u pertencente ao conjunto S em qualquer ponto do algoritmo. Temos que dist[u] é a distância entre s e u.
Prova Prova por indução no tamanho de S Caso base: S = 1 S = {s}, dist[s] = 0, devido inicialização Hipótese: S = k para S = k, assuma que dist[u] é igual a distância entre s e u Caso geral: S = k + 1 k+1 adiciona v à S, dando origem a P v temos que mostrar que P v é mínimo seja (u,v) última aresta no caminho P v pela hipótese, P u é caminho mínimo s-u
Prova Considere outro caminho s-v, P, que não passa por u Precisamos provar que P é maior (ou igual) a P v P passa pela aresta (x,y), com x em S e y fora de S (para algum x e y qualquer) Situação: s S u x y v No passo k+1, algoritmo escolhe v para adicionar a S (e não y) Então, caminho s y é maior ou igual a P v Como dist(y,v) >=0, caminho P será maior ou igual a P v Logo, P v é caminho mínimo e dist[v] será distância até v
Complexidade Qual é a complexidade do algoritmo? 1.Dijkstra(G, s) 2.Para cada vértice v 3. dist[v] = infinito 4.Define conjunto S = 0 // vazio 5.dist[s] = 0 6.Enquanto S!= V 7. Selecione u em V-S, tal que dist[u] é mínima 8. Adicione u em S 9. Para cada vizinho v de u faça 10. Se dist[v] > dist[u] + w((u,v)) então 11. dist[v] = dist[u] + w((u,v)) Depende do tempo para selecionar u tal que dist[u] seja mínima!
Algoritmo simples Complexidade Percorre vértices e encontra dist[u] mínimo Complexidade? O(n 2 ) Outra ideia? Fila de prioridades muito usada em grafos Chave: distâncias Extrair o mínimo (vértice com menor distância) Atualizar chaves (distâncias)
Fila de Prioridade Estrutura de dados poderosa (priority queue) Mantém um conjunto de elementos S Cada elemento possui uma chave (número de prioridade) Permite inserir, remover e modificar elementos de S através de sua chave Complexidade de pior caso para remoção, inserção e modificação: O(log n) caso médio para algumas operações pode ser O(1), dependendo da implementação (ex. Fibonacci Heap)
Heap Heap: Implementação de fila de prioridade Estrutura de dados em forma de árvore Armazena conjunto de elementos, todos associados a uma chave Chave dos elementos define árvore Heap order 1) Min-heap: chave(u) <= chave(v), quando u é pai de v (usado para remover menor chave primeiro) 2) Max-heap: chave(u) >= chave(v), quando u é pai de v (usado para remover maior chave primeiro)
Heap Binário Heap Binário: árvore binária cheia fácil implementação Operações básicas adicionar, remover, atualizar chave Não serve para fazer busca (não está ordenada) 9 7 8 10 12 15 Max-heap ou Min-heap? Saindo da raiz, como chegar na chave 12?
Inserção e Remoção Inserção 1) adicionar elemento na última posição da árvore 2) trocar posição com pai até garantir heap-order (subir) Remoção 1) remover raiz e mover último elemento para raiz 2) trocar de posição com menor filho até garantir heap-order (descer) Exemplos Adicionar chave 5 Remover raiz 9 7 8 10 12 15 Atualização Chave pode mudar de valor Subir ou descer, de acordo
Heap Binário 7 Considere heap binário com n elementos Qual é a altura da árvore? log 2 n 9 8 10 12 15 Complexidade das operações de inserção, remoção e atualização? Subir ou descer na árvore pior caso percorre todos os níveis, log 2 n Complexidade: O(log n)
Complexidade Quantas operações no heap? 1.Dijkstra(G, s) 2.Para cada vértice v 3. dist[v] = infinito 4.Define conjunto S = 0 // vazio 5.dist[s] = 0 6.Enquanto S!= V 7. Selecione u em V-S, tal que dist[u] é mínima 8. Adicione u em S 9. Para cada vizinho v de u faça 10. Se dist[v] > dist[u] + w((u,v)) então 11. dist[v] = dist[u] + w((u,v)) n operações de remoção m operações de atualização (cada aresta) Complexidade: O((n+m)log n) = O(m log n), se grafo for conexo