【问题标题】:Determine if an adjacency matrix has a cycle and then output that cycle判断邻接矩阵是否有循环,然后输出该循环
【发布时间】:2017-12-09 07:05:45
【问题描述】:

所以我有两个功能:

更新

unordered_map<int, bool> visited2;
vector<vector<int>> elements2D;


bool DFSDetectCycle(int vertex){
    s.push(vertex);
    while(!s.empty()){
        int np_vertex = s.top();
        s.pop();
        if (visited2[np_vertex] == true){
            return true;
        }
        visited2[np_vertex] = true;
        for (int i = 0; i<elements2D.size(); i++){
            if(elements2D[np_vertex][i] != 0){
                if(DFSDetectCycle(i)){
                    return true;
                }
            }
        }
    }
    return false;   
}

bool hasCycle(vector<vector<int>> v){
    if (v.empty()){
        return false;   
    }
    for (int i = 0; i<v.size(); i++){
           if (!visited2[i]){
                      if(DFSDetectCycle(i)){
                          return true;
                      } 
           }
    }
    return false;
}

在我的主要功能中,我这样称呼它:

if (hasCycle(elements2D)){
        for (int i = 0; i<elements2D.size(); i++){
            if (!visited2[i]){
                DFSDetectCycle(i);
            }       
        }
}else{
        cout << "No cycles." << endl;
}

所以基本上,输入看起来像这样:

g++ -o GraphProcessor.o GraphProcessor.cpp -std=c++11
./GraphProcessor.o graph1.txt

输出应该是这样的:

Connected components:
{0,1,2,4,7}
{3}
{5,6}
A cycle: 0 1 4 2

但我的输出是这样的:

Connected components:
{0,1,4,2,7}
{3}
{5,6}
No cycles.

graph1.txt 看起来像这样:

0 2 6 0 0 0 0 3
2 0 0 0 4 0 0 1
6 0 0 0 3 0 0 2
0 0 0 0 0 0 0 0
0 4 3 0 0 0 0 0
0 0 0 0 0 0 7 0
0 0 0 0 0 7 0 0
3 1 2 0 0 0 0 0

不要担心连接的组件部分,这不是我现在的问题。我的问题是我的代码没有正确检测图中的循环,也没有正确输出它们。似乎我的 hasCycle() 函数总是给出错误的陈述,但我不确定为什么。 elements2D 是我正在使用的矩阵,因为它是从文件中读取的,所以我需要某个地方来存储它。对于我的visited2 函数,我使用unordered_map 来保留关于我是否访问过顶点的布尔值。我知道如果我再次访问了一个顶点,那么我就有了一个循环。但我不确定如何修改我的算法以获得这样的结果。

再次感谢您的帮助。

【问题讨论】:

  • 找到连通分量后是否重置visited2数组?
  • 很抱歉,我应该澄清一下。对于连接的组件部分,我使用了一个名为visited 的unordered_map。我为循环初始化了这个名为visited2 的新unordered_map。

标签: c++ graph cycle adjacency-matrix


【解决方案1】:
  1. 您正在递归调用DFSDetectCycle 而不使用它的返回值。我建议你检查递归调用是否返回true,并返回它。

  2. 您专门跳过了循环,因为您使用 if(elements2D[np_vertex][i] != 0 &amp;&amp; !visited2[i]) 过滤递归调用 - 这意味着您不会进入已经访问的顶点,跳过循环。

此外,代码中没有任何打印可以产生所需的输出...

【讨论】:

  • 我已经按照你说的做了,我相信它现在正在工作。我已经更新了上面的代码。但我不确定在哪里放置打印语句以输出循环。你认为你能给我一些关于从这里去哪里的指示吗?
  • 尝试在刚刚添加的“return true”之前添加打印。它会给你循环打印,但向后
【解决方案2】:

您应该从if(elements2D[np_vertex][i] != 0 &amp;&amp; !visited2[i]) 中删除visited[i] 检查,因为如果您已经访问过i,则删除此检查可以检测到它。如果它发现循环,你应该立即返回它。

if(elements2D[np_vertex][i] != 0){
    if (DFSDetectCycle(i)) return true;
}

另一个问题是如果存在边0-&gt;11-&gt;0,那么它们会形成一个循环。你需要做更多的工作才能找到最大的循环。

【讨论】:

  • 不幸的是,我得到了相同的输出。它说没有周期。
  • 有什么方法可以上传一个可运行的程序以便有人帮助你吗?
  • 对不起,我不知道在哪里可以看到答案。你能提供一个链接吗?顺便感谢您的帮助。
  • 我已经编辑了我们正在评论的答案。
  • 好的,我已经改了。但是现在,我不确定将打印语句放在哪里以输出循环。我应该把它们放在哪里?
猜你喜欢
  • 1970-01-01
  • 2013-05-02
  • 1970-01-01
  • 2014-07-25
  • 1970-01-01
  • 1970-01-01
  • 2017-03-24
  • 2021-08-02
  • 1970-01-01
相关资源
最近更新 更多