Volmir Eugênio Wilhelm Departamento de Engenharia de Produção UFPR 45 Problema da Árvore Geradora Mínima (The Minimum Spanning Tree Problem-MST) Alguns problemas de otimização combinatória podem ser formulados através de um tipo de grafo específico conhecido como árvore. Uma árvore é um grafo conexo (existe caminho entre qualquer par de seus vértices) e acíclico (que não possui ciclos). Dado um grafo conectado e não direcionado, uma árvore geradora desse grafo é um subgrafo que é uma árvore e conecta todos os vértices juntos. Um único grafo pode ter muitas árvores diferentes. Uma árvore de arborescência mínima (geradora mínima-mst) para um grafo ponderado, conectado e não direcionado é uma árvore geradora com peso menor ou igual ao peso de todas as outras árvores geradoras. O peso de uma árvore geradora é a soma dos pesos dados a cada aresta da árvore de abrangência. Modelagem matemática O modelo matemático para o problema de caminho mais curto do nó 1 ao nó n de um grafo G=(V,E) não direcionado, N = {1, 2,..., n}. Supondo nó 1 com oferta de n-1 unidades e demais nós com demanda de 1 unidade, o modelo matemático para construir uma árvore fica da forma: Variáveis: yij {0, 1} se a aresta (i, j) é usada ou não xij fluxo no arco (i, j) Parâmetros: cij custo unitário do fluxo em (i, j), c(i,j) 0 S(j) é o conjunto dos nós sucessores de j P(j) é o conjunto dos nós predecessores de j Função objetivo: i Restrições: (, ) c
Volmir Eugênio Wilhelm Departamento de Engenharia de Produção UFPR 46 (, ) (, ), j,, (, ) ( ) Obs: as restrições não controlam loops. O problema da árvore geradora mínima pode ser resolvido otimamente utilizando-se procedimento guloso no sentido de sempre escolher, sucessivamente, as arestas de menor comprimento. 1) Algoritmo de Prim Um algoritmo famoso para o problema é o Algoritmo de Prim. No algoritmo de Prim, iniciamos com uma árvore formada por um único nó (qualquer nó do grafo) e vamos adicionando à árvore, a cada passo, o nó que estiver mais próximo dela. Poderíamos resumir o algoritmo assim: Suponha que T é uma subárvore (não necessariamente geradora) de um grafo nãodirigido conexo G com custos nas arestas. A franja (=fringe) de T é o conjunto de todas as arestas de G que têm uma ponta em T e outra fora. Portanto, a franja de T nada mais é que o leque 1 do conjunto de vértices de T. Cada iteração do algoritmo começa com uma subárvore T. No início da primeira iteração, T consiste em um único vértice. O processo iterativo pode ser descrito assim. Enquanto a franja de T não estiver vazia: 1. escolha uma aresta da franja que tenha custo mínimo; 2. seja e a aresta escolhida; 3. acrescente e a T. Como se vê, o algoritmo de Prim tem caráter guloso: em cada iteração, abocanha a aresta mais barata da franja sem se preocupar com o efeito global dessa escolha. O algoritmo de Prim, sempre mantem uma árvore conectada começando com um único vértice. Analisa-se todas as arestas do vértice atual para outros e encontra o de e or custo e tre eles. E seguida, adicio a-se o vértice mais de menor custo à árvore, aumentando seu tamanho em 1. Em N 1 etapas, cada vértice estaria conectado se tivermos um gráfico conectado. Exemplo 1 1 O leque de um conjunto X de vértices de um grafo não orientado é o conjunto de todas as arestas que têm uma ponta em X e outra no complemento X de X.
Volmir Eugênio Wilhelm Departamento de Engenharia de Produção UFPR 47 Exemplo 2
Volmir Eugênio Wilhelm Departamento de Engenharia de Produção UFPR 48 2) Algoritmo de Kruskal O algoritmo de Kruskal começa com uma floresta de árvores formadas por apenas um vértice cada e procura, a cada passo, uma aresta que, além de conectar duas árvores disti tas da floresta, possua custo í i o. Supo ha que, u a determinada iteração, o algoritmo escolheu a aresta (u,v) para ser inserida no conjunto A e que a aresta (u,v) conecte a árvore C1 à árvore C2. Note que, dentre todas as arestas que conectam duas componentes distintas nesta iteração, (u,v) é uma das que possui o menor peso, pois ela foi escolhida assim. O Algoritmo de Kruskal pode, portanto, ter o seu funcionamento assim descrito: considerando cada vértice como uma árvore independente, o algoritmo procura a aresta de e or custo que conecta duas árvores diferentes. Os vértices das árvores selecionadas passam a fazer parte de uma mesma árvore. O processo se repete até que todos os vértices façam parte de uma mesma árvore ou quando não se pode encontrar uma aresta que satisfaça essa condição. Podemos agora tratar do algoritmo. Cada iteração começa com uma floresta geradora F de G. O processo iterativo é muito simples, enquanto existe alguma aresta externa: 1. escolha uma aresta externa que tenha custo mínimo; 2. seja e a aresta escolhida; 3. acrescente e a F. No início da primeira iteração, cada componente conexa da floresta F tem apenas um vértice. No fim do processo iterativo, F é conexa, uma vez que G é conexo e não há arestas externas a F. Como se vê, o algoritmo tem caráter guloso: em cada iteração, abocanha a aresta que parece mais promissora localmente sem se preocupar com o efeito global dessa escolha.
Volmir Eugênio Wilhelm Departamento de Engenharia de Produção UFPR 49 Assim como o algoritmo de Kruskal, o algoritmo de Prim também é um caso especial do algoritmo genérico. No caso do Prim, ao invés de conectar árvores de uma floresta, o algoritmo mantém uma única árvore que cresce a cada iteração com a inserção de um vértice. O algoritmo de Prim é significativamente mais rápido no limite quando o grafo é denso com muitas mais arestas do que vértices. Kruskal funciona melhor em situações típicas (gráficos esparsos), pois usa estruturas de dados mais simples. No algoritmo de Kruskal, não é mantinda uma única árvore, mas uma floresta. Em cada etapa, analisa-se a aresta de e or custo e que ão gera u ciclo a floresta atual. Esta aresta tem que ligar necessariamente duas árvores na floresta atual em uma. Uma vez que inicia com N árvores de um único vértice, em passos N 1 todos eles teriam que estar conectados se o grafo for conectado. Exemplo
Volmir Eugênio Wilhelm Departamento de Engenharia de Produção UFPR 50