我有一个有向图,我想找到所有现有的欧拉路径(在我的图中,我实际上知道那些将是电路)。
我做了一些研究,所以我可以使用例如Hierholzer算法,如下所示:http://stones333.blogspot.co.uk/2013/11/find-eulerian-path-in-directed-graph.html从给定节点中找到一条路径,但是这个算法只返回一条我认为的路径。
我想解决这个问题的方法是让算法从给定节点开始返回所有现有的欧拉路径/电路。然后我将为所有节点运行此算法并获得结果。这将具有n ^ 2或n ^ 3的复杂性,这很好。
所以我的问题是,是否有一个算法可以在给定节点的有向图中找到所有欧拉路径/电路?或者也许有人知道我问题的另一种解决方案。
编辑: 在Gassa发表评论之后,我认为使用欧拉路径的解决方案可能对我的问题有些过分。问题如下:对于给定的n,我们创建一对整数,其和为< = n。对于那些对,找到连接所有对的所有路径,使得前一对的第二个值等于下一对的第一个值(如多米诺)。
示例:n = 2,然后可用对= {(0,0),(0,1),(1,0),(1,1),(2,0),(0,2)} 。有效链之一=(0,0)=>(0,1)=>(1,1)=> (1,0)=>(0,2)=>(2,0)。我更喜欢使用图表的算法,因为例如(0,0)有时候可能无效,但是让我们说它对于这个问题是有效的。对这个问题的强力解决方案当然是创建可用对的所有排列,然后看它们是否有效,但这显然是O(n!)复杂。我很确定这可以在一些" smart"方式。
答案 0 :(得分:3)
在一般情况下,不同的欧拉路径的数量在顶点数n中是指数的。仅计算无向图中欧拉电路的数量为#P-complete(参见格雷厄姆·布莱德威尔和彼得温克勒的Note on Counting Eulerian Circuits)。引用维基百科:
用于求解#P-complete问题的多项式时间算法(如果是) 存在,意味着P = NP,因此P = PH。没有这样的算法 目前已知。
所以也许你需要另一种方法。
但是,如果您的图表具有某些属性,这些属性无法使指数的欧拉电路成为可能,请告诉我们这些属性。
答案 1 :(得分:1)
如果你想枚举所有的欧拉路径(和Gassa一样,我有疑问),那么下面简单的输出敏感算法就有多项式开销,因为n非常小,应该足够了。这是一个递归过程,用于枚举来自v
的所有路径,如Python中所示。
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
仅返回欧拉路径,我们进行两次修改。首先,如果没有Eulerian路径扩展当前路径,我们将修剪递归。其次,我们只在neighbors[v]
为空时才进行第一次收益,即唯一的扩展是微不足道的,所以path
是欧拉。由于满足度平衡条件,我们只需在每次递归调用时检查非隔离顶点的强连通性,只要我们从起始顶点添加一个弧到v
。这可以通过两次遍历来完成,一次是验证每个非孤立顶点可以到达起始顶点,另一次是验证每个非孤立顶点是否可以从v
到达。 (或者,您可以暂时添加弧并进行一次遍历,但是您必须处理多图,这可能是您不想要的。)