使用递归回溯查找所有循环有向图递归

2023-09-11 22:44:20 作者:-如欢如殇

我正在使用递归回溯寻找周期向图。有一个建议伪code这个这里,这是在这里:

I am working on finding cycles in directed graph using recursive backtracking. There is a suggested pseudocode for this here, which is 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;

调用上述功能的起始节点:

Call the above function with the start node:

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

虽然这不是最有效的算法相比, Tarjans算法,这就够了我简单的让我明白了。目前,该code没有检测到循环次数的计数。

While this is not the most efficient algorithm when compared to Tarjans algorithm, this is simple enough me for me to understand. Currently, this code does not have a count of number cycles detected.

我用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个周期的输出

For the graph with following edges: (1 2),(2 3),(3 1),(2 5),(5 6),(6 2)-- I get 6 cycles as output.

(1 2),(2 3),(3〜4),(4,1),(2 5),(5,6),(6 2) - 我得到7个循环输出

(1 2),(2 3),(3 4),(4,1),(2 5),(5 6),(6 2) -- I get 7 cycles as output.

我可以看到我目前的code做循环检测每个顶点已经pviously检测周期一个$ P $的一部分(例如:具有三个节点一个周期给我三个周期,而这必须每个节点为一个)。我在这里需要一些技巧,以什么错误以及一些修复。

I can see that my current code does cycle detection for each vertex that are already part of a previously detected cycle (e.g.: a cycle with three nodes gives me three cycles for each individual nodes while this must be one). I need some tips here as to what is going wrong and some fix.

推荐答案

有关(1 2),(2 3),(3 1),你打电话

DFS(vertex1,vertex1,计数),它给你的周期 1 - > 2 - > 3 - > 1 DFS(vertex2,vertex2,计数),它给你的周期 2 - > 3 - > 1 - > 2 DFS(vertex3,vertex3,计数),它给你的周期 3 - > 1 - > 2 - > 3 dfs(vertex1, vertex1, count), which gives you the cycle 1 -> 2 -> 3 -> 1. dfs(vertex2, vertex2, count), which gives you the cycle 2 -> 3 -> 1 -> 2. dfs(vertex3, vertex3, count), which gives you the cycle 3 -> 1 -> 2 -> 3.

所以,你数着相同的周期多次。

So you're counting the same cycle multiple times.

最简单的修复我能想到的是简单地设置了访问标志 DFS 通话后。

The simplest fix I can think of is simply setting the visited flag after the dfs call.

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