INF Estruturas de Dados Avançadas Grafos // DI, PUC-Rio Estruturas de Dados Avançadas.
Algoritmo de Dijkstra 8 8
Algoritmo de Dijkstra 8 8 8
Algoritmo de Dijkstra 8 8 8
Algoritmo de Dijkstra 8 8 8 8 8
Algoritmo de Dijkstra 8 8 8 8
Algoritmo de Dijkstra 8 8 8 8
Algoritmo de Dijkstra 8 8 8 8 8 8
Algoritmo de Dijkstra 8 8 8 8 8 8 8
Algoritmo de Dijkstra 8 8 8 8 8 não tem vizinhos não visitados!
Algoritmo de Dijkstra 8 8 8 8 8 não tem vizinhos não visitados!
Algoritmo de Dijkstra implementação sugestão: heap para otimizar a recuperação do nó de menor caminho mas tivemos que consertar o heap a cada vez que encontramos um caminho mais curto para nó não visitado perdemos as vantagens do heap!
Algoritmo de Dijkstra como implementar usando heap e manter vantagens de tempo de acesso?. abrir a implementação do heap. criar heap maior e inserir cada nó várias vzs
Algoritmo de Dijkstra como implementar usando heap e manter vantagens de tempo de acesso?. abrir a implementação do heap custo de corrige_pos está na busca podemos manter a posição atual de cada nó
Algoritmo de Dijkstra como implementar usando heap e manter vantagens de tempo de acesso?. abrir a implementação do heap tamanho do menor caminho heap prio nó
Algoritmo de Dijkstra como implementar usando heap e manter vantagens de tempo de acesso? abrir a implementação do heap heap deixa de ser módulo separado tamanho do menor caminho posição do nó no heap heap - inf inf prio nó
Algoritmo de Dijkstra como implementar usando heap e manter vantagens de tempo de acesso?. sobrealocação do heap tamanho do menor caminho heap inf inf prio nó
Algoritmo de Dijkstra como implementar usando heap e manter vantagens de tempo de acesso?. sobrealocação do heap menor caminho heap inf visitado inf prio nó tamanho do menor caminho novo heap inf visitado prio nó
Algoritmo de Dijkstra em geral não queremos apenas saber o tamanho dos menores caminhos mas também sua estrutura
Algoritmo de Dijkstra em geral não queremos apenas saber o tamanho dos menores caminhos mas também sua estrutura custo inf último nó visitado - -
Algoritmo de Kruskal Árvore geradora de custo mínimo Dado um grafo ponderado G = (V,E,p), uma árvore geradora de custo mínimo para G é uma árvore tal que: V é o conjunto de nós da árvore A soma dos pesos das arestas é minima (entre as árvores geradoras) // DI, PUC-Rio Estruturas de Dados Avançadas.
Algoritmo de Kruskal Algoritmo de Kruskal Entrada: Um grafo ponderado G = (V,E,p) Saída: Árvore geradora de custo mínimo. Considere cada nó em V como uma árvore separada (formando uma floresta). Examine a aresta de menor custo. Se ela unir duas árvores na floresta, inclua-a.. Repita o Passo () até todos os nós estarem conectados. // DI, PUC-Rio Estruturas de Dados Avançadas.
Algoritmo de Kruskal. Considere cada nó como uma árvore separada (formando uma floresta) 8 8 // DI, PUC-Rio Estruturas de Dados Avançadas.
Algoritmo de Kruskal. Examine a aresta de menor custo. Se ela unir duas árvores na floresta, inclua-a.. Repita o Passo () até todos os nós estarem conectados. 8 8 // DI, PUC-Rio Estruturas de Dados Avançadas.
Algoritmo de Kruskal. Examine a aresta de menor custo. Se ela unir duas árvores na floresta, inclua-a.. Repita o Passo () até todos os nós estarem conectados. 8 8 // DI, PUC-Rio Estruturas de Dados Avançadas.
Algoritmo de Kruskal. Examine a aresta de menor custo. Se ela unir duas árvores na floresta, inclua-a.. Repita o Passo () até todos os nós estarem conectados. 8 8 // DI, PUC-Rio Estruturas de Dados Avançadas.
Algoritmo de Kruskal. Examine a aresta de menor custo. Se ela unir duas árvores na floresta, inclua-a.. Repita o Passo () até todos os nós estarem conectados. 8 8 // DI, PUC-Rio Estruturas de Dados Avançadas. 7
Algoritmo de Kruskal. Examine a aresta de menor custo. Se ela unir duas árvores na floresta, inclua-a.. Repita o Passo () até todos os nós estarem conectados. 8 8 8 // DI, PUC-Rio Estruturas de Dados Avançadas. 8
Algoritmo de Kruskal. Examine a aresta de menor custo. Se ela unir duas árvores na floresta, inclua-a.. Repita o Passo () até todos os nós estarem conectados. 8 8 // DI, PUC-Rio Estruturas de Dados Avançadas. 9
Algoritmo de Kruskal. Examine a aresta de menor custo. Se ela unir duas árvores na floresta, inclua-a.. Repita o Passo () até todos os nós estarem conectados. 8 8 // DI, PUC-Rio Estruturas de Dados Avançadas.
Algoritmo de Kruskal. Examine a aresta de menor custo. Se ela unir duas árvores na floresta, inclua-a.. Repita o Passo () até todos os nós estarem conectados. 8 8 // DI, PUC-Rio Estruturas de Dados Avançadas.
como descobrir se uma aresta conecta duas árvores? uso de uma estrutura de dados específica chamada união e busca estrutura de dados para manipulação de partições de conjuntos
Definições Universo: U = {x,x,,x n } Uma partição é uma coleção : C = {S,,S k } de conjuntos disjuntos S i U para qualquer i S S k = U (cobertura) S i S j =, para i j (disjunção) partição S i identificada por um de seus elementos x S i (REPRESENTANTE)
Operações Básicas cria() : cria uma partição do conjunto original busca(x): Informa qual partição um elemento faz parte, retornando um elemento que representa a partição Útil para determinar se dois elementos estão no mesmo conjunto {k,j,n,o,y,w,x,z} := w união(x,y): combina dois conjuntos em um único, substituindo S i e S j por um novo conjunto S k tal que S i S j = S k
Representação por Árvores Reversas //
Representação por Árvores Reversas Árvores reversas (Reversed Trees) Cada nó aponta para o seu pai a raiz aponta para si mesma ou aponta para NULL Depois de um nó deixar de ser a raiz, um nó nunca pode se tornar uma raiz novamente x x x x y s w w ys w w //
Representação por Árvores Reversas Exemplo u u x x t z y t v y z s w v s w S = {t,u,v,y,z} S = {s,w,x} // 7
Operações cria(n) = {S,, S n- } cria uma estrutura uniao-e-busca com n elementos disjuntos // 8
Operações busca(ub, x) retorna o elemento que representa o conjunto busca a raiz da árvore que contém o elemento busca(y) -> u busca(s) -> x u u x t z y t v y z s w v s w 9
Operações união(ub, u, x) une dois grupos, fazendo com que a raiz de um grupo aponte para a raiz do outro grupo torna uma árvore uma sub-árvore da outra união(ub, u, x) = {t,u,v,y,z, s,w,x} u u x x t z y t v y z s w À medida que novas uniões são realizadas, uma árvore completamente degenerada pode ser criada, fazendo com que as operações de Find se realizem em tempo linear O(n) v s w
Operações busca(ub, x) retorna o elemento que representa o conjunto busca a raiz da árvore que contém o elemento u u x x t z y t v y z s w v s w
Representação por Vetor
Representação por Vetor Implementação de partições: Através de um vetor Cada elemento do vetor representa um elemento do universo Cada elemento do vetor aponta para seu pai //
Representação por Vetor Exemplo (Note que a raiz possui - como valor do ponteiro) 7 - - u x 7 t z y 7 v s w //
Union-Find (implementação simplificada ineficiente!!!) typedef struct uniaobusca UniaoBusca; struct uniaobusca {int n; int *v;}; UniaoBusca* cria(int size) { /* aloca novo item com tamanho dado e preenche vetor com - */ } int busca (UniaoBusca* ub, int u){ while (ub->v[u] >= ) u = ub->v[u]; return u; } void uniao (UniaoBusca* ub, int u, int v) { v = busca (ub, v); /* acha raiz de árvore de v */ ub->v[u] = v; } //
Problema Configuração inicial: uma floresta com n nós (singletons) 9 Operações; União dos elementos em ordem uniaosimples(,), uniaosimples(,),..., uniaosimples(n-, n) 7 8 Resultado: uma árvore degenerada busca muito cara!!!
otimizações 7
otimizações na união busca raizes void uniao (UniaoBusca* ub, int u, int v){ u = busca(ub, u); v = busca(ub, v); /* une u e v! */ } 8
união nas raizes void uniao (UniaoBusca* ub, int u, int v){ u = ub_busca(ub, u); v = ub_busca(ub, v); /* une u e v! */ } u s x 7 w ou t z y 7 v u t z y 7 v x 7 s 9 w
união nas raizes pendurar árvore com menor número de nós void uniao (UniaoBusca* ub, int u, int v){ u = busca(ub, u); v = busca(ub, v); if (u==v) return; /* uniao com base no numero de nós */ if /* arvore em u tem menos nós */ { ub->v[u] = v; /* atualiza o numero de nós de v */ } else /* arvore em v tem menos nós */ } como manter o número de nós em cada árvore podemos usar o próprio campo que indica o pai e em vez de - armazenar (número de nós) em cada raiz
união nas raizes pendurar árvore com menor número de nós na outra void uniao (UniaoBusca* ub, int u, int v){ u = busca(ub, u); v = busca(ub, v); if (u==v) return; /* uniao com base no numero de nós */ if (ub->v[u] < ub->v[v]) { ub->v[v] += ub->v[u]; ub->v[u] = v; } else /* arvore em v tem menos nós */ } como manter o número de nós em cada árvore podemos usar o próprio campo que indica o pai e em vez de - armazenar (número de nós) em cada raiz
otimizações na união busca raizes L mas agora união fica cara como melhorar isso?