如何使用 networkx + python 枚举图中所有*最大*派系?

Shi*_*ond 3 python algorithm graph-theory networkx python-3.x

如果您查看https://en.wikipedia.org/wiki/Clique_problem,您会注意到派系和最大派系之间存在区别。最大集团只包含在其自身之外,不包含其他集团。所以我想要那些派系,但networkx似乎只提供:

networkx.algorithms.clique.enumerate_all_cliques(G)

所以我尝试了一个简单的for循环过滤机制(见下文)。

def filter_cliques(self, cliques):
    # TODO: why do we need this?  Post in forum...
    res = []
    for C in cliques:
        C = set(C)
        for D in res:
            if C.issuperset(D) and len(C) != len(D):
                res.remove(D)
                res.append(C)
                break
            elif D.issuperset(C):
                break
        else:
            res.append(C)
    res1 = []
    for C in res:
        for D in res1:
            if C.issuperset(D) and len(C) != len(D):
                res1.remove(D)
                res1.append(C)
            elif D.issuperset(C):
                break
        else:
            res1.append(C)     
    return res1
Run Code Online (Sandbox Code Playgroud)

我想过滤掉所有合适的小派系。但正如你所看到的,它很糟糕,因为我必须过滤两次。这不是很优雅。所以,问题是,给定一个对象列表(整数、字符串),它们是图中的节点标签;enumerate_all_cliques(G)准确返回此标签列表列表。现在,给定这个列表列表,过滤掉所有适当的子团。例如:

[[a, b, c], [a, b], [b, c, d]] => [[a, b, c], [b, c, d]]

最快的Python方式是什么?

use*_*ica 6

有一个函数:networkx.algorithms.clique.find_cliques,是的,它确实只返回最大派系,尽管名称中没有“最大”。它的运行速度应该比任何过滤方法都要快得多。

如果您发现该名称令人困惑(我确实如此),您可以重命名它:

from networkx.algorithms.clique import find_cliques as maximal_cliques
Run Code Online (Sandbox Code Playgroud)