Algoritmo de Prim Wikipédia, a enciclopédia livre

Documentos relacionados
Algoritmo de Dijkstra Wikipédia, a enciclopédia livre

Grafos: árvores geradoras mínimas. Graça Nunes

Sub-grafo. Árvore Geradora Mínima

Grafos: componentes fortemente conexos, árvores geradoras mínimas

GRAFOS Aula 08 Árvore Geradora Mínima: Algoritmos de Kruskal e Prim-Jarnik Max Pereira

Grafos. Exemplo de árvore geradora mínima. Notas. Notas. Notas. Notas. Árvores espalhadas mínimas. Como construir uma árvore geradora miníma

5COP096 TeoriadaComputação

Grafos. Fabio Gagliardi Cozman. PMR2300 Escola Politécnica da Universidade de São Paulo

Prof. Marco Antonio M. Carvalho

Árvore Geradora Mínima

Estruturas de Dados. Grafos VIII: Árvores Geradoras Mínimas. Prof. Ricardo J. G. B. Campello

Problema da Árvore Geradora Mínima (The Minimum Spanning Tree Problem-MST)

Grafos Árvores Geradoras Mínimas

Prova Didática Grafos: Árvores Geradoras e Caminhos Mínimos, Análise de Complexidade

Ciclos hamiltonianos e o problema do caixeiro viajante

Demonstração. Relação invariante chave. Implementações do algoritmo de Prim. Implementação grosseira

Projeto e Análise de Algoritmos

MATEMÁTICA DISCRETA PARA ENGENHARIA DE COMPUTAÇÃO

O estudo utilizando apenas este material não é suficiente para o entendimento do conteúdo. Recomendamos a leitura das referências no final deste

Caminhos mínimos de única origem

Grafos Parte 1. Aleardo Manacero Jr.

Algoritmo de Kruskal. Algoritmo de Kruskal. Floresta geradora 26. Subfloresta S 20.3

Busca em largura. Algoritmos em Grafos. Marco A L Barbosa

Algoritmos e Estruturas de Dados II

Introdução à Teoria dos Grafos (MAC-5770) IME-USP Depto CC Profa. Yoshiko. Capítulo 3

Teoria dos Grafos Aula 5

Desafios de Programação TCC Turma A-1

Algoritmos em Grafos: Caminho Mínimo

Busca em Largura. Adaptado de Humberto C. B. Oliveira

Projeto e Análise de Algoritmos. Método Guloso

INF 1010 Estruturas de Dados Avançadas

06 Grafos: Caminhos Mínimos SCC0503 Algoritmos e Estruturas de Dados II

INF 1010 Estruturas de Dados Avançadas

Estruturas de Dados Grafos

Algoritmo de Dijkstra (um para todos ; arestas de peso não negativo ; guloso)

Árvores. Thiago Martins, Fabio Gagliardi Cozman. PMR2300 / PMR3201 Escola Politécnica da Universidade de São Paulo

Definição 1.1 : Uma árvore é um grafo simples conexo e sem ciclos.

Eduardo Camponogara. DAS-9003: Introdução a Algoritmos

O estudo utilizando apenas este material não é suficiente para o entendimento do conteúdo. Recomendamos a leitura das referências no final deste

CONCEITOS BÁSICOS EM GRAFOS

Teoria dos Grafos. Edson Prestes

INSTITUTO FEDERAL DO ESPÍRITO SANTO CURSO BACHARELADO EM SISTEMAS DE INFORMAÇÃO

O estudo utilizando apenas este material não é suficiente para o entendimento do conteúdo. Recomendamos a leitura das referências no final deste

Otimização em Grafos

Grafos parte 2. Percorrendo um grafo. Correção. Eficiência. Percorrendo um Grafo. Percorrendo um Grafo. Percorrendo um Grafo

Algoritmo de Dijkstra Estudo e Implementação

Teoria dos Grafos Aula 8

Análise e Síntese de Algoritmos. Algoritmos em Grafos CLRS, Cap. 22

Grafos. Notas. Notas. Notas. Notas. Caminhos mais curtos de única origem. Subestrutura ótima. Propriedades de caminhos mais curtos

Facebook. Um grafo é uma rede. Estrutura de dados fundamental em Informática, tal como listas e árvores.

Complexidade de Algoritmos

Grafos parte 2* Algoritmos e Estruturas de Dados II SCC-203 Rosane 2010/2011. *Baseado em material de professores dos anos anteriores

grafo nós vértices arcos arestas

GRAFOS. Prof. André Backes. Como representar um conjunto de objetos e as suas relações?

GRAFOS Aula 02 Formalização: definições Max Pereira

Caminho mais curto a partir de um nó Algoritmos de Dijkstra e Bellman-Ford. O problema tem subestrutura óptima

Algoritmos em Grafos COM11087-Tópicos Especiais em Programação I

Caminho mais curto a partir de um nó Algoritmos de Dijkstra e Bellman-Ford

ESTRUTURAS DE DADOS. prof. Alexandre César Muniz de Oliveira. 1. Introdução 2. Pilhas 3. Filas 4. Listas 5. Árvores 6. Ordenação 7. Busca 8.

Estruturas de Dados para Conjuntos Disjuntos: Union-find Letícia Rodrigues Bueno

Teoria dos Grafos. Árvores Geradoras

Árvores de Suporte de Custo Mínimo

APOSTILA DE MÉTODO GULOSO

Otimização em Grafos

05 Grafos: ordenação topológica SCC0503 Algoritmos e Estruturas de Dados II

Oalgoritmo de Dijkstra

Módulo 2 OTIMIZAÇÃO DE REDES

Teoria dos Grafos. Edson Prestes

Grafos - Introdução. Pedro Ribeiro 2014/2015 DCC/FCUP. Pedro Ribeiro (DCC/FCUP) Grafos - Introdução 2014/ / 32

Grafos Parte 2. SCC-603 Algoritmos e Estruturas de Dados II. Profª. Rosane Minghim / Baseado em material de professores dos anos anteriores

Tecnicas Essencias Greedy e Dynamic

Caminhos mínimos de todos os pares

Programação Dinâmica: Algoritmo de Bellman-Ford

Volmir Eugênio Wilhelm Departamento de Engenharia de Produção UFPR 45

Algoritmos e Estruturas de Dados II

Busca em Profundidade. Componentes Conexos. Grafos. Maria Adriana Vidigal de Lima. Fevereiro

INSTITUTO SUPERIOR TÉCNICO

Teoria dos Grafos Aula 7

Grafos Caminhos mais Curtos

Análise de Algoritmos

Grafos COM11087-Tópicos Especiais em Programação II

Caminho Mínimo de Fonte Única em Grafos sem Pesos Negativos

Fluxo Máximo a Custo Mínimo

Projeto e Análise de Algoritmos Aula 8: Algoritmos Gulosos (5)

Edsger Wybe Dijkstra

Cap. 2 Conceitos Básicos em Teoria dos Grafos

Problema do Caminho Mínimo

Introdução a Grafos Letícia Rodrigues Bueno

5COP096 TeoriadaComputação

Abordagens para Resolução de Problemas

UNIVERSIDADE DE SÃO PAULO INSTITUTO DE CIÊNCIAS MATEMÁTICAS E DE COMPUTAÇÃO Departamento de Ciências de Computação

Algoritmo de Dijkstra em LISP

SCC Laboratório de Algoritmos Avançados. Multigrafos: Caminhos Mínimos. Multigrafos e Multidígrafos. Multigrafos e Multidígrafos

Teoria dos Grafos Caminhos. Profª. Alessandra Martins Coelho

O estudo utilizando apenas este material não é suficiente para o entendimento do conteúdo. Recomendamos a leitura das referências no final deste

Análise e Síntese de Algoritmos

QUESTÕES DE PROVAS ANTIGAS

Aula 10: Tratabilidade

UNIVERSIDADE DE SÃO PAULO INSTITUTO DE CIÊNCIAS MATEMÁTICAS E DE COMPUTAÇÃO Departamento de Ciências de Computação

Transcrição:

1 de 8 26/08/2013 22:34 Algoritmo de Prim Origem: Wikipédia, a enciclopédia livre. Na ciência da computação o algoritmo de Prim é um algoritmo guloso (greedy algorithm) empregado para encontrar uma árvore geradora mínima (minimal spanning tree) num grafo conectado, valorado e não direcionado. Isso significa que o algoritmo encontra um subgrafo do grafo original no qual a soma total das arestas é minimizada e todos os vértices estão interligados. O algoritmo foi desenvolvido em 1930 pelo matemático Vojtěch Jarník e depois pelo cientista da computação Robert C. Prim em 1957 e redescoberto por Edsger Dijkstra em 1959. Outros algoritmos conhecidos para encontrar árvores geradoras mínimas são o algoritmo de Kruskal e algoritmo de Boruvka. No entanto estes algoritmos podem ser empregados em grafos desconexos, enquanto o algoritmo de Prim precisa de um grafo conexo. Índice 1 Descrição 1.1 Algoritmo genérico 2 Pseudocódigo 3 Complexidade 4 Exemplo de execução 5 Implementações 5.1 Implementação em Python 5.2 Implementação em PHP 6 Referências 7 Bibliografia 8 Ligações Externas Descrição O algoritmo de Prim encontra uma árvore geradora mínima para um grafo desde que ele seja valorado e não direcionado. Por exemplo, se na figura 1 os vértices deste grafo representassem cidades e as arestas fossem estradas de terra que interligassem estas cidades, como poderíamos determinar quais estradas asfaltar gastando a menor quantidade de asfalto possível para interligar todas as cidades. O algoritmo de Prim neste caso fornecerá uma resposta ótima para este problema que não necessariamente é única. A etapa f) da figura 1 demonstra como estas cidades devem ser conectadas com as arestas em negrito. Algoritmo genérico Um algoritmo genérico para o algoritmo de Prim é dado da seguinte forma: Escolha um vértice S para iniciar o subgrafo enquanto há vértices que não estão no subgrafo selecione uma aresta segura insira a aresta segura e seu vértice no subgrafo Pseudocódigo

2 de 8 26/08/2013 22:34 prim(g) # G é grafo # Escolhe qualquer vértice do grafo como vértice inicial/de par s seleciona-um-elemento(vertices(g)) para todo v vertices(g) π[v] nulo Q {(0, s) S ø enquanto Q ø v extrair-mín(q) S S {v para cada u adjacente a v se u S e pesodaaresta(π[u] u) > pesodaaresta(v u) Q Q \ {(pesodaaresta(π[u] u), u) Q Q {(pesodaaresta(v u), u) π[u] v retorna {(π[v], v) v vertices(g) e π[v] nulo π[v] indica o predecessor de v. Após o término do algoritmo, para cada v pertencente aos vértices de G, π[v] v representa uma aresta selecionada para a árvore geradora mínima se π[v] nulo. O algoritmo retorna o conjunto dessas arestas, formado pelos pares (π[v], v). Q é um conjunto de pares (peso, vértice). O método extrair-mín(q) deve extrair o menor elemento de Q; um Figura 1: passo a passo da execução do algoritmo de Prim iniciado pelo vértice 0 par (a,b) é menor que um par (c,d) se a < c ou se a = c e b < d. S é um conjunto que armazena os vértices cujas adjacências já foram analisadas. Complexidade A complexidade do algoritmo de Prim pode mudar de acordo com a estrutura de dados utilizada para representar o grafo. As implementações mais comuns para um grafo são por listas de adjacência e por matrizes de adjacência e suas respectivas complexidades e no pior caso. Exemplo de execução Repare neste exemplo de execução do algoritmo como as arestas são escolhidas para entrar no subgrafo. O conjunto V\U são os vértices que ainda não entraram no subgrafo, o conjunto U são os vértices que já estão no subgrafo, as arestas possíveis é uma lista de arestas que poderiam ser incluidas no subgrafo, pois conectam vértices contidos no subgrafo com os que ainda não estão e as arestas incluídas são aquelas que já estão no subgrafo. Dessa maneira e segundo o algoritmo genérico dado acima, para escolhermos uma aresta segura devemos observar o conjunto de arestas possíveis e selecionar aquelas que não formam ciclos com o subgrafo até entao formado e cujo peso é o mínimo possível naquele momento. Se uma aresta apresentar todos estes quesitos podemos considerá-la uma aresta segura.

lgoritmo de Prim Wikipédia, a enciclopédia livre de 8 26/08/2013 22:34 Imagem Arestas incluídas no subgrafo U Arestas possíveis V \ U Descrição { { {A,B,C,D,E,F,G Este é o grafo original. Os números próximos das arestas significam o seu peso. {DA {D {D,A = 5V {D,B=9 {D,E=15 {D,F=6 {A,B,C,E,F,G O vértice D foi escolhido como ponto inicial do algoritmo. Vértices A, B, E e F estão conectados com D através de uma única aresta. A é o vértice mais próximo de D e, portanto a aresta AD será escolhida para formar o subgrafo. DF {A,D {D,B=9 {D,E=15 {D,F=6V {A,B=7 {B,C,E,F,G O próximo vértice escolhido é o mais próximo de D ou A. B está a uma distância 9 de D, E numa distância 15 e F numa distância 6. E A está a uma

4 de 8 26/08/2013 22:34 distância de 7 de B. Logo devemos escolher a aresta DF, pois é o menor peso. DF, AB {A,D,F {D,B=9 {D,E=15 {A,B=7V {F,E=8 {F,G=11 {B,C,E,G Agora devemos escolher o vértice mais próximo dos vértices A, D ou F. A aresta em questão é a aresta AB. DF, AB, BE {A,B,D,F {B,C= 8 {B,E=7V {D,B=9ciclo {D,E=15 {F,E=8 {F,G=11 {C,E,G Agora podemos escolher entre os vértices C, E, e G. C está a uma distância de 8 de B, E está a uma distância 7 de B e G está a 11 de F. E é o mais próximo do subgrafo e, portanto escolhemos a aresta BE. DF, AB, BE, EC {A,B,D,E,F {B,C=8 {D,B=9ciclo {D,E=15ciclo {E,C=5V {E,G=9 {F,E=8 ciclo {F,G=11 {C,G Restam somente os vértices C e G. C está a uma distância 5 de E e de G a E 9. C é escolhido, então a aresta EC entra no

5 de 8 26/08/2013 22:34 DF, AB, BE, EC, EG DF, AB, BE, EC, EG {A,B,C,D,E,F {A,B,C,D,E,F,G {B,C=8ciclo {D,B=9ciclo {D,E=15ciclo {E,G=9V {F,E=8ciclo {F,G=11 {B,C=8 ciclo {D,B=9 ciclo {D,E=15 ciclo {F,E=8 ciclo {F,G=11 ciclo {G { subgrafo construído. Agora só resta o vértice G. Ele está a uma distância de 11 de F, e 9 de E. E é o mais próximo, então G entra no subgrafo conectado pela aresta EG. Aqui está o fim do algoritmo e o subgrafo formado pelas arestas em verde representam a árvore geradora mínima. Nesse caso esta árvore apresenta a soma de todas as suas arestas o número 39. Implementações Implementação em Python A implementação a seguir usa uma lista de adjacência para representar o grafo. A complexidade de tempo é. Uma função adicional, primdesconexo, resolve o problema para grafos desconexos, sem alterar a complexidade de tempo do algoritmo. # Implementacao do algoritmo de Prim O(E log V) em Python # Note que a unica funcao que representa a implementacao do algoritmo eh a funcao prim(graph,vi=0,edge=[],vi # A funcao add_edge eh apenas auxiliar, e a funcao primdesconexo(graph) eh um adicional, e nao costuma seque # implementada para o algoritmo de Prim (pois no caso de um grafo ser desconexo, Kruskal eh a solucao ideal)

6 de 8 26/08/2013 22:34 from heapq import heappop, heappush MAXV = 1000 # numero de vertices no grafo graph = [[] for x in xrange(maxv)] def add_edge(v, u, w): graph[v].append((u,w)) graph[u].append((v,w)) # considera que o grafo eh nao direcionado # Se o grafo for totalmente conectado, Vi pode receber qualquer vertice sem diferenca no peso total da arvor # Se o grafo for desconexo, apenas a parte conectada a Vi tera sua arvore geradora minima calculada # O retorno eh uma lista de tuplas edge[v]=(w,u), que representa, para cada v, a aresta u->v com peso w, usa # conectar a sub-arvore de v a sub-arvore de u na arvore geradora minima def prim(graph, Vi=0, edge=[], vis=[]): # edge[v] = (pesodaaresta(u->v), u) # Se edge[] ou vis[] nao tiverem sido gerados ainda, geramos. Geralmente esta condicao nao existe, e amb # sao geradas dentro do proprio prim; porem, para manter o primdesconexo em O(V + E log V), permitimos q # passadas pelos parametros da funcao. if edge == []: edge = [(-1,-1)] * len(graph) if vis == []: vis = [False] * len(graph) edge[vi] = (0,-1) heap = [(0,Vi)] while True: v = -1 while len(heap) > 0 and (v < 0 or vis[v]): v = heappop(heap)[1] if v < 0 or edge[v][0] < 0: break vis[v] = True for (u, w) in graph[v]: if edge[u][0] < 0 or edge[u][0] > w: edge[u] = (w, v) heappush(heap, (edge[u][0],u)) return edge # Se o grafo for desconexo, pode-se usar: def primdesconexo(graph): edge = [(-1,-1)] * len(graph) vis = [False] * len(graph) for i in xrange(len(graph)): if edge[i][0] == -1: prim(graph, i, edge, vis) return edge Implementação em PHP $origem = array( 1 => 1,1,2,2,2,3,4,4,5); $destino = array( 1 => 2,3,3,4,5,5,6,5,6); $custo = array( 1 => 1,3,1,2,3,2,3,-3,2); $nos = 6; $narcos = 9; // Define o infinito como sendo a soma de todos os custos $infinito = array_sum($custo); // Imprimindo origem destino e custo echo utf8_decode("grafo:<br>"); for($i =1 ; $i <= count($origem) ; $i++) { echo utf8_decode("$origem[$i] $destino[$i] $custo[$i]<br>"); // ------ Passo inicial // Seta os valores de T for($i =1 ; $i <= 6 ; $i++) { if($i == 1) { $t[$i] = $i;

7 de 8 26/08/2013 22:34 else { $t[$i] = "nulo"; // Seta os valores de V for($i =1 ; $i <= 6 ; $i++) { if($i == 1) { $v[$i] = "nulo"; else { $v[$i] = $i; echo utf8_decode("início"); echo utf8_decode("<br> T: "); print_r($t); echo utf8_decode("<br> V: "); print_r($v); echo utf8_decode("<br>"); // ------ Fim do passo inicial $total_nos = count($origem); for($x =1 ; $x <= ($nos-1) ; $x++) { // Verifica origem -> destino $minimo1 = $infinito; for($i =1 ; $i <= $narcos ; $i++) { for($j =1 ; $j <= $nos ; $j++) { if($origem[$i] == $t[$j]) { for($k =1 ; $k <= $nos ; $k++) { if($destino[$i] == $v[$k]) { if($custo[$i] < $minimo1) { $minimo1 = $custo[$i]; $aux1 = $i; // Verifica destino -> origem $minimo2 = $infinito; for($i =1 ; $i <= $narcos ; $i++) { for($j =1 ; $j <= $nos ; $j++) { if($destino[$i] == $t[$j]) { for($k =1 ; $k <= $nos ; $k++) { if($origem[$i] == $v[$k]) { if($custo[$i] < $minimo2) { $minimo2 = $custo[$i]; $aux2 = $i; if($minimo2 < $minimo1) { $cont = 1; $minimo = $minimo1; $aux = $aux1; echo utf8_decode("<br> Aresta ($origem[$aux],$destino[$aux]) escolhida de custo $custo[$aux]") else { $minimo = $minimo2; $aux = $aux2; echo utf8_decode("<br> Aresta ($destino[$aux],$origem[$aux]) escolhida de custo $custo[$aux]") $cont = 2; if($cont == 1) { $t[$destino[$aux]] = $destino[$aux]; $v[$destino[$aux]] = "nulo"; else { $t[$origem[$aux]] = $origem[$aux]; $v[$origem[$aux]] = "nulo"; echo utf8_decode("<br> ".$x." iteração"); echo utf8_decode("<br> T: "); print_r($t); echo utf8_decode("<br> V: ");

8 de 8 26/08/2013 22:34 print_r($v); Referências Bibliografia CORMEN, Thomas; Stein, Clifford. Introduction to Algorithms (em inglês). 2 ed. [S.l.]: MIT Press and McGraw-Hill, 2001. Capítulo: 23, ISBN 0-262-03293-7 Ligações Externas Algoritmo de Prim (http://www.mincel.com/java/prim.html) Exemplo animado de um algoritmo de Prim (http://students.ceid.upatras.gr/~papagel/project/prim.htm) Demonstração em Python de uma árvore mínima (http://people.csail.mit.edu/rivest/programs.html) Implementção em Java do algoritmo de Prim (http://code.google.com/p/annas/) Implementação em C# do algoritmo de Prim (http://code.google.com/p/ngenerics/) Obtida de "http://pt.wikipedia.org/w/index.php?title=algoritmo_de_prim&oldid=36757162" Categoria: Algoritmos de grafos Esta página foi modificada pela última vez à(s) 03h46min de 26 de agosto de 2013. Este texto é disponibilizado nos termos da licença Atribuição-Partilha nos Mesmos Termos 3.0 não Adaptada (CC BY-SA 3.0); pode estar sujeito a condições adicionais. Consulte as condições de uso para mais detalhes.