Java 用递归回溯法求有向图中的所有圈

Java 用递归回溯法求有向图中的所有圈,java,algorithm,recursion,directed-graph,cyclic,Java,Algorithm,Recursion,Directed Graph,Cyclic,我正在使用递归回溯法在有向图中寻找圈。这里有一个建议的伪代码: 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; 使用开始节点调

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

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算法
相比,这不是最有效的算法,但这足够简单,我可以理解。目前,此代码未检测到循环数

我用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);
}
对于具有以下边的图形:
(12)、(23)、(31)、(25)、(56)、(62)
——我得到6个循环作为输出

(12)、(23)、(34)、(4,1)、(25)、(56)、(62)
——我得到7个循环作为输出

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

对于
(12)、(23)、(31)
,您的电话是:

  • 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];
}
public int-allCyclesDirectedmain(){
clearAll();
int[]计数=新的int[1];
对于(顶点v:vertexMap.values()){
dfs(v,v,count);

v、 setvisted(true);//这里的运行时分析是什么?我想它一定是
(v+E)^2
,对吗?我不是100%确定,但我认为它是
O(v^b)
,其中
b
是平均分支因子(输出边的数量),或者可能更接近
O(P(v,b))
P
)@Dukeling,你能上传整个代码吗?我想在我这边实现它。请@ExceptionHandler我想我从来没有比我在这里发布的代码更多的代码。你能上传你所有的代码吗?我想用python试试,如果你上传会有帮助。你能上传整个代码吗?我想在我这边实现它。请