Matemática Discreta Capítulo 3 Versão preliminar

Documentos relacionados
x y Grafo Euleriano Figura 1

Capítulo 2- Modelos de grafos.

Matemática Aplicada às Ciências Sociais- 11º ano (Versão: para o manual a partir de 2016/17)

1 Trajeto Euleriano. > Trajeto Euleriano 0/20

Noções da Teoria dos Grafos

Noções da Teoria dos Grafos. André Arbex Hallack

Noções da Teoria dos Grafos. André Arbex Hallack

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

As Pontes de Königsberg

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

Teoria dos Grafos. Valeriano A. de Oliveira Socorro Rangel Departamento de Matemática Aplicada.

1 Congruências e aritmética modular

Introdução à Teoria dos Grafos

XXXVII OLIMPÍADA PAULISTA DE MATEMÁTICA Prova da Primeira Fase 9 de agosto de 2014 Nível (6º e 7º anos do Ensino Fundamental)

Matemática Discreta. Aula 06: Teoria dos Grafos. Tópico 01: Grafos e suas Representações. Observação

Grafos IFRN. Prof.Robinson Alves

PERCURSOS. André Falcão, Carlos Augusto, Rafael Broédel e Lucas Dipré

1. O que podemos dizer sobre a imagem da função. f : Z Z, f(x) = x 2 + x + 1?

RESOLUÇÃO DCC-UFRJ MATEMÁTICA COMBINATÓRIA 2006/2 PROVA Considere a soma. S n = n 2 n 1

Algoritmos de aproximação - Problema do caixeiro viajante

Grafos Eulerianos e o Problema do Carteiro Chinês

Circuitos Hamiltorianos

MATEMÁTICA DISCRETA PARA ENGENHARIA DE COMPUTAÇÃO

Teoria dos Grafos. Árvores Geradoras

Teoria dos Grafos. Edson Prestes

GRAFOS: UMA INTRODUÇÃO

SCC603 Algoritmos e Estruturas de Dados II Prof.a Rosane Minghim 1o sem. 2013

3 O Teorema de Ramsey

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

Pontos extremos, vértices e soluções básicas viáveis

MATEMÁTICA DISCRETA. Patrícia Ribeiro 2018/2019. Departamento de Matemática, ESTSetúbal 1 / 47

15 - Coloração Considere cada um dos grafos abaixo:

2º Trabalho Prático - Algoritmos em grafos

Teoria dos Grafos. Valeriano A. de Oliveira, Socorro Rangel, Silvio A. de Araujo. Capítulo 16: Grafos Planares. Departamento de Matemática Aplicada

Método Simplex dual. Marina Andretta ICMC-USP. 24 de outubro de 2016

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

2. Desenhe o grafo orientado G = (X, Γ) para: 3. Em cada alínea dois grafos são iguais. Identifique-os. (a) (b) (c)

Existem infinitos números de Carmichael, mas não provaremos isso neste curso.

Teoria dos Grafos. Coloração de Vértices

INE5403 FUNDAMENTOS DE MATEMÁTICA DISCRETA

ESTRUTURAS DISCRETAS (INF 1631) GRAFOS. 1. O que é um grafo? Defina um grafo orientado. Defina um grafo não-orientado.

Teoria dos Grafos. Valeriano A. de Oliveira, Socorro Rangel, Silvio A. de Araujo. Departamento de Matemática Aplicada

Representação decimal dos números racionais

Programa. 1 Parte 1 - Conjuntos e Aplicações. 1 Conjuntos. 4 Indução matemática e divisibilidade. 5 Congruências lineares

Teoria dos Grafos. Edson Prestes

NÚMEROS INTEIROS E CRIPTOGRAFIA UFRJ

Marina Andretta. 10 de outubro de Baseado no livro Introduction to Linear Optimization, de D. Bertsimas e J. N. Tsitsiklis.

Grafo planar: Definição

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

14 Coloração de vértices Considere cada um dos grafos abaixo:

Departamento de Matemática da Universidade de Aveiro Matemática Discreta. A prova consta de 4 questões cada uma cotada com 5 valores.

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

UNIVERSIDADE FEDERAL DO RIO DE JANEIRO DEPARTAMENTO DE CIÊNCIAS DA COMPUTAÇÃO. 5 a Lista de Exercícios

4 3 10! Resposta pedida: 3! x 4! = 144 Resposta: C

76) 1.1 Sim 1.2 Não 1.3 Não

2 Relação entre soma dos graus e número de arestas

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

Representação decimal dos números racionais

Teoria dos Grafos. Valeriano A. de Oliveira, Socorro Rangel, Silvio A. de Araujo. Capítulo 11: Grafos Eulerianos. Departamento de Matemática Aplicada

Módulo 2 OTIMIZAÇÃO DE REDES

OBMEP 2010 Soluções da prova da 2ª Fase Nível 2. Questão 1

Lógica Proposicional Parte 3

Aula 3 Propriedades de limites. Limites laterais.

Espaços Euclidianos. Espaços R n. O conjunto R n é definido como o conjunto de todas as n-uplas ordenadas de números reais:

Árvores Árvores Geradoras de Custo Mínimo 0/16

Tópicos de Matemática Finita Data: I II-1 II-2 II-3 II-4 III-1 III-2 III-3 III-4 IV-1 IV-2 IV-3 IV-4 Nota Final

Séries de Laurent e Teoremas de Cauchy

Dízimas e intervalos encaixados.

Teoria dos Grafos. Valeriano A. de Oliveira, Socorro Rangel, Silvio A. de Araujo. Departamento de Matemática Aplicada

Percursos em um grafo

Teoria dos Grafos. Valeriano A. de Oliveira Socorro Rangel Departamento de Matemática Aplicada.

Pesquisa em Grafos. Pedro Ribeiro 2014/2015 DCC/FCUP. Pedro Ribeiro (DCC/FCUP) Pesquisa em Grafos 2014/ / 33

Teoremas de uma, duas e três séries de Kolmogorov

Teoria dos Grafos Caminhos. Profª. Alessandra Martins Coelho

Grafos I. Figura 1: Mapa de Königsberg

Circuitos Eulerianos Ciclos Hamiltonianos O Problema do Caixeiro Viajante CAMINHAMENTOS BASEADO EM TOWNSEND (1987), CAP. 7.

Otimização. Otimização em Redes. Paulo Henrique Ribeiro Gabriel Faculdade de Computação Universidade Federal de Uberlândia 2016/2

Aula 10: Tratabilidade

Instituto de Computação - Universidade Federal Fluminense Teoria dos Grafos - Lista de exercícios

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

Teoria dos Grafos. Árvores

Gabriel Coutinho DCC035 - Pesquisa Operacional Lista 6

Introdução à Teoria dos Grafos. Isomorfismo

Transcrição:

Matemática Discreta Capítulo 3 Versão preliminar Henri Anciaux e Derek Hacon October 25, 2007 1 Generalidades sobre grafos Um grafo G é simplesmente um par de dois conjuntos V e A, o segundo sendo constituído de pares de elementos do primeiro. Os elementos de V serão chamados vértices do grafo G, e os de A arestas de G. Exemplo 1 G = (V, A), com V = {V 1, V 2, V 3, V 4, V 5 } e A = {(V 1, V 2 ), (V 1, V 3 ), (V 1, V 4 ), (V 2, V 3 )} Diremos que uma aresta A = (V, V ) é adjacente a V e a V. Diremos também que V e V são adjacentes se (V, V ) é uma aresta, i.e. se (V, V ) A. Na definição das arestas, não nos importaremos com a ordem dos dois vértice, ou seja (V, V ) e (V, V ) definem a mesma aresta. Como o seu nome indica, um grafo pode ser descrito graficamente, os vértices sendo representados por pontos e as arestas adjacentes a dois vértices por um segmento ou uma curva ligando os pontos correspondentes. Porém é importante reparar que não são Figure 1: Duas representações do mesmo grafo (cf Exemplo 1) 1

relevantes em um grafo as posições relativas dos vértices e das arestas, ou a forma delas. A única coisa que nos importará é o fato de dois vértices serem ou não ligados por uma aresta. Por exemplo, os dois desenhos da Figura 1 abaixo correspondem ambos ao grafo G do Exemplo 1 Definição 1 Um caminho de G é uma sequência de vértices tais que dois vértices consecutivos são adjacentes. Se o primeiro e o último vértice da sequência são iguais, diremos que o caminho é fechado. Caso contrario, diremos que o caminho conecta o primeiro e o último vértice. Diremos que um grafo é conexo, se para dois quaisquer vértices, existe um caminho conectando-os. Definição 2 Diremos que G = (V, A ) é um subgrafo de G = (V, A) se V V e A A, isto é se ambos os vértices e as arestas de G são vértices e arestas de G. Diremos que G é um gerador de G se além disso G é conexo. Exemplo 2 O grafo G do Exemplo 1 não é conexo, já que é impossível conectar o vértice V 5 a qualquer outro. Já o subgrafo G = (V, A ) de G definido por V = {V 1, V 2, V 3, V 4 } e A = A = {(V 1, V 2 ), (V 1, V 3 ), (V 1, V 4 ), (V 2, V 3 )} é conexo. As componentes conexas de um grafo G são os conjuntos de vértices de G que podem ser todos conectados entre si. As componentes conexas do grafo do Exemplo 1 são {V 1, V 2, V 3, V 4 } e {V 5 }. Definição 3 Uma árvore é um grafo conexo que não contem ciclos. Proposição 1 Dado um grafo conexo G = (V, A), existe sempre uma árvore geradora G = (V, A ). Teorema 1 Seja G um grafo com um número n V de vértices e um número n A de arestas; (i) Se G não contem ciclos, n V n A + 1; (ii) Se G é uma árvore, n V = n A + 1; (iii) Se G é conexo, n V n A + 1. 1.1 Grau de um vértice Definição 4 O grau Gr(V ) de um vértice V de um grafo G é o número de arestas de G adjacentes a V. Exemplo 3 No Exemplo 1, Gr(V 1 ) = 3, já que as arestas adjacentes a V 1 são (V 1, V 2 ), (V 1, V 3 ) e (V 1, V 4 ); temos também Gr(V 5 ) = 0. 2

Teorema 2 A soma dos graus de todos os vértices de um grafo é igual a duas vezes o número de arestas. O número de vértices de grau ímpar de um grafo é par. Prova. A primeira afirmação é evidente: cada aresta liga dois vértices, então conta por dois na soma S dos graus de todos os vértices. Para provar a segunda afirmação, denotaremos por S p a soma dos graus dos vértices de grau par e por S i a soma dos graus dos vértices de grau ímpar. Temos visto que S é par, e S p, sendo uma soma de números pares, é par também. Decorre então que S i = S S p, sendo a diferença de dois números pares, é par. Lembrando das notações do Capítulo 2, podemos re-escrever o raciocínio simbolicamente: S i = S S p 0 0[2] 0[2]. Para terminar a prova, observamos que a soma de N números ímpares n i, 1 i N, é congruente a N módulo 2 (ou seja, é par quando N for par e ímpar quando N for ímpar). Com efeito, usando o fato que n i 1[2], temos N n i i=1 N 1[2] N[2]. i=1 Aplicando esse raciocínio a S i, concluimos que tem um número par de vértices de grau ímpar. 2 Grafos eulerianos Definição 5 Um ciclo euleriano em um grafo G é um caminho fechado que passa exatamente por cada aresta de G. Um grafo G é dito euleriano se ele admitir um ciclo euleriano. Teorema 3 Um grafo é euleriano se e somente se ele é conexo e o grau de cada vértice é par. Prova. Primeiramente mostraremos que se um grafo é euleriano, então ele é conexo e o grau de cada vértice é par. Com efeito, um caminho euleriano passa por todas as arestas, e em particular conecta todos os vértices entre si, logo o grafo é conexo. Além disso, seja V um vértice que não seja o vértice inicial (e final) do ciclo. Portanto o número de vezes em que o ciclo entra em V é igual ao número de vezes em que ele saí. Já que o ciclo é euleriano, todas as arestas ajacentes a V devem serem visitadas pelo ciclo, seja para entrar, seja para sair do vértice V. O caso do vértice inicial não é diferente: após ter saido uma primeira vez dele, o ciclo vai entrar e sair um certo número de vezes, visitando um número par de arestas. Pois ele vai entrar uma última vez para fechar o ciclo. Com a saida inicial, são ainda duas arestas (isto é, um número par) que foram visitadas. Logo o número total das arestas visitadas, isto é o grau de V, deve ser par. Para mostrar a recíproca, construiremos explicitamente um ciclo euleriano, dado um grafo G conexo com todos os seus graus pares. O método segue as seguintes etapas. 3

1) Escolha um vértice inicial V 1 e faça um caminho C 1 através do grafo, sem nunca repetir uma aresta, e continua até voltar em V 1. Afirmação 1: É sempre possível encontrar um tal caminho Se todas as arestas de G foram visitadas, obtivemos então um ciclo euleriano e paramos aqui. Caso contrario, proceda na etapa seguinte. 2) Escolha um vértice V 2 pertencente ao caminho C 1 que admite uma aresta adjacente que ainda não foi visitada Afirmação 2: Sempre existe uma tal aresta. 3) Faça um caminho saindo de V 2 por esta aresta, sem nunca repetir uma aresta nem usar uma aresta de C 1, e continua até voltar em V 2. Afirmação 3: É sempre possível encontrar um tal caminho. Se todas as arestas de G foram visitadas por C 1 e C 2, paramos aqui. Senão, passa à etapa seguinte. 2 ) Escolha um vértice V 3 pertencendo ao caminho C 1 ou ao caminho C 2 que admite uma aresta adjacente que ainda não foi visitada O algoritmo procede assim por diante, criando ciclos C 1,..., C n, de jeito que C n tem um vértice em comum com um dos ciclos anteriores, até que cada aresta seja visitada por algum ciclo. Para finalizar a nossa tarefa, criamos um ciclo C juntando os ciclos C 1,..., C n entre si da seguinte maneira: percorremos as arestas de C 1 até encontrar um vértice que seja o ponto inicial do caminho C 2. Aí bifurcamos e percorremos todas as arestas de C 2 até voltar ao ponto inicial de C 2 ou encontrar o ponto inicial de um outro caminho C 3. No segundo caso percorremos igualmente o caminho C 3, e quando isso foi feito, terminamos o percurso de C 2. Depois, voltamos a percorrer C 1, até o final, a menos de encontrar o ponto inicial de um outro caminho. Continuamos assim por diante, até voltar ao ponto inicial de C 1 e ter assim percorrido exatamente uma vez todas as arestas do grafo G. Para terminar a prova, falta demonstrar que é sempre possível seguir as etapas descritas acima, ou seja, demonstrar que a três afirmações feitas são verdadeiras. Prova da Afirmação 1: A afirmação segue da hipótese de que o grau de cada vértice é par: assim chegando pela primeira vez em um vértice, sobra um número ímpar de arestas adjacentes que nunca foram visitadas, portanto sobra pelo menos uma. Ao sair desse vértice, o caminho deixa um número par de arestas disponíveis para uma visita futura: exatamente duas delas foram visitadas, e um número par menos dois é ainda um número par. Assim é sempre possível continuar caminhando até voltar ao ponto inicial (o grafo sendo finito, sabemos que sempre chegaremos ao ponto inicial). 4

Figure 2: Um grafo euleriano Prova da Afirmação 2: Esta afirmação decorre da hipótese de conexidade do grafo G: com efeito, seja V um vértice que foi visitado pelo caminho C 1 e V que não foi. O grafo G sendo conexo, existe um caminho C ligando V e V. Já que o vértice V não foi visitado por C 1, é claro não todas as arestas de C foram visitadas por C 1. É fácil então verificar que a primeira aresta do caminho C que não pertence ao caminho C 1 é adjacente a C 1, e a afirmação é verificada. Prova da Afirmação 3: sendo similar à prova da Afirmação 1, deixamo-la ao leitor. Exemplo 4 Implementaremos o algoritmo descrito na demonstração acima no grafo G da Figura 2: escolhemos de sair de V 1 e definimos o ciclo C 1 = (V 1, V 2, V 5, V 4, V 1 ). Vemos claramente que poderiamos ter escolhido melhor o nosso caminho: chegando em V 4, não é muito esperto voltar para V 1 em vez de ir para V 3. Mas isso não deve nos preocupar, o que é importante aqui é entender que o algoritmo descrito sempre funciona, mesmo sem ter uma percepção global do grafo (o que é o caso de um computador que segue ao pé da letra as instruções que lhe são dadas). Com efeito, seguindo o passo 2 do algoritmo, reparamos que de V 5 saí uma aresta que não foi visitada. Iniciamos então a partir de V 5 o novo ciclo C 2 = (V 5, V 6, V 10, V 9, V 5 ). Agora, vemos que não saí de C 2 nenhuma aresta disponível, voltamos então a C 1 e vemos que saí uma aresta disponível de V 4. Iniciamos então um terceiro ciclo C 3 = (V 4, V 8, V 7, V 3, V 4 ), que será o último já que todas as arestas foram visitadas. Para concluir, falta só costurar entre si o três ciclos C 1, C 2 e C 3. O resultado é C = (V 1, V 2, V 5, V 6, V 10, V 9, V 5, V 4, V 8, V 7, V 3, V 4, V 1 ). O leitor pode verificar que esse caminho visita exatamente uma vez cada aresta. 5

3 O algoritmo de Dijkstra Definição 6 Um grafo com peso (G, p) é um grafo G munido de uma função positiva p definida sobre o conjunto das arestas. Em outras palavras, a cada aresta A é atribuido um número positivo p(a). Definição 7 O peso p(c) de um caminho C = (V 1, V 2,..., V n, V n+1 ) é a soma dos pesos das arestas A 1 = (V 1, V 2 ), A 2 = (V 2, V 3 ),..., A n = (V n, V n+1 ) que ele visita: p(c) = p(a 1 ) + p(a 2 ) +... + p(a n ). Um caminho (não fechado) C é dito mínimo se, para todo caminho C com mesmos vértices inicial e final, p(c) p(c ). Denotaremos por p(v, V ) o peso de um caminho mínimo conectando os vértices V e V. Adotamos a convenção de que p(v, V ) = 0. Observação 1 Quando o grafo é uma árvore, existe sempre um único caminho entre quaisquer dois vértices (se tivesse dois caminhos distintos, teria um ciclo). Definição 8 Diremos que uma árvore H que é subgrafo de G é mínima com respeito a V 0 se para todo vértice V de H, o caminho que liga V 0 a V em H é um caminho mínimo em G. Teorema 4 (Algoritmo de Dijkstra) Dado um vértice V 0 de um grafo conexo com pesos G, existe uma árvore geradora H mínima com respeito a V 0. Prova. Vamos construir a árvore H por indução, acrescentando arestas uma depois da outra. 1) Na primeira etapa, escolhemos entre todas a arestas adjacentes a V 0 uma aresta A 1 de menor peso. Seja V 1 o outro vértice de A 1 e H 1 a árvore formada por A 1 e os seus vértices adjacentes, isto é H 1 = ({V 0, V 1 }, {A 1 }). Já que escolhamos A 1 de menor peso, é claro que qualquer caminho que conecta V 0 e V 1 tem um peso maior o igual que o peso de A 1. Portanto H 1 é uma árvore mínima. 2) Escolhemos agora uma aresta A 2 = (V, V 2 ) com V H 1 e V 2 / H 1 e tal que o número p(v 0, V ) + p(a 2 ) seja o menor possível. Observe que aqui p(v, V 0 ) = 0 se V = V 0 e p(v, V 0 ) = p(a 1 ) se V = V 1. Seja agora H 2 o grafo obtido acrescentando a H 1 o vértice V 2 e a aresta A 2, ou seja H 2 = (V 2, A 2 ) com V 2 = {V 0, V 1, V 2 } e A 2 = {A 1, A 2 }. Afirmação 1: H 1 é uma árvore mínima com respeito a V 0. 6

2 ) Repetimos a etapa anterior várias vezes, escolhendo uma aresta A n+1 = (V, V n+1 ) com V H n+1 e V n+1 / H n, tal que p(v 0, V ) + p(a n+1 ) seja o menor possível. Logo definimos H n+1 como sendo o grafo obtido acrescentando a H n o vértice V n+1 e a aresta A n+1, ou seja H n+1 = (V n+1, A n+1 ) com V n+1 = V n {V n+1 } e A n+1 = A n {A n+1 }. Afirmação 2: Se H n é uma árvore mínima com respeito a V 0, então H n+1 é também uma árvore mínima com respeito a V 0. Repetimos a etapa 2 ) até obter uma árvore geradora, o que sempre acontece com um grafo finito. A duas afirmações mostram por indução que as árvores da sequência H 0, H 1,..., H n são todas mínimas, em particular é o caso da última, e obtemos assim a existência de uma árvore H geradora e mínima. Para completar a prova, falta demonstrar as Afirmações 1 e 2. Prova da Afirmação 1: Primeiramente, V 2 sendo diferente de V 0 e V 1, é claro que H 1 não contém ciclo e portanto é uma árvore. Já vimos no item 1) que (V 0, V 1 ) é o caminho mínimo entre V 0 e V 1, logo basta mostrar que o caminho que liga V 0 e V 2 em H 1 é mínimo. Considere então qualquer outro caminho C que conecta V 0 e V 2 e seja A = (V, V ) a primeira aresta de C que não pertence a H 0 (tal aresta sempre existe já que V 2 / H 0 ). Pela escolha feita de A 2, sabemos que p(v 0, V 2 ) p(v 0, V ) + p(a ) e por outro lado, p(v 0, V ) + p(a ) p(c), portanto p(v 0, V 2 ) p(c). Demonstramos então que o caminho ligando V 0 a V 2 em H 1 tem menor peso que qualquer outro. Prova da Afirmação 2: É claro que se H n é uma árvore, H n+1 o é, já que não criamos ciclos acrescentando A n+1. Para mostrar que H n+1 é mínima, é suficiente provar que o caminho que liga V 0 e V n+1 em H n+1 é mínimo, o que se demonstra de modo análogo ao que foi feito na prova da Afirmação 1. Observação 2 É importante notar que o caminho que liga dois vértices quaisquer V e V em H não é mínimo a priori. O algoritmo de Dijkstra só dá os caminhos mínimos entre um dado vértice V 0 e todos os outros vértices de G. Logo, se quisermos encontrar um caminho mínimo entre dois outros vértices, teremos que aplicar novamente o algoritmo a partir de um deles, construindo uma árvore diferente. Exemplo 5 Vamos implementar o algoritmo de Dijkstra no grafo da Figura 3. Na primeira etapa, escolhemos a aresta D, a de menor peso saindo de V 0. Logo, devemos escolher entre as arestas A, H e K. Os pesos dos caminhos correspondentes (ligando V 0 a um dos vértices da aresta em questão) são 3(= 1 + 2), 8 e 10, portanto, escolhemos a aresta A. Logo, devemos escolher entre B, E, H e K. A aresta que cria um caminho de menor peso é E (com peso 4 = 1 + 2 + 1). Têm duas escolhas possíveis pela quarta aresta da nossa árvore: com efeito, L e K criam ambas um caminho de peso 10, enquanto as 7

Figure 3: Um grafo com peso e uma árvore mínima em relação ao vértice V 0 arestas C, F e I criariam caminhos de maior peso. Observe também que a partir de agora a aresta H está excluida, (apesar de criar um caminho de peso 8) porque ela criaria um ciclo. Continuamos assim por diante até conectar todos os vértives a V 0. Têm quatro ordens possíveis de escolha das arestas: (D, A, E, B, L, K, P, I, C, J) (D, A, E, B, K, L, P, I, C, J) (D, A, E, B, L, K, P, I, C, G) (D, A, E, B, K, L, P, I, C, G) As duas primeiras possibilidades levam ambas à construção da árvore mínima da Figura 4. As duas últimas construem uma outra árvore mínima. 4 O algoritmo do carteiro Nesta seção vamos encontrar um caminho que tem peso mínimo entre todos aqueles que passam pelo menos uma vez por todas as arestas de um grafo conexo G. Este problema tem muitas aplicações práticas: é o caso do carteiro que deve passar pelo menos uma vez em cada rua de um dado bairro para distribuir o correio mas que quer percorrer a menor distância; pelas mesmas razão é também o caso de um caminhão de lixo. O caso mais fácil para resolver este problema é quando o grafo é euleriano: vimos na Seção 2 como construir um ciclo euleriano, isto é, que passa exatamente por cada aresta. É claro então que qualquer outro caminho fechado que passa pelo menos uma vez por cada aresta deve ter um peso maior ou igual, logo os ciclos eulerianos, quando existirem, são solução do problema do carteiro. 8

Para resolver o caso de um grafo não euleriano, vamos nos inspirar desse caso mais fácil, no sentido que vamos eulerianizar o grafo. Concretamente, vamos acrescentar a G algumas arestas, que qualificaremos de virtuais, entre os vértices que são responsáveis para o grafo G não ser euleriano, isto é, as arestas de grau ímpar. Sabemos pelo Teorema 2 que tem um número par de arestas de grau ímpar, logo a maneira mais natural de acrescentar arestas é agrupar os vértices em grupos de dois, ou seja emparelhar eles, e acrescentar uma aresta a cada par de vértices. Assim, o grau de cada um desses vértices, sendo incrementado de 1, passa a ser par e o grafo assim criado (o grafo virtual) é euleriano. Logo, podemos criar um ciclo euleriano, que chamaremos também de caminho virtual, já que ele visita todas as arestas, inclusive as virtuais. A última etapa do algoritmo consiste em associar a esse caminho virtual um caminho fechado no grafo original G, que chamaremos logicamente de caminho real. Por isso, percorremos simplesmente as arestas reais do caminho virtual, e quando encontramos uma aresta virtual, a trocamos por um caminho real, isto é, usando arestas de G. Até agora, temos descrito apenas as grandes linhas do algoritmo, faltam na verdade dois detalhes importantes: Como escolher as arestas virtuais entre todos os possíveis emparalhamentos de vértices de grau ímpar? Como escolher os caminhos reais que vão substituir as arestas virtuais na hora de determinar o caminho real? As respostas a essas duas perguntas têm a ver com o objetivo do algoritmo, isto é, encontrar um caminho (fechado e passando por todas as arestas) de peso mínimo. O ponto chave aqui é que o nosso caminho real terá como peso total a soma dos pesos de todas as arestas, mais o peso dos caminhos que irão substituir as arestas virtuais. Já que não podemos reduzir a soma dos pesos das arestas (temos que passar pelo menos uma vez por cada uma, lembra-se), devemos minimizar o peso dos caminhos que substituem as arestas virtuais. Vimos na seção anterior um jeito de encontrar caminhos mínimos entre dois vértices, usando o algoritmo de Dijkstra. Vamos usar este algoritmo para determinar, dado um par de vértices (V, V ) de G de grau ímpar, o peso p(v, V ) de um caminho mínimo ligando V e V. Podemos então escolher como emparelhar os vértices de grau ímpar: queremos que a soma dos pesos p(v, V ) de todas os pares (V, V ) de nosso emparelhamento seja a menor possível. Agora podemos também responder à nossa segunda pergunta: os caminhos reais que vão substituir as arestas virtuais são exatamente os caminhos mínimos determinados pelo algoritmo de Dijkstra. Resumindo o algoritmo: Para cada par (V, V ) de vértices de G de grau ímpar, use o algoritmo de Dijkstra para determinar um caminho de peso mínimo ligando V e V ; 9

Figure 4: Um grafo não euleriano O número de vértices de G de grau ímpar sendo par, podemos agrupar eles por pares (V 1, V 1), (V 2, V 2),..., (V n, V n); escolhemos o emparelhamento que minimiza a soma n i=1 p(v i, V i ); Criamos um grafo virtual G acrescentando a G as arestas (V 1, V 1), (V 2, V 2),..., (V n, V n); observamos que todos o vértices do grafo virtual têm grau par: os graus pares de G não mudaram e os graus ímpares foram acrescentados de 1; O grafo G sendo euleriano, criamos um ciclo euleriano C nele, que passa exatamente uma vez por cada aresta, inclusive as reais (isto é as que já pertenciam a G) e as virtuais, isto é (V 1, V 1), (V 2, V 2),..., (V n, V n); Criamos o caminho fechado C em G, da seguinte maneira: percorremos as arestas reais de C e trocamos cada aresta virtual (V i, V i ) por um caminho de peso mínimo ligando V i a V i em G. Teorema 5 O caminho criado no algoritmo acima tem peso mínimo entre todos aqueles que passam pelo menos uma vez por todas as arestas de G. Exemplo 6 Vamos implementar o algoritmo do carteiro no grafo G da Figura 4. Primeiramente, identificamos os vértices de grau ímpar de G, isto é, V 1, V 2, V 6 e V 7. 10

Logo, usamos o algoritmo de Dijkstra para calcular os pesos dos caminhos mínimos entre estes quatro vértices. Observe que precisamos usar apenas três vezes o algoritmo de Dijkstra. Com efeito, determinamos primeiramente uma árvore mínima com respeito a V 1, o que nós dá p(v 1, V 2 ) = 1, p(v 1, V 6 ) = 3 e p(v 1, V 7 ) = 6. Depois, fazemos uma árvore mínima com respeito a V 2, que nós dá p(v 2, V 6 ) = 4 e p(v 2, V 7 ) = 5. Logo falta só calcular p(v 6, V 7 ), que podemos determinar com uma árvore mínima em relação a V 6 ou a V 7, dando em ambos casos p(v 6, V 7 ) = 8. Observe também que não é necessário determinar a árvore mínima completa: uma vez que temos determinado os pesos requeridos, podemos parar o algoritmo. Agora, vamos examinar os pesos dos possíveis emparelhamentos dos vértices de grau ímpar para selecionar as arestas virtuais a acrescentar para obter um grafo virtual euleriano. Os três emparelhamentos possíveis são ( (V 1, V 2 ), (V 6, V 7 ) ), de peso total 1 + 8 = 9, ( (V 1, V 6 ), (V 2, V 7 ) ), de peso 3 + 5 = 8 e ( (V 1, V 7 ), (V 2, V 7 ) ), de peso 4 + 6 = 10. Escolhemos então o segundo deles. O grafo virtual G obtido a partir de G acrescentando as arestas (V 1, V 6 ) e (V 2, V 7 ) é euleriano, portanto podemos usar o algoritmo da Seção 2 para encontrar um ciclo euleriano: C = (V 1, V 2, V 5, V 3, V 8, V 5, V 7, V 2, V 7, V 6, V 4, V 1, V 6, V 1 ). Observe que em G, têm duas arestas ligando V 1 e V 6, assim como V 2 e V 7, uma sendo real (i.e. pertencendo a G) e a outra virtual, e por isso na sequência de vértices temos em seguida V 1 e V 6 (assim como V 2 e V 7 ). Não tem importância se a primeira aresta a ser visitada é a real ou a virtual, já que não afeta o peso final do caminho. Para encontrar um caminho em G de menor peso, falto só trocar as duas arestas virtuais por um caminho de menor peso em G. Trocamos então a aresta virtual (V 1, V 6 ) pelo caminho (V 1, V 4, V 6 ) e a aresta virtual (V 2, V 7 ) por (V 2, V 5, V 7 ), obtemos finalmente um caminho fechado de peso mínimo: C = (V 1, V 2, V 5, V 3, V 8, V 5, V 7, V 2, V 5, V 7, V 6, V 4, V 1, V 4, V 6, V 1 ) 5 Árvores de peso mínimo: os algoritmos de Prim e Kruskal Seja G um grafo conexo com pesos. Um subgrafo mínimo H é uma subgrafo gerador que tem peso menor que qualquer outro gerador. É fácil ver que tal gerador é necessariamente uma árvore; com efeito se um grafo gerador tiver um ciclo, podemos tirar uma aresta deste ciclo, o grafo assim obtido fica sendo gerador, mas tem peso menor; portanto uma gerador com ciclos não pode ter peso mínimo. Em seguida veremos dois algoritmos diferentes que constroem uma árvore geradora de peso mínimo. 11

Observação 3 As árvores de peso mínimo não devem ser confundidas com as árvores mínimas encontradas no algoritmo de Dijkstra. 5.1 Algoritmo de Kruskal O príncipio deste algoritmo é muito simples: ele consiste em construir um subgrafo de G acrescentando arestas sem nunca criar ciclo. O algoritmo termina quando o subgrafo assim criado é gerador. Sendo gerador e sem ciclos, ele é uma árvore. Intuitivamente, para criar uma árvore de peso menor, a cada etapa acrescentaremos a aresta de menor peso possível que não crie ciclo, e de fato a árvore assim criada é mínima: Teorema 6 O algoritmo de Kruskal constrói uma árvore geradora de peso mínimo. Exemplo 7 Seja G o grafo com pesos da Figura 5. Uma sequência possível de arestas escolhidas pelo algoritmo de Kruskal é (D, T, H, C, O, E, Q, F, L, U). Observe que o algoritmo poderia começar pelas arestas H ou T que têm também peso mínimo. Além disso, a escolha da quarta aresta poderia ter sido O em vez de C. Finalmente, na escolha da oitava aresta, era possível escolher B ou L em vez de F, porém a escolha de F excluiria a de D e reciprocamente, por que criaria um ciclo. 5.2 Algoritmo de Prim O príncipio do algoritmo de Prim, que cria também uma árvore geradora de peso mínimo é parecido ao de Kruskal, a única diferença sendo que a sequência de arestas construídas é a cada etapa uma árvore, exatamente como no algoritmo de Dijkstra. Porém aqui a aresta escolhida a cada etapa é a de menor peso (nada de caminho mínimo!). O algoritmo procede então come segue: 1) Escolha uma aresta A 1 = (V 0, V 1 ) de menor peso em G; a árvore formada por A 1 e os seus vértices adjacentes é chamada H 1 ou seja, H 1 = ({V 0, V 1 }, {A 1 }); 2) Escolha uma aresta A 2 = (V, V 2 ) com V H 1 e V 2 / H 1 que não crie ciclo e que seja de menor peso; Seja H 2 o grafo obtido acrescentando a H 1 o vértice V 2 e a aresta A 2, ou seja H 2 = (V 2, A 2 ) com V 2 = {V 0, V 1, V 2 } e A 2 = {A 1, A 2 }; 2 ) Repetimos a etapa anterior: escolhemos uma aresta A n+1 = (V, V n+1 ) com V H n e V n+1 / H n que não crie ciclo e que seja de menor peso; logo definimos H n+1 como sendo o grafo obtido acrescentando a H n o vértice V n+1 e a aresta A n+1, ou seja H n+1 = (V n+1, A n+1 ) com V n+1 = V n {V n+1 } e A n+1 = A n {A n+1 }; O algoritmo termina quando a árvore H n é geradora. 12

13 Figure 5: Um grafo e duas árvores mínimas

Teorema 7 A árvore construída no algoritmo acima é uma árvore geradora de peso mínimo. Exemplo 8 Seja G o grafo com pesos da Figura 5. Uma das sequências possíveis de arestas escolhidas pelo algoritmo de Prim é (D, C, E, H, B, Q, T, O, L, U). Observe que, como no caso do algoritmo de Kruskal, o algoritmo poderia começar pelas arestas H ou T. Porém a sequência das arestas teria sida completamente diferente. Começando com H, as sequências possíveis são (H, Q, T, O, B, D, C, E, L, U) e (H, Q, T, O, F, E, D, C, L, U). Observe que podemos tomar como quinta aresta ambos B ou F. Esta escolha acarreta mudanças na seguida, já que se escolhermos B, fica possível escolher logo a aresta D que tem peso 1. No caso contrario, D não sai da árvore formada pelas arestas (H, Q, T, O, F ) e a escolha da sexta aresta é portanto E. 6 Exercícios 1. Seja G = (V, A) um grafo conexo e A uma aresta de G tal que o grafo G = (V, A ), com A = A {A} obtido tirando a aresta A de G não seja mais conexo. Demonstre que o grafo G não é euleriano. 2. Demonstre que uma árvore tem pelo menos dois vértices de grau 1. 3. Dê um exemplo de grafo com n V vértices e n A arestas tal que n V = n A + 1 e que não seja uma árvore. 4. Seja G um grafo com n V vértices, n A arestas e n C componentes conexas. Demonstra que n V n A + n C. 5. Implemente o algoritmo de Dijkstra no grafo da Figura 5, a partir do vértice adjacente às arestas A e C (esquina de cima a esquerda) 6. Implemente o algoritmo do carteiro no grafo com peso das Figuras 3 e 5. 7. (*) Seja H uma árvore com pesos. Demonstre que um caminho fechado solução do problema do carteiro (i.e. que passa pelo menos uma vez por cada aresta de H) passa exatamente duas vezes por cada aresta. 8. Implemente os algoritmos de Kruskal e Prim nos grafos das Figuras 3 e 4 9. Dê um exemplo de um árvore H de um grafo com peso G tal que H seja uma árvore mínima em relação a algum vértice V 0, mas que não seja uma árvore de peso mínimo. 14