如何在具有多边的有向图中找到 all cyles ?
图示例1:
周期:
1-2-6
1-2-3-4
1-2-3-4-5-6
1-2-6-5-3-4
3-4-5
5-6
图示例2(多边4/5):
周期:
1-2-3
1-4
1-5
Notes:
我不想检测一个循环(布尔结果),我想列出所有循环 .
任何Strongly connected component算法都不足以解决我的问题(在两个示例中都只找到一个组件) .
我正在使用C#中的QuickGraph实现,但我很乐意看到任何语言的算法 .
3 回答
我很开心这个问题,谢谢! :P
我有一个C#的解决方案 . 查找周期的算法非常短(~10行),但周围有很多杂乱(例如Node和Edge类的实现) .
我使用了字母"e"代表边的变量命名约定,字母"a"边缘开始的节点,以及它链接到的节点"b" . 有了这些约定,这就是 algorithm :
它有一个优化来重用一些Hashsets,这可能会令人困惑 . 我已经包含了以下代码,它产生完全相同的结果,但是这个实现 doesn't have optimizations ,所以你可以更容易地弄清楚它是如何工作的 .
这使用 Node, Edge and Cycle 的以下实现 . 它们非常直截了当,尽管我确实考虑过使一切变得一成不变,而且成员尽可能不易访问 .
然后为了说明如何使用这个小API,我实现了你的两个 examples . 基本上它归结为,通过指定它们链接的节点来创建所有节点,然后调用SetReferences()来设置一些引用 . 之后,调用可公开访问的FindAllCycles()应该返回所有循环 . 我已经排除了重置静态成员的任何代码,但这很容易实现 . 它应该只清除所有静态列表 .
我必须注意,这些示例中的边的索引与图像中的索引不对应,但是通过简单的查找可以避免这种情况 . The results :allCycles是第一个例子:
allCycles是第二个例子:
我希望您对此解决方案感到满意并使用它 . 我几乎没有对代码发表评论,所以我知道它可能很难理解 . 在这种情况下,请询问,我会对此发表评论!
如何使用Breadth-first search查找节点A和B之间的所有路径 - 让我们调用该函数
get_all_paths
要找到您需要的所有周期:
get_all_paths(x,x)
因为循环只是在同一节点中开始和结束的路径 .只是一个替代解决方案 - 我希望它提供新的想法 .
Edit
另一种选择是计算所有可能的路径,并在每次第一条边开始最后一条边完成时检查 - 一个周期 .
在这里,您可以看到它的Python代码 .
JBSnorro给出了一个很棒的答案,但它看起来有点太硬了 . 从他的解决方案开始,我提出了一个更容易理解的例子,它不需要Node,Edge和Cycle的定义,也适用于邻接矩阵 . 但是,我的解决方案是,如果从不同的节点启动,则重复一些周期 .