如何在无向图中找到所有无弦循环?
例如,给定图
0 --- 1 | | \ | | \ 4 --- 3 - 2
该算法应返回1-2-3和0-1-3-4,但不能返回0-1-2-3-4。
(请注意: [1] 这个问题与_平面图中的小循环发现_不一样,因为该图不一定是平面的。 [2] 我已阅读了以下论文,即根据以下原理生成所有循环,无弦循环和哈密顿循环:排斥,但我不明白他们在做什么:)。 [3] 我尝试了CYPATH,但是程序仅给出计数,readme.txt中的EnumChordlessPath算法有很大的错别字,并且C代码很乱。 [4]我不是要找到任意一组的基础金属周期。循环基础可以有和弦。)
将数字分配给从1到n的节点。
选择节点编号1.将其称为“ A”。
枚举来自“ A”的成对链接。
选一个。让我们将B小于C的相邻节点称为’B’和’C’。
如果连接了B和C,则输出周期ABC,返回步骤3并选择另一对。
如果B和C未连接:
重复直到向量用完。
对所有对重复步骤3-5。
删除节点1及其所有链接。选择下一个节点,然后返回到步骤2。
编辑:您可以消除一个嵌套循环。
乍一看,这似乎可行,可能存在错误,但是您应该了解一下:
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); } } } } }