• Home
  • Projetos
  • Palestras
  • Artigos
  • Livros

Calcular o caminho euleriano em PHP

08/09/2008  Ler e Comentar

Um caminho euleriano em um grafo é o caminho que usa cada aresta exatamente uma vez. Se tal caminho existir, o grafo é chamado traversável. Um ciclo euleriano é um ciclo que usa cada aresta exatamente uma vez. O ciclo euleriano é utilizado para resolver o problema do caixeiro viajante.
Existe um conceito paralelo: um caminho hamiltoniano em um grafo é o caminho que visita cada nodo uma só vez; e um ciclo hamiltoniano é um ciclo que visita cada vértice uma só vez. O caminho hamiltoniano é utilizado para resolver o problema do carteiro chinês.
O algoritmo a seguir descobre o ciclo euleriano utilizando "Cycle finding algorithm".

This algorithm is based on the following observation: if C is any cycle in a Eulerian graph, then after removing the edges of C, the remaining connected components will also be Eulerian graphs.
The algorithm consists in finding a cycle in the graph, removing its edges and repeating this steps with each remaining connected component. It has a very compact code with recursion:


'tour' is a stack
find_tour(u):
for each edge e=(u,v) in E:
remove e from E
find_tour(v)
prepend u to tour

to find the tour, clear stack 'tour' and call find_tour(u),
where u is any vertex with a non-zero degree.


<?php
/**
* Euler Walk
* Encontra o caminho euleriano a partir de uma matriz de adjacências
* @author Pablo Dall'Oglio <pablo at dalloglio.net>
*/

// matriz de adjacencia
$m[0] = array(0,1,1,0,0,0,0,0);
$m[1] = array(1,0,0,0,1,0,0,0);
$m[2] = array(1,0,0,1,1,0,0,0);
$m[3] = array(0,0,1,0,0,0,0,0);
$m[4] = array(0,1,1,0,0,1,1,0);
$m[5] = array(0,0,0,0,1,0,0,1);
$m[6] = array(0,0,0,0,1,0,0,1);
$m[7] = array(0,0,0,0,0,1,1,0);

// conta os impares
$min_sum=INF;
foreach (
$m as $key => $row)
{
    
$sum = array_sum($row);
    if (
$sum % 2 !== 0)
    {
        
$odds[] = $key;
        if (
$sum<$min_sum)
        {
            
$min_sum=$sum;
            
$min_key=$key;
        }
    }
}
reset($m);
$odds[] = key($m);
// se tem mais de três nodos com qtde ímpar de arestas,
// não há como ter caminho euleriano
if (count($odds)>3)
{
    die(
"Mais de tres impares");
}

// começa pelo menor ímpar, senão começa pelo primeiro
$first = count($odds)>0 ? $min_key : key($m);;
echo 
find_tour($m, $first);
echo 
"$first\n";

/**
* função recursiva para encontrar
* o caminho euleriano
*/
function find_tour(&$matriz, $vertice)
{
    
// echo "=>$vertice\n";
    // descobre o proximo vertice
    
foreach ($matriz as $key => $row)
    {
        if (
$row[$vertice])
        {
            
// marca como visitado
            
$matriz[$key][$vertice] = 0;
            
$matriz[$vertice][$key] = 0;
            
$next = $key;
            
find_tour($matriz, $next);
            echo 
$next."\n";
        }
    }
}
?>




Comentários

  Erros 

Alguns comentários com relação a sua solução para o problema:
1) Seu algoritmo não determina o caminho euleriano, mas sim o ciclo euleriano.
2) A condição 'número de vértices ímpares' > 3 não está correta. Para existir um ciclo euleriano em um grafo não-dirigido, não devem haver vértices de grau ímpar. Para haver um caminho euleriano, no entanto, deve haver exatamente 2 vértices com grau ímpar.

  Enviado por Luiz Ribeiro em 2008-11-29  



 Adicionar Comentário
 Nome
 Email
 Título
 Comentário

Livros


  • Outros

    • Galeria de Fotos
    • Posts no Codare

    Arquivo

    • 2009
    • 2008
    • 2007
    • 2006
    • 2005
    • 2004
  • Google

    Blogroll

    • Adler Medrado
    • Aurélio Jargas
    • Andrei Zmievski
    • Eduardo Maçan
    • Efetividade
    • Er Galvão
    • Joel on Software
    • Marcelio Leal
    • Martin Fowler
    • Miguel de Icasa
    • Newton Wagner
    • Rafael Dohms
    • Rasmus Lerdorf
    • Sérgio Crespo
    • Timoty Ney

    Posts Aleatórios

    • Canon SX100 - Sem comparação
    • phpNow! em Petrópolis-RJ
    • 2 Workshop PHPMS
    • GNUTeca no Rio
    • PHPMagazine 05 disponível
    • Passeio nas Missões
    • Piratas do Vale do Silício
    • Luau do Sesi e Show do Cidadao Quem em Teutônia
    • Relato da PHP Conference
    • PHP Programando com Orientação a Objetos :: Segunda Edição
    • II Forum Gnome
    • 5o. Fórum Internacional de Software Livre
    • III Seminário de Desenvolvimento de Software Livre
    • Calcular o caminho euleriano em PHP
    • Onde está o Pablo ?
    • Gerando Thumbs em PHP
    • Férias 2010
    • Finalmente Mestre!
    • Semana de Capacitação em Software Livre
    • Escritório de nerd imitando de executivo
 
Designed by Wolfgang Bartelme Designed by Wolfgang Bartelme

© 2006 Wordpress Themes | Theme (Not so) Fresh
XHTML CSS