Algorithms to Identify All the Cycle Bases in a UnDirected Graph

前端 未结 4 1867
梦谈多话
梦谈多话 2020-12-08 17:29

I have an undirected graph with Vertex V and Edge E. I am looking for an algorithm to identify all the cycle bases in that graph.

I think

4条回答
  •  半阙折子戏
    2020-12-08 18:14

    The following is my actual untested C# code to find all these "base cycles":

    public HashSet> FindBaseCycles(ICollection connectedComponent)
    {
       Dictionary>> cycles =
           new Dictionary>>();
    
       // For each vertex, initialize the dictionary with empty sets of lists of
       // edges
       foreach (VertexT vertex in connectedComponent)
           cycles.Add(vertex, new HashSet>());
    
       HashSet spanningTree = FindSpanningTree(connectedComponent);
    
       foreach (EdgeT edgeNotInMST in
               GetIncidentEdges(connectedComponent).Except(spanningTree)) {
           // Find one cycle to split, the HashSet resulted from the intersection
           // operation will contain just one cycle
           HashSet> cycleToSplitSet =
               cycles[(VertexT)edgeNotInMST.StartPoint]
                   .Intersect(cycles[(VertexT)edgeNotInMST.EndPoint]);
    
           if (cycleToSplitSet.Count == 0) {
               // Find the path between the current edge not in ST enpoints using
               // the spanning tree itself
               List path =
                   FindPath(
                       (VertexT)edgeNotInMST.StartPoint,
                       (VertexT)edgeNotInMST.EndPoint,
                       spanningTree);
    
               // The found path plus the current edge becomes a cycle
               path.Add(edgeNotInMST);
    
               foreach (VertexT vertexInCycle in VerticesInPathSet(path))
                   cycles[vertexInCycle].Add(path);
           } else {
                // Get the cycle to split from the set produced before
                List cycleToSplit = cycleToSplitSet.GetEnumerator().Current;
                List cycle1 = new List();
                List cycle2 = new List();
                SplitCycle(cycleToSplit, edgeNotInMST, cycle1, cycle2);
    
                // Remove the cycle that has been splitted from the vertices in the
                // same cicle and add the results from the split operation to them 
                foreach (VertexT vertex in VerticesInPathSet(cycleToSplit)) {
                    cycles[vertex].Remove(cycleToSplit);
                    if (VerticesInPathSet(cycle1).Contains(vertex))
                         cycles[vertex].Add(cycle1);
                         if (VerticesInPathSet(cycle2).Contains(vertex))
                             cycles[vertex].Add(cycle2); ;
                }
           }
       }
       HashSet> ret = new HashSet>();
       // Create the set of cycles, in each vertex should be remained only one
       // incident cycle
           foreach (HashSet> remainingCycle in cycles.Values)
               ret.AddAll(remainingCycle);
    
           return ret;
    }
    

    Oggy's code was very good and clear but i'm pretty sure it contains an error, or it's me that don't understand your pseudo python code :)

    cycles[v] = []
    

    can't be a vertex indexed dictionary of lists of edges. In my opinion, it have to be a vertex indexed dictionary of sets of lists of edges.

    And, to add a precisation:

    for vertex on cycle_to_split:
    

    cycle-to-split is probably an ordered list of edges so to iterate it through vertices you have to convert it in a set of vertices. Order here is negligible, so it's a very simple alghoritm.

    I repeat, this is untested and uncomplete code, but is a step forward. It still requires a proper graph structure (i use an incidency list) and many graph alghoritms you can find in text books like Cormen. I wasn't able to find FindPath() and SplitCycle() in text books, and are very hard to code them in linear time of number of edges+vertices in the graph. Will report them here when I will test them.

    Thanks a lot Oggy!

提交回复
热议问题