Algorithm 寻找寻找欧拉路径的算法

Algorithm 寻找寻找欧拉路径的算法,algorithm,graph-theory,euler-path,Algorithm,Graph Theory,Euler Path,我在寻找一种算法,在图中找到一条欧拉路径 几周前我看过一个不错的,但现在找不到了,我记得有标记边缘,一些偶数/奇数连接的东西 你知道一个类似的简单而直接的算法吗?如果一个图正好有两个奇数度的顶点,那么就存在一个euler路径。这些实际上是euler路径的端点 因此,您可以找到一个奇数度的顶点,并开始使用DFS遍历图:当您移动时,有一个访问的边数组。不要遍历边两次 如果顶点没有留下任何边,请检查是否已访问所有边,如果已访问,则检查是否已完成 要存储实际的euler路径,可以保留一个前置数组,该数组

我在寻找一种算法,在图中找到一条欧拉路径

几周前我看过一个不错的,但现在找不到了,我记得有标记边缘,一些偶数/奇数连接的东西


你知道一个类似的简单而直接的算法吗?

如果一个图正好有两个奇数度的顶点,那么就存在一个euler路径。这些实际上是euler路径的端点

因此,您可以找到一个奇数度的顶点,并开始使用DFS遍历图:当您移动时,有一个访问的边数组。不要遍历边两次

如果顶点没有留下任何边,请检查是否已访问所有边,如果已访问,则检查是否已完成


要存储实际的euler路径,可以保留一个前置数组,该数组存储路径中的上一个顶点。

Hierholzer算法是在有向图中查找euler路径的更好方法

它有代码和测试用例。

对于无向图,这将按相反的顺序进行浏览,即从结束顶点到开始顶点:

  • 从空堆栈和空回路(欧拉路径)开始。
    • 如果所有顶点的阶数均为偶数:请选择任意一个顶点。这将是当前顶点
    • 如果正好有两个顶点具有奇数阶:选择其中一个。这将是当前顶点
    • 否则,不存在Euler回路或路径
  • 重复步骤2,直到当前顶点不再有邻居且堆栈为空

  • 如果当前顶点没有邻居:
    • 将其添加到电路中
    • 从堆栈中删除最后一个顶点并将其设置为当前顶点
  • 否则:

    • 将顶点添加到堆栈中
    • 获取其任何邻居,删除选定邻居和该顶点之间的边,并将该邻居设置为当前顶点

      • 我没有任何语言的代码,但我知道算法,知道如何查找,我将在这里编写

        假设有n个节点的图。我们称节点的阶数为连接到该节点的边数。首先,根据“握手问题”,我们应该说每个节点的和度是均匀的

        现在假设我们有一些Euler路径p,从节点s开始,到节点f结束。然后对于每个不同于st和t的节点,每次进入该节点时,我们都应该离开(如果我们不离开,那么我们就不会到达最终的f节点),所以对于这些节点,度是偶数,对于s和f,如果它们不同,度是奇数,因为我们第一次离开s,然后在每次进入后,我们离开s节点,所以会有1+2*n度,其中n是我们再次访问s的次数。f也是如此。因此,如果存在欧拉路径,则应该有两个奇数度的节点。如果有Euler圆,那么每个节点的阶数应该是偶数,如果是这样,那么选择哪个节点作为s并不重要,我们也会以s结束圆

        现在的问题是如何得到欧拉圆/路径。这里我们需要在图中定义“桥”。桥是一条具有特定属性的边,如果我们删除该边,则剩余图中的组件数将增加一个。换句话说,桥接是一条边,它是图中某些两个组件的唯一连接边

        既然我们知道什么是桥,我们就可以定义算法。如果恰好存在两个偶数度的节点: 1) 我们从其中一个节点开始,通过选择连接到当前节点的边向前移动到下一个节点。 2) 如果我们要在桥和非桥之间选择边,我们应该总是选择非桥。 3) 如果剩下的是节点非桥边,则只能选择任何桥

        如果没有奇数度的节点,那么我们可以从任何节点开始,遵循这3条规则

        这就是始终有效的整个算法。 这里还有一些有用的链接


        所以这是我的解决方案,我使用finally block打印出来,因为我得到了异常“stack is empty”,我没有时间来修复它。我希望这对别人有帮助

        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();            
            }
        
        public void EulerTour()
        {
        GetInput();//获取邻接矩阵
        int start=NodeList[0];//从任何顶点开始,我选择0
        Push(节点列表[0]);//临时路径-堆栈
        尝试
        {
        while(tempPath.Count!=0)
        {
        对于(int i=0;i”);
        }
        }     
        Console.ReadKey();
        }
        
        给定一个图(a--B--C,a--D--B)(你必须想象它),有一条B->D->a->B->C euler路径,但如果它恰好从B开始(具有奇数度),然后在DFS中首先转到C,你的算法将找不到它?