web-dev-qa-db-fra.com

Recherche d'un algorithme pour trouver le chemin d'euler

Je cherche un algorithme pour trouver un chemin d'Euler dans un graphique.

J'en ai vu un bon il y a quelques semaines, mais je ne le trouve pas maintenant. Je me souviens qu'il y avait des bords de marquage, quelque chose avec des connexions paires/impaires ...

Connaissez-vous un algorithme similaire, simple et direct?

10
user2489034

À partir de Graph-Magics.com , pour un graphe non dirigé, cela vous donnera le tour dans l’ordre inverse, c’est-à-dire du sommet le plus bas au sommet:

  1. Commencez avec une pile vide et un circuit vide (chemin eulérien).
    • Si tous les sommets ont même degré: choisissez-en un. Ce sera le sommet actuel.
    • S'il existe exactement 2 sommets ayant un degré impair: choisissez l'un d'eux. Ce sera le sommet actuel.
    • Sinon, aucun circuit ou chemin d'Euler n'existe.

Répétez l'étape 2 jusqu'à ce que le sommet actuel n'ait plus de voisins et que la pile soit vide.

  1. Si le sommet actuel n'a pas de voisin:
    • Ajoutez-le au circuit,
    • Supprimez le dernier sommet de la pile et définissez-le comme étant le sommet actuel.

Autrement:

  • Ajouter le sommet à la pile,
  • Prenez n'importe lequel de ses voisins, supprimez l'arête entre le voisin sélectionné et ce sommet et définissez ce voisin comme sommet actuel.
16
MJW

Je n'ai pas de code dans aucune langue, mais je connais l'algorithme, comment le trouver et je l'écrirai ici.

Supposons que nous ayons un graphe avec n nœuds. Nous appelons degré d'un nombre de nœuds d'arêtes connectées à ce nœud. Au début, nous devrions dire que la somme des degrés de chaque nœud serait égale en fonction du "problème de négociation".

Supposons maintenant que nous ayons un chemin d'Euler p partant du noeud s et se terminant au noeud f. Ensuite, pour chaque nœud différent de st et t, chaque fois que nous entrons dans ce nœud, nous devons partir (si nous ne partons pas, nous n'atteindrons pas le nœud f final), donc pour ces nœuds, le degré sera égal à et pour s et f, s'ils sont différents degré serait impair, parce que nous avons quitté s à la première fois, puis après chaque entrée, nous avons quitté le nœud s, donc il y aurait 1 + 2 * n degré où n est le nombre de fois nous avons visité s à nouveau. Même chose pour f. Donc, il devrait y avoir 2 nœuds avec un degré impair s'il existe un chemin d'Euler. Et s'il y a un cercle d'Euler, le degré de chaque nœud doit être pair, et si tel est le cas, le nœud choisi comme s n'a pas d'importance, nous terminerons le cercle par s également.

Maintenant, le problème est de savoir comment obtenir un cercle/chemin d'Euler. Ici, nous devons définir "pont" dans le graphique. Bridge est un Edge avec une propriété spécifique. Si nous supprimons ce Edge, le nombre de composants restants dans le graphique augmenterait de un. En d'autres termes, Bridge est un Edge qui est le seul Edge à connecter entre les deux composants du graphique.

Puisque nous savons ce qu'est un pont, nous pouvons définir un algorithme. S'il existe exactement 2 nœuds de degré égal: 1) on part de l'un d'entre eux et on avance vers les nœuds suivants en choisissant des arêtes connectées au nœud actuel. 2) si nous choisissons Edge entre bridge et nonbridge, nous devrions toujours choisir none. 3) s'il ne reste aucun noeud Edge Edge, nous pourrons alors choisir n'importe quel pont.

S'il n'y a pas de nœud avec un degré impair, alors nous pouvons commencer à partir de n'importe quel nœud et suivre ces 3 règles.

C'est tout l'algorithme qui fonctionne toujours. voici quelques liens utiles aussi.

https://www.math.ku.edu/~jmartin/courses/math105-F11/Lectures/chapter5-part2.pdfhttp://www.graph-magics.com/articles/euler. php

3
Mamuka

L'algorithme de Hierholzer est un meilleur moyen de trouver le chemin d'Euler dans un graphe dirigé.

http://stones333.blogspot.com/2013/11/find-eulerian-path-in-directed-graph.html

Il a le code plus les cas de test.

3
stones333

Un chemin euler existe si un graphe a exactement deux sommets de degré impair. Ce sont en fait les extrémités du chemin euler.

Ainsi, vous pouvez trouver un sommet avec un degré impair et commencer à parcourir le graphique avec DFS: Lorsque vous vous déplacez, vous avez un tableau visité pour les arêtes. Ne traversez pas une arête deux fois.

Si vous n'avez plus d'arête d'un sommet, vérifiez si toutes les arêtes ont été visitées, si c'est le cas.

Pour stocker le chemin euler actuel, vous pouvez conserver un tableau prédécesseur, qui stocke le sommet précédent dans le chemin.

0
Aravind

Donc c'est ma solution, j'ai utilisé finalement block pour imprimer parce que j'obtiens une exception "pile est vide" et je n'ai pas vraiment le temps de réparer ça. J'espère que ça aidera quelqu'un!

public void EulerTour()
    {
        GetInput(); //gets the adjency matrix

        int start = NodeList[0]; //start from any vertex, i choose 0
        tempPath.Push(NodeList[0]); //temporary path - stack
        try
        {
            while (tempPath.Count != 0) 
            {
                for (int i = 0; i < total; i++)
                {
                    if (adjencyMatrix[start, i] == 'd')
                    {
                        tempPath.Push(NodeList[i]);
                        adjencyMatrix[start, i] = 'n';
                        adjencyMatrix[i, start] = 'n';

                        if (!hasNeighbour((int)tempPath.Peek())) //checks if current node has any neighbour
                        {
                            while (!hasNeigbour((int)tempPath.Peek()))
                            {
                                finalPath.Push(tempPath.Pop());

                            }
                            start = (int)tempPath.Peek();
                        }
                        else
                        {
                            start = i;
                            break;
                        }
                    }
                }
            }
        }
        catch
        {
            Console.WriteLine("Print: ");
        }
        finally
        {
            foreach (object o in finalPath)
            {
                Console.Write(o.ToString() + "---->");
            }
        }     
        Console.ReadKey();            
    }
0
Jure Kljajic