【问题标题】:Finding all cycles in a directed graph using recursive backtracking使用递归回溯查找有向图中的所有循环
【发布时间】:2013-12-13 21:51:18
【问题描述】:

我正在使用递归回溯在有向图中寻找循环。这个here 有一个建议的伪代码,在这里:

dfs(adj,node,visited):  
  if (visited[node]):  
    if (node == start):  
      "found a path"  
    return;  
  visited[node]=YES;  
  for child in adj[node]:  
    dfs(adj,child,visited)
  visited[node]=NO;

以起始节点调用上述函数:

visited = {}
dfs(adj,start,visited)

虽然与Tarjans algorithm 相比,这不是最有效的算法,但这对我来说很简单,我可以理解。目前,此代码未检测到循环次数。

我用 Java 实现了这个:

//this is the main method that calls the helper DFS which runs on each node
public int allCyclesDirectedmain(){
    //this initializes all vertices
    clearAll();
    int[] count = new int[1];
    for (Vertex v: vertexMap.values()){
        //System.out.println(v.name);
        //clearAll();
        dfs(v,v,count);
    }
    return count[0];
}

//start and v are same when the method first fires.
public void dfs(Vertex start, Vertex v,int[] count){
   if (v.isVisited){
       if (start==v){
           //found a path
           count[0]++;
       }
       return ;
   }
   v.setVisited(true);
   for (Edge e : v.adj){
       Vertex next = e.target;
       dfs(start,next,count);
   }
   v.setVisited(false);
}

对于具有以下边的图:
(1 2),(2 3),(3 1),(2 5),(5 6),(6 2)-- 我得到 6 个周期作为输出。

(1 2),(2 3),(3 4),(4,1),(2 5),(5 6),(6 2) -- 我得到 7 个周期作为输出。

我可以看到我当前的代码对已经是先前检测到的循环的一部分的每个顶点进行循环检测(例如:具有三个节点的循环为每个单独的节点提供三个循环,而这必须是一个)。我需要一些提示来了解问题所在并进行修复。

【问题讨论】:

  • 你能在这里上传你所有的代码吗?我想在python中尝试一下,如果你上传它会很有帮助
  • 你能上传整个代码吗,我想在我这边实现它。请

标签: java algorithm recursion directed-graph cyclic-graph


【解决方案1】:

对于(1 2),(2 3),(3 1),您正在致电:

  • dfs(vertex1, vertex1, count),它为您提供循环 1 -> 2 -> 3 -> 1
  • dfs(vertex2, vertex2, count),给你循环2 -> 3 -> 1 -> 2
  • dfs(vertex3, vertex3, count),它为您提供循环 3 -> 1 -> 2 -> 3

所以你多次计算同一个周期。

我能想到的最简单的解决方法就是在 dfs 调用之后设置访问标志。

public int allCyclesDirectedmain(){
    clearAll();
    int[] count = new int[1];
    for (Vertex v: vertexMap.values()){
        dfs(v,v,count);
        v.setVisited(true); // <---
    }
    return count[0];
}

【讨论】:

  • 这里的运行时分析是什么?我想一定是(V+E)^2,对吗?
  • 我不是 100% 确定,但我认为它是 O(V^b),其中 b 是平均分支因子(传出边数),或者可能更接近 O(P(V,b)) (@987654335 @表示permutations)。
  • @Dukeling ,你能上传整个代码吗,我想在我这边实现它。请。
  • @ExceptionHandler 我不认为我在这里发布的代码比我在这里发布的更多。
猜你喜欢
  • 2010-10-07
  • 2014-01-02
  • 2015-12-25
  • 1970-01-01
  • 2012-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-29
相关资源
最近更新 更多