Grafos Hamiltonianos
“O amor é paciente, é bondoso. Não inveja, não se vangloria, não se orgulha. Não
Problema
Um representante comercial
(“caixeiro-viajante”, em português “fora de moda”)
Precisa visitar várias cidades (a
negócio) e retornar à cidade de onde saiu
Como percorrer o menor caminho
Problema
Caso mais simples (será?)
Distâncias unitárias entre as cidades Objetivo: evitar repetição de cidade!
Caso mais complexo
Distâncias quaisquer
Estrutura da Aula
1.
Grafos e Ciclos Hamiltonianos
2.
Problema do Caixeiro-Viajante
(TSP)
1. Grafos e Ciclos
Hamiltonianos
Definições (Direcionado ou Não)
Ciclo Hamiltoniano
Caminho que passa exatamente uma vez
por cada vértice e retorna ao vértice inicial
Grafo Hamiltoniano
Todo grafo que contém um ciclo
Exemplo
Dois grafos Hamiltonianos
Eulerianos x Hamiltonianos
Um Grafo Hamiltoniano tem um ciclo que
visita todos os vértices exatamente uma vez
Pode não visitar todas as arestas
Um Grafo Euleriano tem um ciclo que visita
todas as arestas exatamente uma vez
Pode não visitar ou até repetir vértices
Conceitos parecidos, mas independentes
Um grafo pode ser de um dos tipos e não ser do
Exemplo
Grafo Hamiltoniano e Euleriano
Ciclo Hamiltoniano e Euleriano
a b c f e d a d a e b c f
Exemplo
Grafo Hamiltoniano não-Euleriano
Ciclo Hamiltoniano a b c f e d a d a e b c f
Exemplo
Grafo Euleriano não-Hamiltoniano
Ciclo Euleriano a b c e f e d a f d a e b c
Teoremas de Ore e Dirac
(Grafos Não-Direcionados)
Algumas condições suficientes para
um grafo simples não-direcionado
conectado G , com mais de 3
vértices, ser Hamiltoniano:
G é completo
ou
Para todo par de vértices u e v
não-adjacentes, vale
Sobre os Teoremas
As condições apresentadas são
muito fortes
Não são necessárias para ser Hamiltoniano
Ou seja
Se satisfaz as condições, é Hamiltoniano
Se não satisfaz, não se sabe (pode ser ou não)
Rever exemplos anteriores...
Teoremas de Ghouila-Houiri e
Meyniel (Grafos Direcionados)
Condições suficientes para um grafo
direcionado simples G, fortemente conectado, ser Hamiltoniano
Todo vértice v de G tem grau total maior ou igual
ao número de vertices (deg(v) |V|) ou
Para todo par de vértices u e v distintos e
não-adjacentes, vale
deg(u) + deg(v) 2|V| - 1
Algoritmos
Não existem (ainda) algoritmos
eficientes para o problema de
Achar um ciclo Hamiltoniano
A versão de decisão é um
problema NP-Completo clássico
Os algoritmos conhecidos são exponenciais Não se sabe se é possível criar algoritmos
eficientes
Algoritmos
Existem algoritmos eficientes
para casos específicos
Ex: Grafos Direcionados Torneios
Talvez vejamos em uma aula prática como
Aplicações
Achar um ciclo Hamiltoniano resolve
a forma mais simples do problema
apresentado no início da aula, se:
O grafo for Hamiltoniano
Aplicação
Em um almoço em que nem todos os
convidados se conhecem, é possível
colocar todos juntos em uma mesa
com cada pessoa sentada ao lado de
dois conhecidos (um no lado esquerdo
e outro no lado direito)?
Grafo não-direcionado da relação “conhece” Achar um ciclo que passe uma vez por cada
Problema Relacionado
Um problema relacionado ao
problema de achar um ciclo
Hamiltoniano é o Problema do
Caixeiro-Viajante
Certas variantes deste problema
são mais gerais e têm mais
aplicações
2. Problema do
Caixeiro-Viajante
Problema do Caixeiro-Viajante
Original
Formulação padrão
Um caixeiro-viajante planeja viajar por um
conjunto de cidades
Dado um conjunto de cidades e as
distâncias entre todas elas
Como fazer um percurso que passe por
todas elas e retorne à cidade de início percorrendo a menor distância?
Problema do Caixeiro Viajante –
Versão com Grafos
O problema pode ser representado
em um grafo completo e valorado
Cidades e distâncias entre todo par de
cidades
Para minimizar seus custos, o
caminho não deve repetir vértices
e deve ser o de custo mínimo
Problema do Caixeiro Viajante
com Grafos
Sigla TSP
Do inglês Travelling Salesman Problem
Achar um ciclo Hamiltoniano de custo
mínimo em um grafo completo e valorado
Grande importância teórica na
Computação
Variante: Múltiplas Visitas
Travelling Salesman Problem with Multiple
visits (TSPM)
Grafos com pesos, conectados quaisquer
Ciclo tem que passar pelo menos uma vez por cada vértice
Generaliza o problema de achar ciclo Hamiltoniano
Pode ser reduzido ao TSP Criar um novo grafo completo
Cada aresta de x para y representa o menor caminho de x a y
Algoritmos para o TSP
Para o problema do caixeiro-viajante
(TSP) não existem algoritmos eficientes
Os melhores algoritmos conhecidos são
exponenciais
Tratado como “problema de decisão”,
ele é NP-Completo
“dado um grafo e um valor k, indicar se existe
Algoritmos para TSP
Diferentes abordagens
1.
Algoritmos ótimos
2.
Algoritmos aproximativos
1. Algoritmos Ótimos
Dão resposta exata, mas levam
tempo exponencial
Solução força-bruta(íssima):
Examina (n-1)! ciclos distintos
Inviável para poucas dezenas de vértices...
Porém, o algoritmo “estado da
arte” já trata dezenas de milhares
de nós
2. Algoritmos Aproximativos
Ou “de aproximação” ou “aproximados”
Retornam uma solução cuja qualidade
está dentro de certa faixa de qualidade
Comprovado formal/matematicamente
O melhor algoritmo aproximativo para o
TSP dá um ciclo até 40% pior (maior) que o ótimo
3. Algoritmos Heurísticos
Ou, meramente, “heurísticas”
Não dão a resposta exata e não há
garantia formal (matemática) da
qualidade da solução
Mas, na prática, podem dar boas soluções
Podem ser usadas heurísticas
específicas ou podem ser adaptadas
técnicas genéricas de otimização
3.1 Heurística Especializada
Ex.: “Vizinho mais próximo”
Ciclo começa em um nó qualquer Repete até incluir todos:
Seja x a extremidade do caminho
Adiciona, no ciclo, o vizinho y não visitado
mais próximo de x (aresta xy)
3.2 Heurística usando Técnicas de
Otimização
Existe uma infinidade de possibilidades
Ex.: Hill-Climbing (“subida da encosta”),
variante Steepest Ascent
1. Começar com um único ciclo qualquer
2. Aplica algum operador para gerar novos ciclos
Trocar k vértices
Remover k arestas e reconfigurar o ciclo, etc.
3. Mantém apenas o melhor ciclo e repete
4. Critérios de parada: quando não surgirem ciclos
Hill-Climbing – Pseudocódigo
HILL-CLIMBING( grafo G )
cicloAtual = CICLO-ALEATORIO(G); repita
aplicar <operadores> em cicloAtual, gerando “filhos” melhorFilho = filho com menor custo
if (CUSTO(melhorFilho) < CUSTO(cicloAtual)) cicloAtual = melhorFilho;
enquanto ( <critério de parada> não atingido ) retorne cicloAtual;