一尘不染

在无向图中找到所有无弦循环

algorithm

如何在无向图中找到所有无弦循环

例如,给定图

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]我不是要找到任意一组的基础金属周期。循环基础可以有和弦。)


阅读 283

收藏
2020-07-28

共1个答案

一尘不染

将数字分配给从1到n的节点。

  1. 选择节点编号1.将其称为“ A”。

  2. 枚举来自“ A”的成对链接。

  3. 选一个。让我们将B小于C的相邻节点称为’B’和’C’。

  4. 如果连接了B和C,则输出周期ABC,返回步骤3并选择另一对。

  5. 如果B和C未连接:

    • 枚举连接到B的所有节点。假设它连接到D,E和F。创建向量CABD,CABE,CABF的列表。对于这些:
    • 如果最后一个节点连接到除C和B之外的任何内部节点,则丢弃该向量
    • 如果最后一个节点连接到C,则输出并丢弃
    • 如果未连接到任何一个,则创建一个新的向量列表,并将最后一个节点连接到的所有节点追加。

重复直到向量用完。

  1. 对所有对重复步骤3-5。

  2. 删除节点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);
                }
            }
        }
    }
}
2020-07-28