How to find all chordless cycles in an undirected graph?
For example, given the graph
0 --- 1 | | \ | | \ 4 --- 3 - 2
the algorithm should return 1-2-3 and 0-1-3-4, but never 0-1-2-3-4.
(Note: [1] This question is not the same as small cycle finding in a planar graph because the graph is not necessarily planar. [2] I have read the paper Generating all cycles, chordless cycles, and Hamiltonian cycles with the principle of exclusion but I don't understand what they're doing :). [3] I have tried CYPATH but the program only gives the count, algorithm EnumChordlessPath in readme.txt has significant typos, and the C code is a mess. [4] I am not trying to find an arbitrary set of fundametal cycles. Cycle basis can have chords.)
Insert the edges into an adjacency list. Call the DFS function which uses the coloring method to mark the vertex. Whenever there is a partially visited vertex, backtrack till the current vertex is reached and mark all of them with cycle numbers. Once all the vertexes are marked, increase the cycle number.
Here for finding the number of cycles in the undirected graph, the time complexity is the same as DFS traversal, i.e., O(V+E), where V is the number of vertices and E is the number of edges in the graph. Space complexity is O(V) as extra color[ ] and par[ ] is used here.
The DFS-based variants with back edges will find cycles indeed, but in many cases it will NOT be minimal cycles.
Abstract. A chordless cycle (induced cycle) C of a graph is a cycle without any chord, meaning that there is no edge outside the cycle connecting two vertices of the cycle. A chordless path is defined similarly.
Assign numbers to nodes from 1 to n.
Pick the node number 1. Call it 'A'.
Enumerate pairs of links coming out of 'A'.
Pick one. Let's call the adjacent nodes 'B' and 'C' with B less than C.
If B and C are connected, then output the cycle ABC, return to step 3 and pick a different pair.
If B and C are not connected:
Repeat until you run out of vectors.
Repeat steps 3-5 with all pairs.
Remove node 1 and all links that lead to it. Pick the next node and go back to step 2.
Edit: and you can do away with one nested loop.
This seems to work at the first sight, there may be bugs, but you should get the idea:
void chordless_cycles(int* adjacency, int dim) { for(int i=0; i<dim-2; i++) { for(int j=i+1; j<dim-1; j++) { if(!adjacency[i+j*dim]) continue; list<vector<int> > candidates; for(int k=j+1; k<dim; k++) { if(!adjacency[i+k*dim]) continue; if(adjacency[j+k*dim]) { cout << i+1 << " " << j+1 << " " << k+1 << endl; continue; } vector<int> v; v.resize(3); v[0]=j; v[1]=i; v[2]=k; candidates.push_back(v); } while(!candidates.empty()) { vector<int> v = candidates.front(); candidates.pop_front(); int k = v.back(); for(int m=i+1; m<dim; m++) { if(find(v.begin(), v.end(), m) != v.end()) continue; if(!adjacency[m+k*dim]) continue; bool chord = false; int n; for(n=1; n<v.size()-1; n++) if(adjacency[m+v[n]*dim]) chord = true; if(chord) continue; if(adjacency[m+j*dim]) { for(n=0; n<v.size(); n++) cout<<v[n]+1<<" "; cout<<m+1<<endl; continue; } vector<int> w = v; w.push_back(m); candidates.push_back(w); } } } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With