Professional Documents
Culture Documents
Lista de Figuras
Figura 1: Grafo (esquerda) e sua rvore Geradora Mnima (Direita).......................................... 3
Figura 2: conjunto-disjunto inicial contendo 8 arvores ou singletons.......................................... 4
Figura 3: conjunto-disjunto aps algumas operaes contendo trs arvores................................ 4
Figura 4: operao makeset. ......................................................................................................... 5
Figura 5: operao union(x, y). .................................................................................................... 5
Figura 6: operao find(x)............................................................................................................ 5
Figura 7: Pseudocdigo para o algoritmo de Kruskal .................................................................. 6
Figura 8: Encontrando A rvore Geradora Mnima atravs do algoritmo de Kruskal. ............... 7
Introduo
O Algoritmo de Kruskal um algoritmo utilizado para encontrar rvores
Geradoras Mnimas ou AGMs. Em um grafo ponderado ( , ), onde o nmero de
vrtices e o nmero de arestas, uma AGM o caminho simples (sem existncia de
ciclos) que liga todos os vrtices, tal que a , de , onde o peso de cada aresta, tal
que a minimizado. Essas arvores tm diversas aplicaes no mundo real, desde o
desenho de placas de circuito at a elaborao de rotas de comrcio.
Este trabalho se prope a apresentar uma comparao entre o algoritmo de Kruskal
implementado com Conjuntos-Disjuntos e com Matrizes de Adjacncia, e est organizado
da seguinte forma: primeiro sero apresentadas revises sobre rvores Geradoras
Mnimas, Conjuntos-Disjuntos e o Algoritmo de Kruskal, em seguida, teremos uma
explicao sobre o esquema utilizado na implementao e por fim uma concluso sobre
a realizao da tarefa e os resultados obtidos.
( ) = (
, )
( , ) (1)
minimizado. J que T acclico e conecta todos os vrtices, ele forma uma rvore, a
qual chamamos rvore geradora, e j que ele gera o grafo G. Dizemos que o problema
para determinar a arvore T chamado problema da rvore geradora mnima [1].
Conjuntos-Disjuntos
Em computao, um conjunto-disjunto uma estrutura de dados, onde elementos
com caractersticas em comum so particionados em um nmero especfico de
subconjuntos. Podemos pensar nos conjuntos-disjuntos como florestas, nas quais suas
arvores so subconjuntos com ns em comum, do contrrio, as arvores apresentaram
apenas seu n raiz, tambm chamado singleton.
makeset(x): Essa operao recebe um elemento e cria uma rvore de rank 0 cujo
n raiz o prprio elemento , ou em outras palavras um conjunto do tipo { }.
union(x, y): Essa operao combina a arvore de raiz , com a arvore de raiz ,
atravs da heurstica de unio por rank, Como vimos anteriormente a operao
makeset(x) define o rank de como 0. Assim, quando unimos com , fazemos
o n com
menor, filho do n com
maior. E atualizamos o
do n
escolhido como raiz.
find(x): Essa operao segue todos os ns a partir de at sua raiz. Durante essa
fase, usamos uma heurstica chamada compresso de caminho, onde fazemos cada
n entre o n e sua raiz, apontarem para essa raiz diretamente, comprimindo o
caminho. A operao retorna o elemento cannico do conjunto.
) com uso de ambas heursticas. Tarjan, obteve o limite superior atual para o pior-caso,
de ( ( , )) onde ( , ) a inversa da funo de Ackermann [5].
Algoritmo de Kruskal
O algoritmo de Kruskal um algoritmo utilizado na resoluo do problema de
rvores Geradoras Mnimas. Ele ir solucionar o problema, conectando dois vrtices e
de uma floresta, encontrando a prxima aresta de que liga ( , ) com o menor custo.
Esse algoritmo qualificado como guloso, tendo em vista que, a cada passo, ele adiciona
uma nova aresta com o menor peso possvel.
Sua implementao feita atravs do uso de conjuntos-disjuntos, onde cada
conjunto contm os vrtices existentes em uma arvore da floresta atual. Atravs da
operao find(u) = find(v), determinamos se dois ns e , pertencem a mesma arvore,
ou seja, se eles j esto conectados atravs da mesma aresta, em caso negativo, podemos
combinar esses ns atravs da operao union(u, v) [1].
de
aciclicamente com o menor peso possvel, e retornamos o conjunto A, agora
contendo a rvore Geradora Mnima encontrada.
Esquema de implementao
O algoritmo foi implementado em C++, atravs do framework Visual Studio 2013.
Ele conta com trs classes, a saber: a) Union_Find, pela qual representamos a estrutura
de conjuntos-disjuntos, b) Kruskal, que como o prprio nome sugere, a responsvel pela
execuo do algoritmo de Kruskal e c) Graph, que implementa uma matriz de adjacncia.
O cdigo e outros arquivos necessrios podem ser baixados atravs do seguinte
repositrio: https://www.dropbox.com/s/ef7u2lb3ghyikee/Kruskal.rar?dl=0.
A classe Union_Find foi implementada segundo as orientaes encontradas em
[3]. De incio, essa classe foi construda com duas pequenas diferenas: i) a funo MakeSet inicializava todos os conjuntos com rank 1 e ii) a funo Unite unia dois conjuntos
atravs do seguinte critrio:
if (rank[i] < rank[j]){
// unite by rank.
id[i] = j;
rank[j] += rank[i];
}
else{
id[j] = i;
rank[i] += rank[j];
}
Desse modo, caso o conjunto j tivesse o maior rank, o conjunto i seria atualizado
como seu novo filho, e em seguida, o rank de j seria teria seu valor atual somado com o
valor atual do rank de i. Caso estivssemos tratando da primeira operao de unio, os
ranks de i e j seriam iguais a 1, assim eles cairiam na segunda condio e i receberia j
como seu novo filho e teria seu rank atualizado para 2. Mas como visto em sala de aula,
essa implementao encontra-se incorreta.
A operao Make-set desse modo inicializa o rank de todos os conjuntos com 0 e
a funo Unite foi rescrita da seguinte forma:
if (rank[i] < rank[j]){
id[i] = j;
rank[j] += 1
}
else{
id[j] = i;
rank[i] += 1
}
// unite by rank.
Ficando ento essa classe da forma como foi descrita no paper acima mencionado,
o qual faz parte da bibliografia encontrada em [1].
importante dizer que a estrutura escolhida para armazenar a lista de vrtices foi
a pair, que agrupa pares de valores que podem apresentar diferentes tipos. Esses valores
podem ser acessados individualmente atravs de seus membros pblicos first e second
[4]. Definimos ento o tipo de varivel pii (pair int int) que nada mais do que um pair,
cujo primeiro e segundo membros so inteiros, nele armazenaremos dois vrtices e
simbolizando uma aresta qualquer. Definimos ainda o tipo pip (pair int pair), cujo
primeiro membro um inteiro, onde ser armazenado o valor da aresta e o segundo
membro um pair, do tipo pii.
Para ordenar as arestas de acordo com o seu peso, foi escolhida a funo sort(),
encontrada na biblioteca algorithm. Essa funo ordena os elementos dentro de um
determinado intervalo em ordem ascendente. Em mdia, essa funo tem complexidade
de , onde seria o tamanho desse intervalo [4].
Na implementao do algoritmo por meio de uma matriz de adjacncia, foi usado
um array de inteiros para salvar os vrtices que esto conectados. Quando uma nova
aresta adicionada, esse array atualizado, para conter o novo conjunto de vrtices que
compem a Arvore Geradora Mnima, similar a operao unite dos conjuntos-disjuntos,
assim a operao de unio realizada da seguinte forma:
void Graph::addEdge(int u, int v) {
A[u][v] = A[v][u] = 1;
int pv = parent[v];
int pu = parent[u];
Isso pode ser obtido num tempo de (1), assim como a operao find dos
conjuntos-disjuntos.
A ferramenta utilizada para criao dos grafos foi a Standard Network Analysis
Platform (SNAP) 2.3, uma biblioteca de minerao de grafos escrita em C++, capaz de
criar redes massivas de centenas de milhes de ns e bilhes de arestas. Ela consegue
gerar de maneira eficiente grafos randmicos, onde podemos acrescentar diversas
propriedades, tanto nos ns quanto nas arestas [6]. Foram gerados 3 grafos de tamanhos,
100, 500 e 1000 ns, com pesos randmicos nas arestas, com valores entre 0 e 100,
obtidos atravs da funo rand() da biblioteca C++. Assim, o arquivo que contm o grafo
formado apenas por sequncias de dois nmeros, que indicam uma aresta conectando
dois vrtices. Ao ler essa aresta, o programa se encarrega de inserir o seu peso, de forma
dinmica. Optei por esse mtodo para poder testar diferentes escalas de pesos e ver qual
a sua influncia no resultado final.
Abaixo temo os tempos em milissegundos obtidos para ambas implementaes
usando grafos de tamanhos variados:
Quant. De
ns
100
500
1000
Quant. De
arestas
377
3788
10130
Quant. De
ns
100
500
1000
Quant. De
arestas
377
3788
10130
Concluso
Como podemos ver, a implementao de Kruskal atravs de conjuntos-disjuntos
apresenta uma considervel melhoria no tempo de execuo. A escala de pesos
randmicos, no entanto, no acrescentou muito nos testes, porm, seria necessrio realizar
diversos outros testes com grafos mais densos, e chegar sua relevncia na tarefa.
Em uma breve busca, podemos encontrar na internet diversas implementaes
para esse algoritmo em diversas linguagens. As quais podemos utilizar como fonte de
estudo para criao do nosso prprio cdigo. O cdigo que apresento nesse trabalho foi
escrito adaptando a perspectiva contida em diversos outros cdigos a minha prpria viso
de como ele deveria funcionar. No meu ponto de vista particular, o algoritmo ficou bem
organizado e bastante legvel tanto para pessoas familiarizadas com c++, quanto aqueles
familiarizados com outras linguagens.
A maior dificuldade que encontrei durante a realizao deste trabalho, foi entender
de forma satisfatria o funcionamento dos conjuntos-disjuntos. Algo que me ajudou de
forma bastante significativa foram os vdeos do professor doutor Robert Sedgewick, da
universidade de Princeton, que apresenta um minicurso sobre essa estrutura, disponveis
livremente atravs do site youtube.
Para finalizar gostaria de dizer que este trabalho foi de grande importncia para
meu crescimento acadmico, tanto no sentido da pesquisa, quanto na aquisio de novos
conhecimentos sobre o estudo de grafos.
Referncias
[1]
Cormen, Thomas H.; Leiserson, Charles E.; Rivest, Ronald L.; Stein, Clifford.
Introduction to Algorithms Third Edition. 2009 Massachusetts Institute of technology.
[2]
Souza, Kleber J. F. Souza; Guimares, Silvio J. F. Uma Abordagem de
Simplificao de Imagem Colorida Baseada na rvore Geradora Mnima. 2011,
PUC Minas, Belo Horizonte, MG.
[3]
Harfst, Gregory C.; Reingold, Edward M. A Potential-Based Amortized
Analysis of the Union-Find Data Structure. 3 de Agosto de 2000. ACM 2000 Article.
[4] http://www.cplusplus.com/reference.
[5]
Ackermann function.
Disponvel
em
<http://www.saylor.org/site/wpcontent/uploads/2011/06/Ackermann-Function.pdf> Acesso em: 29/03/2015.
[6]
http://snap.stanford.edu/index.html.