最大团 极大团 Bron–Kerbosch算法 poj 2989

poj2989:All Friends(Bron–Kerbosch算法) 传送门 题意: 最大团计数。 题解: 这种题只能深搜了。。但是深搜要讲方法,有一种极大团计数高效算法,可以跑n=100" role="presentation">n=100n=100n=100的稠密图,甚至能跑上万的稀疏图,这就是Bron–Kerbosch算法。 算法流程(from wiki): BronKerbosch1(R, P, X): " role=" 阅读详情

昨日老刘开了最大团专题后,起初以为挺简单,后来发现有点麻烦。能用的资料又很少。分享一下学习的东西


以poj 2989为例,题意是求 不同极大团的数量

要用Bron–Kerbosch算法


首先是最朴素的伪代码,没有任何剪枝(来自维基百科)https://en.wikipedia.org/wiki/Bron%E2%80%93Kerbosch_algorithm

   BronKerbosch(All, Some, None):
       if Some and None are both empty:
           report All as a maximal clique
       for each vertex v in Some:
           BronKerbosch1(All ⋃ {v}, Some ⋂ N(v), None ⋂ N(v))
           Some := Some \ {v}
           None := None ⋃ {v}


N(v)为顶点v相邻的点。

all为已取的顶点集,some为未处理顶点集(初始状态是全部顶点),none为不取的顶点集


最大团类型的题目中,我们求最大团顶点数时只要some,要求记录路径时要all和some,这里求极大团数量,需要all、some、none。

c代码:

void dfs(int d, int an, int sn, int nn)
//d为搜索深度,an、sn、nn分别为all、some、none集合中顶点数,
{
    if(sn == 0 && nn == 0) ++ S;//sn==0搜索到终点,只有nn==0时,才是一个极大团,S为极大团数量
    for(int i = 0; i < sn; i ++)
    {
        int v = some[d][i];
        int tsn = 0, tnn = 0;
        for(int j = 0; j < an; j ++) all[d + 1][j] = all[d][j];
        all[d + 1][an] = v;
        for(int j = 0; j < sn; j ++)if(g[v][some[d][j]]) some[d + 1][tsn ++] = some[d][j];
        for(int j = 0; j < nn; j ++) if(g[v][none[d][j]]) none[d + 1][tnn ++] = none[d][j];
        dfs(d + 1, an + 1, tsn, tnn);
        //把v从some取出,放入none
        some[d][i] = 0, none[d][nn ++] = v;
    }
}


(

原文:

The basic form of the algorithm, described above, is inefficient in the case of graphs with many non-maximal cliques: it makes a recursive call for every clique, maximal or not. To save time and allow the algorithm to backtrack more quickly in branches of the search that contain no maximal cliques, Bron and Kerbosch introduced a variant of the algorithm involving a "pivot vertex" u, chosen from P (or more generally, as later investigators realized,[4] from P ⋃ X). Any maximal clique must include either u or one of its non-neighbors, for otherwise the clique could be augmented by adding u to it. Therefore, only u and its non-neighbors need to be tested as the choices for the vertex v that is added toR in each recursive call to the algorithm. In pseudocode:

)

以上算法太朴素,搜索了大量不是极大团的点集。

为了节省时间和让算法更快的回溯,我们可以通过设定关键点 pivot vertex u。
对于任意的最大团,其必须包括顶点u或者u的非邻接点.否则就可以添加顶点u来扩充极大团,这显然矛盾.所以.我们只要测试 顶点u以及 u的非邻接点即可.这样可以节省递归的时间.

伪代码:

   BronKerbosch(All, Some, None):
       if Some and None are both empty:
           report All as a maximal clique
       choose a pivot vertex u in Some ⋃ None
       for each vertex v in Some \ N(u)::
           BronKerbosch1(All ⋃ {v}, Some ⋂ N(v), None ⋂ N(v))
           Some := Some \ {v}
           None := None ⋃ {v}
C代码:

void dfs(int d, int an, int sn, int nn)
{
    if(sn == 0 && nn == 0) ++ S;
    int u = some[d][0];//pivot vertex
    for(int i = 0; i < sn; i ++)
    {
        int v = some[d][i];
        if(g[u][v]) continue;
        int tsn = 0, tnn = 0;
        for(int j = 0; j < an; j ++) all[d + 1][j] = all[d][j];
        all[d + 1][an] = v;
        for(int j = 0; j < sn; j ++)if(g[v][some[d][j]]) some[d + 1][tsn ++] = some[d][j];
        for(int j = 0; j < nn; j ++) if(g[v][none[d][j]]) none[d + 1][tnn ++] = none[d][j];
        dfs(d + 1, an + 1, tsn, tnn);
        //把v从some取出,放入none
        some[d][i] = 0, none[d][nn ++] = v;
    }
}
poj 2989代码:

/*
TechMonster
02.13.2016
*/
#include<stdio.h>
#include<iostream>
#include<string>
#include <algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#define pi acos(-1.0)
#define ls o<<1
#define rs o<<1|1
#define MS(x,y) memset(x,y,sizeof(x));
<span style="font-family: Arial, Helvetica, sans-serif;">#define MAXN 130</span>
const int MAXN = 0x3f3f3f3f;
const double eps = 1e-8;
void fre(){freopen("t.txt","r",stdin);}
using namespace std;
int N, M, a[MAXN], g[MAXN][MAXN];
int S, all[MAXN][MAXN], some[MAXN][MAXN], none[MAXN][MAXN];
//all为已取顶点集,some为未处理顶点集,none为不取的顶点集
//我们求最大团顶点数时只要some,要求记录路径时要all和some,这里求极大团数量,需要all、some、none
void dfs(int d, int an, int sn, int nn)
{
    if(S > 1000) return ; // 极大团数量超过1000就不再统计
    if(sn == 0 && nn == 0) ++ S;//sn==0搜索到终点,只有nn==0时,才是一个极大团
    int u = some[d][0];//pivot vertex
    for(int i = 0; i < sn; i ++)
    {
        int v = some[d][i];
        if(g[u][v]) continue;
        int tsn = 0, tnn = 0;

        for(int j = 0; j < an; j ++) all[d + 1][j] = all[d][j];
        all[d + 1][an] = v;

        for(int j = 0; j < sn; j ++)if(g[v][some[d][j]]) some[d + 1][tsn ++] = some[d][j];


        for(int j = 0; j < nn; j ++) if(g[v][none[d][j]]) none[d + 1][tnn ++] = none[d][j];


        dfs(d + 1, an + 1, tsn, tnn);

        //把v从some取出,放入none
        some[d][i] = 0, none[d][nn ++] = v;
    }
}
void process()
{
    S = 0;
    for(int i = 0; i < N; i ++) some[0][i] = i + 1;
    dfs(0, 0, N, 0);
    if(S > 1000) printf("Too many maximal sets of friends.\n");
    else printf("%d\n", S);
}
int main()
{
  //  fre();
    while(scanf("%d%d", &N, &M) == 2)
    {
        MS(g, 0);
        for(int i = 0; i < M; i ++)
        {
            int x, y;
            scanf("%d%d", &x, &y);
            g[x][y] = g[y][x] = 1;
        }      
        process();
    }
    return 0;
}


除此之外还有另一种优化方法:

An alternative method for improving the basic form of the Bron–Kerbosch algorithm involves forgoing pivoting at the outermost level of recursion, and instead choosing the ordering of the recursive calls carefully in order to minimize the sizes of the sets P of candidate vertices within each recursive call.

The degeneracy of a graph G is the smallest number d such that every subgraph of G has a vertex with degree d or less. Every graph has a degeneracy ordering, an ordering of the vertices such that each vertex has d or fewer neighbors that come later in the ordering; a degeneracy ordering may be found in linear time by repeatedly selecting the vertex of minimum degree among the remaining vertices. If the order of the vertices v that the Bron–Kerbosch algorithm loops through is a degeneracy ordering, then the set P of candidate vertices in each call (the neighbors of v that are later in the ordering) will be guaranteed to have size at most d. The set X of excluded vertices will consist of all earlier neighbors of v, and may be much larger than d. In recursive calls to the algorithm below the topmost level of the recursion, the pivoting version can still be used.[6][7]

In pseudocode, the algorithm performs the following steps:

   BronKerbosch3(G):
       P = V(G)
       R = X = empty
       for each vertex v in a degeneracy ordering of G:
           BronKerbosch2(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
           P := P \ {v}
           X := X ⋃ {v}

没怎么研究,有兴趣自己看吧。。



Bron-Kerbosh算法求解极大团 Bron-Kerbosh算法求解极大团 参考资料:https://www.jianshu.com/p/437bd6936dad 这篇文章讲得很好,本文的代码也是参照这篇文章,用python实现。 什么是极大团? 团、极大团、最大团的定义请问这篇文章:https://www.jianshu.com/p/dabbc78471d7 为什么会用到极大团? 了解到极大团这个知识,是在构建任务指派模型的时候接触到的。在对任务进行指派时,每个任务都有其开始时间、结束时间,在不考虑员工资质的情况下,任务之间可能会存在时间上 阅读详情

相关推荐

POJ-2989-All Friends 极大团算法 Bron-Kerbosch及其改进

http://poj.org/problem?id=2989 给n个点m条边,求极大团的数量。 极大团的定义就是:对于一个团里,所有人互为朋友,且团外的任何一个人,都不会和团里的所有人同时是朋友。 BK算法的伪代码 BronKerbosch(All, Some, None): if Some and None are both empty:

缺氧 1910

最大独立集和最大完全子图

定义 最大独立集:当且仅当对于U 中任意点u 和v所构成的边(u , v) 不是G 的一条边时,U 定义了一个空子图。当且仅当一个子集不被包含在一个更大的点集中时,该点集是图G 的一个独立集(independent set ),同时它也定义了图G 的空子图。最大独立集是具有最大尺寸的独立集(摘自:百度百科:最大独立集)。 最大完全子图:图中任意两顶点都直接相连的图,称为完全图,也称全连接图。图...

FanJin的博客 1万+

Bron-Kerbosch 极大团发现算法:实现 Bron-Kerbosch 算法以查找无向图的所有极大团。-matlab开发

[MC] = MAXIMALCLIQUES(A,V_STR) 给定图的布尔邻接矩阵 A,使用 Bron-Kerbosch 算法以递归方式找到 A 上的所有最大团。 V_STR 是一个可选的输入字符串,带有要使用的 Bron-Kerbosch 算法的版本(“v1”或“v2”)。 版本 2 更快(并且是默认值),并且版本 1 被包含在内以供后代使用。 输出矩阵 MC 在其列中包含最大集团。 注意:此函数可用于通过提供 A 的补集作为输入图来计算图 A 的最大独立集。 注意:此函数可用于通过提供 A 的线图的补集作为输入图来计算图 A 的最大匹配。 参考:Bron、Coen 和 Kerbosch,Joep,“算法 457:查找无向图的所有集团”,ACM 通信,卷。 16,没有。 9, pp: 575–577, 1973 年 9 月。 参考:Cazals, F. 和 Karande,

无向图的极大团、最大团(Bron-Kerbosch算法)

描述:团就是最大完全子图。(极大团) 给定无向图G=(V,E)。如果U包含于V,且对任意u,v属于U且有(u,v)属于E,则称U是G的完全子图。 G的完全子图U是G的团当且仅当U不包含在G的更大的完全子图中,即U就是最大完全子图。 G的最大团是指G中所含顶点数最多的团。 // 最大团: V中取K个顶点,两点间相互连接 // 最大独立集: V中取K个顶点,两点间不连接 // 最大...

yo_bc的博客 3万+

FastH3 + vLLM-Omni:MiniMax H3 视频生成本地部署与加速实战

随着多模态大模型在视频生成领域的普及,如何高效部署和加速推理成为工程实践的关键。vLLM作为高性能推理框架,通过PagedAttention和continuous batching显著优化了大模型吞吐;而FastH3则针对特定模型结构进行算子融合和CUDA优化。结合vLLM-Omni对多模态输入的支持,可以将MiniMax H3的视频生成耗时从分钟级压缩至秒级。本文以视频生成模型为例,详细拆解环境配置、推理优化与问题排查,为多模态模型本地部署提供参考。

ciya3282的博客 482

多元相关性分析_PAST:最简便易用的统计学分析软件教程目录

欢迎来到PAST的世界!本教程并不是将PAST的所有功能均进行详细介绍,而只是挑选与生物、医学、微生物研究相关的统计学分析内容进行讲述。根据PAST内各项分析的标签分类,将该教程具体设置如下:PAST软件介绍PAST的基本信息数据的输入和修改数据的转换和标准化图像绘制 (Plot标签)点线图和直方图散点图条形图和箱须图饼图堆叠条形图三元相图气泡图单变量统计学分析 (Univariate标...

weixin_39605706的博客 3155

极大团与networkx Bron-Kerbosch算法源码解读

我在基于最大团的图池化里提到了一点点Bron-Kerbosch算法,不过对这个算法还是没有太了解,今天单独拿出一篇文章来说这个算法。首先,https://www.jianshu.com/p/437bd6936dad 有着很详细的介绍,毕竟原论文太偏向于理论了不好读透。我会在其基础上添加一些我的理解,并解读networkx的源码。 Bron-Kerbosch算法 极大团的检索算法的时间复杂度都比较高,最近查资料发现也有许多研究旨在降低其时间复杂度,或者在稀疏的巨型图上应用,但是这些都需要对BK算法做一个深入理

qq_36618444的博客 3612

SAP BTP-Cloud foundry 构建并部署JAVA应用程序

本文为 SAP BTP Java 应用程序的简单实例, 我们可以用此实例来熟悉SAP BTP 中的java应用开开发流程.在你完成改示例java应用程序以后, 我们可以直接使用该java应用程序进行后续的开发流程, 或直接构建一个新的JAVA应用程序来支持新的业务开发。

seyafly的博客 803

POJ - 2989 All Friends 极大团

POJ - 2989点我点我 All Friends Time Limit: 1000MS   Memory Limit: 65536KB   64bit IO Format: %lld & %llu Submit Status Description Sociologists are interested in the p

Free Cat~~~ 跳动的喵 1602

熵权法+TOPSIS完整教学:用Python评估大学科研实力(含雷达图绘制技巧)

本文提供了一套完整的熵权法与TOPSIS综合评价方法在Python中的实现教程,以高校科研实力评估为例,详细讲解了从数据预处理、客观权重计算、综合排序到结果可视化的全流程。重点介绍了如何利用Python进行数据清洗与转换,通过熵权法自动确定指标权重,并结合TOPSIS模型计算各院校与理想解的相对接近度进行排名。教程还包含了使用Matplotlib绘制专业雷达图的技巧,帮助读者直观呈现多维数据的对比分析结果,适用于各类多指标决策与绩效评估场景。

weixin_28520495的博客 416

基于YOLOv8的MVTec AD缺陷检测系统设计与实现

速度快,精度高;支持 anchor-free 架构;支持实例分割和图像分类;模块化代码,易于部署与改进;完美兼容 ONNX、TensorRT 等推理框架;官方支持多平台训练和推理(CPU/GPU)。YOLOv8 是工业视觉检测落地非常理想的选择。MVTec AD(Anomaly Detection)数据集包括15类工业对象,每个对象包括多个子类缺陷(例如 “scratch”, “crack”, “hole”)及正常图像。类别缺陷子类bottlecablecapsule。

YOLO 931

poj2989 All Friends(极大团)

题意:给出n个人,其中m对朋友,求最大团数量(就是在团中的人互为朋友,不在团中的人与某些在团中的人不互为朋友,在本题中人数不要求最多) 题解:要用Bron–Kerbosch算法。找最大团,我们设了三个数组:all, some, none,分别表示的是已经选了的点,还没动的点,不要的点(避免重复,实际上就是判重)。 算法的思想是将some中的点逐步加入all和none中,当我们将一个点...

一身清贫怎敢入繁华 706

Windows环境下QGIS完整编译指南(从环境搭建到问题解决)

本文详细介绍了在Windows 11系统下编译QGIS 3.40.12版本的完整流程。主要内容包括:前期准备工作(系统要求、工具清单)、环境搭建(Visual Studio 2026、OSGeo4W、Qt Creator的安装配置)、以及详细的CMake参数设置。特别强调了依赖管理的重要性,并提供了解决常见编译错误的方案。该指南适用于GIS二次开发、QGIS功能定制和源码学习等场景,通过OSGeo4W工具简化了复杂的依赖管理过程,确保编译过程的可重复性。

LuckyHanMo的博客 1333

「图论」Bron-Kerbosch 算法

7.21晚上加赛 T2.七负我,做这题找到了性质发现需要求最大团,不会,爆搜,打假了,赛后改,对了,但时间复杂度大爆炸,看下发题解,有这么一句话:于是学习了一下。 updated on 7.24 增加了图片演示方便理解; updated on 7.25 更新了 \(X\) 集合的作用和关键点优化的解释。 Bron-Kerbosch算法-求图的最大团,极大团 概念: 团:每个顶点都两两...

weixin_40386663的博客 612

栅格数据做相关性分析前的预处理(批量定义投影、栅格投影、重采样)

最近在做两个栅格数据的相关性分析,这个最主要的是两个栅格数的行列号是一致的(也就是说坐标系、分辨率一致),那么标准的栅格数据的分辨率是以米的形式存在的,但是有一些栅格数据是以度为单位存在的,所以在做分析前,一定要先把其转换为米,否则在重采样的时候就会出错。(相关文章——栅格数据以度为单位变为以米为单位的简单做法)当然,在变其分辨率的单位前,一定要将其坐标系转换为一致。所以就有以下的步骤(如何将两个栅格数据的坐标系、分辨率的单位和分辨率一致) 1.首先,要看两个栅格数据的坐标系是否一致,如果不一致,要先统一到

qq_41828818的博客 8350

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Bron-kerbosch算法-求图的最大团,极大团

概念介绍: 团:每个顶点都两两相连 极大团:没有被包含在其他团中的团 最大团:顶点数最多的极大团 独立集:从图中取k个点,任意两点之间不连接 最大团顶点数量:等于补图中最大独立集顶点数 补图:在图论里面,一个图G的补图(complement)或者反面(inverse)是一个图有着跟G相同的点,而且这些点之间有相连当且仅当在G里面他们没有边相连。在制作图的时候,你可以先建立一个有G所有点的完全...

qq_40678690的博客 1812

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

SLAM匹配之无向图------最大团搜索算法总结

在图论中,团 (Clique)是图中一个顶点的子集,使得子集中任意两个顶点都有一条边相连。换句话说,一个团是一个完全子图。

lovely_yoshino的博客 1万+

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

最大团问题 Bron-Kerbosch算法

最大团即最大完全子图问题。正常的做法是,先从一个小集合开始,如果一个新点和这个集合每个元素都有一条边,那么这个新点就可以加到团中。 Bron-Kerbosch算法的特点是,无需显示判断新点是否和原来的集合有边。 R集合即为集合,P集合为搜索范围,由伪代码可见,每个点的邻居都要用交集处理。这样,只有所有人都有的邻居才能加入集合。X集合为不处理的点,如果不处理的点也是所有人的朋友,那就不是最大团(加入新点就不是团)。所以,此算法可以找到所有的最大团,很强。 ...

qq_39678022的博客 2576

学习一个 Bron-Kerbosch 算法

Bron-Kerbosch 算法计算图的最大全连通分量(团clique) 最大独立集: 顶点集V中取 K个顶点,其两两间无连接。 最大团: 顶点集V中取 K个顶点,其两两间有边连接。最大团中顶点数量 = 补图的最大独立集中顶点数量补图定义: G = #include<cstdio> #include<cstdlib> #include<cstring>int best; int num[ma

onepointo 2857

POJ 2989 All Friends (极大团数量 + 全局变量局部变量)

点击打开链接 题意:给出n个点,然后给出m组相邻的点,问极大团的数量。 核心是不变的,还是注意细节,细节如果出错,就会出现一些奇怪的结果。还有要知道怎么样做可以避免出错。 这道题三个集合里放的编号都应该是从1开始的,因为题设编号就是从1开始的。这样一定不会出错,事实证明从0开始的确不可以。 如果一个变量既定义了全局变量,又定义了局部变量,那么就可以看成是一个全局变量和一个局

Muya 934

Bron–Kerbosch算法求一般图最大团/最大独立集

最大团: V中取K个顶点,两点间相互连接 最大独立集: V中取K个顶点,两点间不连接 最大团数量 = 补图中最大独立集数 关于 Bron-Kerbosch算法(原文)   基础形式是一个递归回溯的搜索算法.通过给定三个集合 (R,P,X).   初始化集合R,X分别为空,而集合P为所有顶点的集合.   而每次从集合P中取顶点{v}, 当集合中没有顶点时,两种情况.   ...

REWINE 7720

最大团问题分支限界法_最大团问题与 Bron-Kerbosch 算法

最近注意到了图论中的最大团问题。最大团问题是一个 NP 完全问题,在此对它做简单介绍,并介绍具有代表性的 Bron-Kerbsch 算法。什么是一个团?最大团问题首先一个图的问题,假设读者已经知道图的概念。假设一个无向图 ,一个团是图 的子图,该子图中的所有顶点之间都有边将它们相连。极大团指的是,该团不包含于图 的任何其他团,即不是任何其他团的真子集。最大团指的是结点数量最多的极大团。最大团...

weixin_31971181的博客 1353

发现一个宝藏 Python 库,玩社区发现算法的不能错过!

网络是由一些紧密相连的节点组成的,并且根据不同节点之间连接的紧密程度,网络也可视为由不同簇组成。簇内的节点之间有着更为紧密的连接,不同簇之间的连接则相对稀疏。这种簇被称为**网络中的社区结构**(community structure)。

Trb401012的博客 1311

图论---极大团(POJ 2989,Hdu 1530)

1、极大团: 一个图G = (V,E),要求选取一个子图,这个图中的任意两个点都能相互到达,当这个子图的顶点数最多时, 这个图就是图G的极大团。 2、求解方法: Born_Kerbosch算法: (1)规定三个集合: R:极大团中所包含的顶点; P:未被匹配,还有可能加入极大团的点; X:已经被其他极大团匹配过的点,就是已经计数过的点,用于判断重复的极大团; (2)然...

积少成多,水滴石穿 916

算法笔记 --- Bron–Kerbosch算法-最大独立集与最大问题

定义 最大团:点数最多的极大团。 极大团:不是其他团的子团的团。 团:原图的完全子图。 最大独立集:一个点数最多的点集,且满足集合内的点互不相邻 性质 一个图的最大独立集的集合大小等于该图的补图的最大团大小 用于解决最大团问题的Bron–Kerbosch算法 简书上的图解 博客园的三种优化 优快云上的原理 #define N 1010 /* 最大团 = 补图G的最大独立集数 ———>最大独...

欢迎光临 我的心 1189
上一篇: hdu 1936 Emoticons :-)
下一篇: 高斯消元 模板 hdu2262 判断无穷解 接受无穷解 两种
QZQmmmm
博客等级 码龄11年 77粉丝 110原创
评论 6
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值