【发布时间】:2017-02-27 04:40:44
【问题描述】:
我有一个程序需要在有向图中检测循环(以及作为该循环成员的节点)。为此,我使用 LLVM 的强连接组件算法。它非常易于使用,并且几乎可以完成应有的工作:
vector<vector<PreAstBasicBlock*>> stronglyConnectedComponents;
for (auto iter = scc_begin(&function); iter != scc_end(&function); ++iter)
{
if (iter.hasLoop())
{
stronglyConnectedComponents.push_back(*iter);
}
}
这可以正确识别简单的 SCC,比如这个简单的:
这很好,但我很想知道我什么时候在每个更大的强连接组件中都有强连接组件。例如,这被识别为单个 SCC:
这绝对正确,因为该图中的每个节点都可以从任何其他节点开始访问。但是,B⇄C 具有独立于 D→A 后沿的附加属性。它本身就是一个 SCC,它有一个入口节点和一个出口节点:我可以用一个单一节点替换它,而且我不会有边缘插入或伸出它的概念中间。
如何在强连接组件中找到这些较小的强连接组件?
【问题讨论】:
-
@user2899162,我不确定你的意思。两个图中都没有 C→A 边,所以在我看来,如果将其识别为循环就会出现问题。为了澄清,在每个屏幕截图中,绿色框是被识别的强连接组件,它作为一组节点返回。
-
@user2899162,很像 LLVM CFG,我的图表总是有一个“自然条目”(在这些示例中为 A),并且不能循环返回该自然条目(更一般地说,会有始终是从外部戳到自然入口的边缘)。你可以有 A→B→C→D→B,但它会(应该?)找到 B→C→D→B。