Simulação e detecção em redes através de MST's - T 3
O objetivo deste trabalho é detectar comunidades em um grafo. A identificação dos grupos ou comunidades será realizada da seguinte forma: primeiramente computa-se uma MST(Minimum Spanning Tree) do grafo G = (V, E) em questão. De posse da MST, a forma mais trivial de obter grupos ou comunidades consiste em isolar conjuntos de vértices através da remoção de arestas da MST. Neste trabalho, o critério a ser utilizado é a remoção da maior aresta da MST no caso de 2 grupos. Para obter 3 grupos, deve-se remover as 2 maiores arestas da MST e assim sucessivamente de modo que para se obter K grupos deve-se remover as K-1 maiores arestas da MST. Para gerar a MST necessária para a computação das comunidades utilizaremos o algoritmo de Prim.
o O algorimo de Prim:
A figura 2 ilustra a MST gerada para o grafo analisado neste trabalho.
- Materiais utilizados:
Mais uma vez usamos a linguagem Python para fazer os algoritmos e simular a detecção das comidades. No Windows, usamos o Python(x,y), que engloba uma série de bibliotecas e alguns ambientes de desenvolvimento. Spyder é um destes ambientes e foi utilizado para a programação e execução dos algoritmos. Abaixo estão os links para mais informações sobre o ambiente de programação, sobre a biblioteca NetworkX também usada neste trabalho para facilitar a manipulação dos grafos e também a ferramenta Setuptools que permite de forma fácil instalar bibliotecas Python, em especial a NetworkX que não vem inclusa no pacote do Python(x,y). links:
- https://pypi.python.org/pypi/setuptools
- Grafo:
O grafo utilizado neste trabalho é um grafo ponderado de 59 vértices que relaciona a distâncias entre as cidades na Alemanha
- Desenvolvimento:
Nesta seção apresentaremos alguns aspectos teóricos bem como os resultados obtidos na execução do algoritmo, a construção da MST e a detecção das comunidades.
o A Minimum Spanning Tree (Árvore geradora minima):
As MST's são árvores - árvores são grafos do acíclicos, conexo onde existe um único caminho entre quaisquer dois vértices - que minimiza a soma dos pesos de uma aresta de um grafo ponderado.
![]() |
| Figura 1 - Exemplo de uma árvore geradora mínima em uma grafo G. |
o O algorimo de Prim:
O algoritmo de Prim é um algoritmo que utiliza uma estratégia gulosa, para encontrar a MST de um grafo ponderado, conectado e não-direcionado. O algoritmo foi desenvolvido em 1930 pelo matemático Vojtěch Jarník e depois pelo cientista da computação Robert Clay Prim em 1957 e redescoberto por Edsger Dijkstra em 1959.
A ideia geral deste algoritmo consiste em cada passo, partindo de um vértice raiz, adicionar a MST a aresta de menor custo que sai do conjunto dos vértices já visitados e chaga no conjunto dos vértices não visitados. A implementação do algoritmo sera apresentada no decorrer do texto.
o Implementação:
A implementação do algoritmo será apresentada em várias partes. Primeiramente sera apresentado o código que realiza a geração da MST, apresentaremos a implementação do algoritmo de Prim, bem como as funções que plotam o grafo. Em seguida, apresentaremos o algoritmo que gera as comunidades, 3 e 4 comunidades.
O trecho do algoritmo abaixo faz a geração da MST, neste código fazemos criamos uma arvore, carregamos a matriz de adjacência do grafo g, criamos as arestas baseados na matriz e por fim chamamos o Prim_algorithm(), passado g como parâmetro. Este método gerará a MST e chamara a função que desenhara a matriz na tela.
O próximo trecho é a implementação do algoritmo de Prim. Como já introduzido, o algoritmo a cada passo seleciona a aresta de menor custo. Isso é feito utilizando uma lista de prioridades. Nesta lista a cada passo será retirado no vértice de menor custo, custo este dado por um lambda que representa o custo(distância) de chegar ao vértice atual, que o passo do algoritmo está, partindo de outro vértice predecessor x. Note que x e v representado por este lambda já é o menor caminho para se chegar a v. então o algoritmo verifica nos vizinhos de v se o caminha v ~ u, onde u é um vértice vizinho de v, é menor do que o caminho para se chegar a u que já fora computado (visitado) em outro passo. Uma observação, é que caso o vértice u ainda não foi descoberto, ou seja, não foi computado um caminho até ele, o caminho v~u é sempre o menor, pois não existe outro, então este caminho será computado na árvore até que se ache, se existir, um outro melhor. V, então, é adicionado á uma fila de predecessores como sendo o predecessor de u. Ao final do algoritmo a fila de predecessores representa a MST.
Outras funções usadas pelo algoritmo também estão expostas neste trecho. A função minimo() retorna a posição do vértice com minimo lambda na fila de prioridades. A função Gera_Arvore() cria a MST a partir do vetor de predecessores e chama a função para plotar a árvore. A função plot_weighted_graph(G) utiliza algumas funções da networkX para plotar um grafo, neste caso a MST.
A ideia geral deste algoritmo consiste em cada passo, partindo de um vértice raiz, adicionar a MST a aresta de menor custo que sai do conjunto dos vértices já visitados e chaga no conjunto dos vértices não visitados. A implementação do algoritmo sera apresentada no decorrer do texto.
o Implementação:
A implementação do algoritmo será apresentada em várias partes. Primeiramente sera apresentado o código que realiza a geração da MST, apresentaremos a implementação do algoritmo de Prim, bem como as funções que plotam o grafo. Em seguida, apresentaremos o algoritmo que gera as comunidades, 3 e 4 comunidades.
O trecho do algoritmo abaixo faz a geração da MST, neste código fazemos criamos uma arvore, carregamos a matriz de adjacência do grafo g, criamos as arestas baseados na matriz e por fim chamamos o Prim_algorithm(), passado g como parâmetro. Este método gerará a MST e chamara a função que desenhara a matriz na tela.
O próximo trecho é a implementação do algoritmo de Prim. Como já introduzido, o algoritmo a cada passo seleciona a aresta de menor custo. Isso é feito utilizando uma lista de prioridades. Nesta lista a cada passo será retirado no vértice de menor custo, custo este dado por um lambda que representa o custo(distância) de chegar ao vértice atual, que o passo do algoritmo está, partindo de outro vértice predecessor x. Note que x e v representado por este lambda já é o menor caminho para se chegar a v. então o algoritmo verifica nos vizinhos de v se o caminha v ~ u, onde u é um vértice vizinho de v, é menor do que o caminho para se chegar a u que já fora computado (visitado) em outro passo. Uma observação, é que caso o vértice u ainda não foi descoberto, ou seja, não foi computado um caminho até ele, o caminho v~u é sempre o menor, pois não existe outro, então este caminho será computado na árvore até que se ache, se existir, um outro melhor. V, então, é adicionado á uma fila de predecessores como sendo o predecessor de u. Ao final do algoritmo a fila de predecessores representa a MST.
Outras funções usadas pelo algoritmo também estão expostas neste trecho. A função minimo() retorna a posição do vértice com minimo lambda na fila de prioridades. A função Gera_Arvore() cria a MST a partir do vetor de predecessores e chama a função para plotar a árvore. A função plot_weighted_graph(G) utiliza algumas funções da networkX para plotar um grafo, neste caso a MST.
A figura 2 ilustra a MST gerada para o grafo analisado neste trabalho.
![]() |
| Figura 2 - Grafo que representa a MST gerada a partir do código do Prim, implementado acima. |
A seguir está sendo apresentado o código que gera as comunidades no grafo a partir da MST.
Neste trecho, do mesmo modo que acima, é feita a leitura do grafo g e gerado a MST. Um dicionários com arestas sendo a chave e o peso sendo o dado associado a chave é usado para armazenar todas as arestas da MST. Logo em seguida, o o dicionário é transformado em uma lista onde cada elemento da lista continua sendo a relação aresta/peso, no entanto, esta lista está ordenada em relação aos pesos. Então o for da linha 77 e 78, itera 3 e ou 4 vezes sobre a lista de arestas deletando as 3 e ou as 4 aresta de maior peso, últimos elementos da lista, criando respectivamente 3 e 4 comunidades.
As figuras 3 e 4 mostram as saídas do grafo com 3 e quatro comunidades. Os desenhos dos grafos obtidos foram os melhores conseguidos por nós.
Neste trecho, do mesmo modo que acima, é feita a leitura do grafo g e gerado a MST. Um dicionários com arestas sendo a chave e o peso sendo o dado associado a chave é usado para armazenar todas as arestas da MST. Logo em seguida, o o dicionário é transformado em uma lista onde cada elemento da lista continua sendo a relação aresta/peso, no entanto, esta lista está ordenada em relação aos pesos. Então o for da linha 77 e 78, itera 3 e ou 4 vezes sobre a lista de arestas deletando as 3 e ou as 4 aresta de maior peso, últimos elementos da lista, criando respectivamente 3 e 4 comunidades.
As figuras 3 e 4 mostram as saídas do grafo com 3 e quatro comunidades. Os desenhos dos grafos obtidos foram os melhores conseguidos por nós.
![]() |
| Figura 3 - Grafo com 3 comunidades, gerados a partir da MST do grafo analisado neste trabalho. |
![]() |
| Figura 4 - Grafo com 4 comunidades, gerados a partir da MST do grafo analisado neste trabalho. |
















