【问题标题】:finding a single maximal clique using Bron–Kerbosch使用 Bron–Kerbosch 找到单个最大集团
【发布时间】:2021-08-01 10:35:04
【问题描述】:

我使用networkx库实现了算法 Bron-Kerbosch 库来查找图 G 中的所有最大团。为了加快我的分析,在非常大的图中,我想修改此算法以仅从图 G 中提取一个最大团。修改此算法是最佳解决方案,还是有更高效的算法?

from typing import Iterator, List
import networkx as nx

    def bron_kerbosch_1(r: list, p: list, x: list, graph: nx.classes.graph.Graph) -> Iterator[List]:
   """Basic form (i.e., without pivoting) of the Bron–Kerbosch algorithm.
                """
    if not any((p, x)):
                    yield r
                for node in p[:]:
                    r_new = r + [node]  # R ⋃ {v}
                    p_new = list(set(p).intersection(set(graph.neighbors(node))))  # P ⋂ N(v)
                    x_new = list(set(x).intersection(set(graph.neighbors(node))))  # X ⋂ N(v)
                    yield from BronKerbosch.bron_kerbosch_1(r_new, p_new, x_new, graph)
                    p.remove(node)
                    x.append(node)

G = nx.Graph()
edges = [(0, 1), (0, 4), (1, 4), (1, 2), (2, 3), (3, 4), (3, 5)]
G.add_edges_from(edges)
nodes = list(G.nodes)
maximal_cliques = list(bron_kerbosch_1(r=[], p=nodes[:], x=[], graph=G))
print(maximal_cliques)
>> [[0, 4, 1], [2, 1], [2, 3], [4, 3], [5, 3]]

【问题讨论】:

    标签: python graph


    【解决方案1】:

    如果你关心性能,那么你不应该使用 python。作为一种解释型语言,它的运行速度比编译型语言慢大约 50 倍。

    这是在图中查找最大团的 C++ 代码。它可以在一两秒内处理具有十万个顶点的图形。完整的应用代码见https://github.com/JamesBremner/PathFinder2

        void cPathFinder::cliques()
        {
            // working copy on input graph
            auto work = *this;
    
            // store for maximal clique collection
            std::vector<std::vector<int>> vclique;
    
            while (1)
            {
                std::vector<int> clique;
    
                while (work.nodeCount())
                {
                    //std::cout << "work.nodeCount " << work.nodeCount() << " " << clique.size() << "\n";
                    if (!clique.size())
                    {
                        // start by moving an arbitrary node to the clique from the work graph
                        auto nit = work.nodes().begin();
                        clique.push_back(nit->first);
                        work.removeNode(nit->first);
                        continue;
                    }
                    bool found = false;
    
                    // loop over nodes remaining in work graph
                    for (auto &u : work.nodes())
                    {
                        // loop over nodes in clique
                        for (int v : clique)
                        {
                            if (work.includes_link(v, u.first) ||
                                work.includes_link(u.first, v))
                            {
                                // found node in work that is connected to clique nodes.
                                // move it to clique
                                //std::cout << "add " << myGraph.name(u.first) << "\n";
                                clique.push_back(u.first);
                                work.removeNode(u.first);
                                found = true;
                                break;
                            }
                        }
                        if (found)
                            break; // found a node to add to clique
                    }
                    if (!found)
                        break; // no more nodes can be added, the clique is maximal
                }
    
                if (!clique.size())
                    break; // did not find a clique
    
                // add to collection of maximal cliques
                vclique.push_back(clique);
            }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-02
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 2022-01-24
      • 2012-02-26
      相关资源
      最近更新 更多