在python中使用dfs的euler电路

时间:2014-05-12 02:10:23

标签: python graph depth-first-search

我正在尝试编写一个程序来检查给定矩阵是否有欧拉电路,我正在使用DFS进行检查,但我的递归调用存在一些问题。

DFS访问的第一个调用是DFS访问(G< - 如下所示,0,1,temp_path = 0)

def DFSvisited(G,i,j,temp_path):
    G[i][j]=0
    G[j][i]=0
    temp_path.append(j)
    for k in range(0,n):
        if G[j][k]==1:
            print 'j+++',j,"#### k",k
            DFSvisited(G,j,k,temp_path)

我传递了一个如下所示的矩阵:

   0   1   0   0   0   1   0
   1   0   1   0   0   1   1
   0   1   0   1   1   0   1
   0   0   1   0   1   0   0
   0   0   1   1   0   1   1
   1   1   0   0   1   0   1
   0   1   1   0   1   1   0

但它在第一次迭代中返回[0, 1, 2, 3, 4, 5, 6, 6, 4, 6, 5, 6]而不是[0,1,2,3,4,2,6,1,5,0]的temp_path。

我认为我在方法DFSvisied中的DFS访问的递归调用中遗漏了一些东西,任何想法?

谢谢!

1 个答案:

答案 0 :(得分:0)

你的方法的问题是DFS遍历的顺序不一定等同于欧拉路径。虽然您的 DFS 遍历最终会遍历所有边,但它可能需要回溯而不是采用一条连续路径。因此,不是总是附加到临时路径的末尾,而是必须根据 DFS 回溯的距离插入临时路径。

考虑以下示例图:

enter image description here

如果 DFS 遍历从 a -> b -> c -> a 开始,那么它将卡在 a 处。因此,DFS 遍历必须回溯到具有未遍历边的最后一个顶点。这将是顶点 b。 DFS 遍历然后可以继续 b -> d -> e -> b。此后,找不到未遍历的边,因此搜索结束。为了构建欧拉路径,我们不能简单地按照访问顺序(即 abcabdeb)连接顶点。相反,我们从构建临时路径 abca 开始。然后,当我们在停留在 b 处后回溯到 a 时,我们必须在临时路径中插入从 b 访问的顶点。但不是在最后插入,我们必须在 b 之后插入它们,结果是 abdebca,这是一个有效的欧拉回路。

要修复您的程序,您可以向 offset 方法添加参数 DFSvisited。对于 0 的初始调用,偏移量将设置为 DFSvisited。对于每个递归调用,偏移量设置为 offset+1。然后可以通过在给定的 offset:

处插入临时路径来替换对临时路径的附加
def DFSvisited(G,i,j,offset,temp_path):
    G[i][j]=0
    G[j][i]=0
    n = len(G)
    temp_path.insert(offset, j)
    for k in range(0,n):
        if G[j][k]==1:
            DFSvisited(G,j,k,offset+1,temp_path)