Algorithm 如何在有向图中找到所有欧拉路径

Algorithm 如何在有向图中找到所有欧拉路径,algorithm,graph,Algorithm,Graph,我有一个有向图,我想找到所有现有的欧拉路径(在我的图中,我知道这些将是回路) 我已经做了一些研究,所以我可以使用Hierholzer的算法,比如在这里:从给定的节点找到一条路径,但是这个算法只返回一条我相信的路径 我解决这个问题的想法是使用一种算法,该算法将返回从给定节点开始的所有现有欧拉路径/回路。然后,我将对所有节点运行此算法并获得结果。这将有n^2或n^3的复杂性,这是非常大的 所以我的问题是,是否有一种算法可以从给定的节点找到有向图中的所有欧拉路径/回路?也许有人知道我问题的另一个解决办

我有一个有向图,我想找到所有现有的欧拉路径(在我的图中,我知道这些将是回路)

我已经做了一些研究,所以我可以使用Hierholzer的算法,比如在这里:从给定的节点找到一条路径,但是这个算法只返回一条我相信的路径

我解决这个问题的想法是使用一种算法,该算法将返回从给定节点开始的所有现有欧拉路径/回路。然后,我将对所有节点运行此算法并获得结果。这将有n^2或n^3的复杂性,这是非常大的

所以我的问题是,是否有一种算法可以从给定的节点找到有向图中的所有欧拉路径/回路?也许有人知道我问题的另一个解决办法

编辑:
在发表评论后,我认为使用Euler路径的解决方案可能会对我的问题造成过度伤害。问题如下:对于给定的n,我们创建一对整数,其和为(0,1)=>(1,1)=>(1,0)=>(0,2)=>(2,0)。我更喜欢使用图形的算法,因为例如(0,0)有时可能无效,但就这个问题而言,假设它是有效的。这个问题的强力解决方案当然是创建可用对的所有排列,然后看看它们是否有效,但这显然是O(n!)复杂的。我很确定这可以通过某种“聪明”的方式来实现。

在一般情况下,不同的欧拉路径的数量与顶点数n成指数关系。仅仅计算一个无向图中欧拉回路的数量就被证明是正确的(参见Graham R.Brightwell和Peter Winkler)。引用维基百科:

解#p-完全问题的多项式时间算法 存在,意味着P=NP,因此P=PH。不存在这样的算法 目前已知

因此,也许您需要另一种方法


但是,如果您的图具有某些属性,使得欧拉回路的指数数量不可能,请务必告诉我们这些属性。

在一般情况下,不同欧拉路径的数量与顶点数n成指数关系。仅仅计算一个无向图中欧拉回路的数量就被证明是正确的(参见Graham R.Brightwell和Peter Winkler)。引用维基百科:

解#p-完全问题的多项式时间算法 存在,意味着P=NP,因此P=PH。不存在这样的算法 目前已知

因此,也许您需要另一种方法


然而,如果你的图有某些属性使得指数数量的欧拉回路不可能,请告诉我们这些属性。

如果你想列举所有欧拉路径(像Gassa一样,我也有疑问),那么下面的简单输出敏感算法有多项式开销,因为n非常小,应该足够了。在Python中,有一个递归过程可以枚举
v
中的所有路径

def paths(v, neighbors, path):                # call initially with path=[]
    yield path[:]                             # return a copy of the mutable list
    for w in list(neighbors[v]):
        neighbors.remove(w)                   # remove the edge from the graph
        path.append((v, w))                   # add the edge to the path
        yield from paths(w, neighbors, path)  # recursively enumerate
                                              #   all path extensions from w
                                              #   in the residual graph
        path.pop()                            # remove the edge from the path
        neighbors.add(w)                      # add the edge to the graph

为了只返回欧拉路径,我们做了两个修改。首先,如果没有扩展当前路径的欧拉路径,我们将修剪递归。第二,我们只在
邻居[v]
为空时进行第一次屈服,即唯一的扩展是平凡的扩展,因此
路径
是欧拉的。由于满足度平衡条件,我们只需在每次递归调用时检查非孤立顶点的强连通性即可进行修剪,假设我们从起始顶点添加一条弧到
v
。这可以通过两次遍历来完成,一次验证每个非隔离顶点是否可以到达起始顶点,另一次验证每个非隔离顶点是否可以从
v
到达。(或者,您可以临时添加弧并进行一次遍历,但随后您必须处理多图,这可能是您不希望的。)

如果您希望枚举所有欧拉路径(并且,像Gassa一样,我有我的疑问),那么以下简单的输出敏感算法具有多项式开销,因为n将非常小,应该足够了。在Python中,有一个递归过程可以枚举
v
中的所有路径

def paths(v, neighbors, path):                # call initially with path=[]
    yield path[:]                             # return a copy of the mutable list
    for w in list(neighbors[v]):
        neighbors.remove(w)                   # remove the edge from the graph
        path.append((v, w))                   # add the edge to the path
        yield from paths(w, neighbors, path)  # recursively enumerate
                                              #   all path extensions from w
                                              #   in the residual graph
        path.pop()                            # remove the edge from the path
        neighbors.add(w)                      # add the edge to the graph

为了只返回欧拉路径,我们做了两个修改。首先,如果没有扩展当前路径的欧拉路径,我们将修剪递归。第二,我们只在
邻居[v]
为空时进行第一次屈服,即唯一的扩展是平凡的扩展,因此
路径
是欧拉的。由于满足度平衡条件,我们只需在每次递归调用时检查非孤立顶点的强连通性即可进行修剪,假设我们从起始顶点添加一条弧到
v
。这可以通过两次遍历来完成,一次验证每个非隔离顶点是否可以到达起始顶点,另一次验证每个非隔离顶点是否可以从
v
到达。(或者,您可以临时添加弧并执行一次遍历,但随后您必须处理多个图形,这可能是您不希望的。)

这仅适用于无向图形。对于有向图,公式是已知的。这被称为最佳定理。这只适用于无向图。对于有向图,公式是已知的。这被称为最佳定理。