我在基于最大团的图池化里提到了一点点Bron-Kerbosch算法,不过对这个算法还是没有太了解,今天单独拿出一篇文章来说这个算法。首先,https://www.jianshu.com/p/437bd6936dad 有着很详细的介绍,毕竟原论文太偏向于理论了不好读透。我会在其基础上添加一些我的理解,并解读networkx的源码。
Bron-Kerbosch算法
极大团的检索算法的时间复杂度都比较高,最近查资料发现也有许多研究旨在降低其时间复杂度,或者在稀疏的巨型图上应用,但是这些都需要对BK算法做一个深入理解。
这个算法主要是构造了三个集合,我们假设:
R集合记录的是当前极大团中已经加入的点。
P集合记录的是可能还能加入的点(也就是与R集合中所有点都有边存在的点,这样加入后,才会构成团)
X集合记录的是已经加入过某个极大团的点(作用是判重,因为会从每个结点开始,枚举所有的团,如果不对已经加入某个极大团的点,进行标记,可能会有重复的极大团出现)
伪代码如下:
1.Bron-Kerbosch Algorithm(Version 1)
2.R={
} //已确定的极大团顶点的集合
3.P={
V} //未处理顶点集,初始状态是所有结点
4.X={
} //已搜过的并且属于某个极大团的顶点集合
5.
6.BronKerbosch(R, P, X):
7. if P and X are both empty:
8. report R as a maximal clique
9. for each vertex v in P:
10 BronKerbosch1(R ⋃ {
v}, P ⋂ N(v), X ⋂ N(v))
11 P := P \ {
v}
12 X := X ⋃ {
v}
我们逐行去看。
Line3. 初始化P={V},V代表图中的所有顶点。
Line7,8. 如果P、X都为空,则说明R是最大团。因为算法的思路就是递归遍历整个点集,所以P为空的是必要条件。那么X呢?X表示已经搜索过并且属于某个最大团的点集,因为算法要找的是最大团,比如{1,2,3}这个团的子集{1,2}也是团,但是并不是最大,此时X起到记录{3}的作用,表示之前已经搜索过最大团{1,2,3},因此X此时非空表示R不是最大团。这部分可以看后文的示例,能够更清楚理解。

Line9. 对每一个顶点都进行遍历。这样势必造成计算资源的浪费。还是举例子,从{1}出发找到了最大团{1,2,3},那么从{2}还是能找到此最大团,重了。因此后续才有对其的改进。
Line10. 将{v}(注意是小v)与R合并,取P与N(v)的交集,X与N(v)的交集。N(v)表示当前节点的邻居结点。因为,最大团必须满足节点之间两两存在边,v又是最大团中的节点了,因此新加入的点的必要条件就是必须与v有边,因此必须是v的邻居。然后,在找到了v的基础上回溯。
Line11. 在对v操作完之后自然要从未处理的点集中删除。
Line12. 加入X集合代表当前状态下对包含点v的极大团已经计算完毕了。注意Line11,12都是回溯过程结束之后的操作。
下面看个例子。

本文详细解析了Bron-Kerbosch算法,一种用于寻找图中所有极大团的经典算法。通过构造R、P、X三个集合,算法递归地找出所有可能的极大团。文章不仅介绍了算法的基本原理,还探讨了其在网络x中的实现,以及如何通过改进减少不必要的计算。
最低0.47元/天 解锁文章
1928

被折叠的 条评论
为什么被折叠?



