最大团 极大团 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万+

Simulink中为Scope模块添加图例的方法

比如我要在Scope模块输出三轴加速度的数据,但三轴数据波形混杂在一起不太好看,此时就需要在Scope模块中添加图例来使波形看起来更加清晰明了。 注:我这里使用的Matlab版本为2019a 1.首先在simulink中打开,需要添加图例的Scope,如图示: 2.在Matlab,command窗口输入: >> set(0,'ShowHiddenHandles','On'); >> set(gcf,'menubar','figure'); 此时你会发现Scope窗口菜单栏多了好几

Kunfly的博客 1万+

山景BP10_128DBG开发板通过蓝牙连接手机放歌实验回顾

最近在学习上海山景公司的BP10_128DBG的开发板,因为网上关于BP10开发板的帖子也比较少,在学习的时候也没有太多的参考资料,基本上都是官方的历程。蓝牙放歌这个demo对我来说也比较复杂,特写下此博客进行记录、总结,大家有需要的可以参考。

weixin_56646002的博客 2020

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

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

qq_36618444的博客 3612

嵌入式通信协议----Wi-Fi协议详解(一)

Wi-Fi,又称“无线网络”,是Wi-Fi联盟的商标,一个基于IEEE 802.11标准的无线局域网技术。“Wi-Fi”常写作“WiFi”或“Wifi”,但是这些写法并没有被Wi-Fi联盟认可。Wi-Fi产品经由Wi-Fi联盟的一家独立授权测试实验室进行严格测试,产品成功通过测试后,授予制造商或销售商使用Wi-Fi标志、Wi-Fi CERTIFIED标志和相关商标,Wi-Fi联盟使用术语“Wi-Fi CERTIFIED”来称呼这类通过认证的产品。

聪聪的成长之路 1656

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

Dify + mem0插件实战:如何让AI记住你的饮食习惯(附完整代码)

本文通过Dify平台与mem0插件实战,详细演示了如何为AI助手构建长期记忆系统,使其能记住并理解用户的复杂饮食习惯(如过敏源、饮食偏好)。文章提供了完整的工作流配置与Python代码示例,帮助开发者实现跨会话的个性化饮食建议,解决AI对话中的“健忘”问题。

lg888的博客 1094

STM32开发者必看:如何在正点原子探索者开发板上快速移植CANopenNode协议栈

本文为STM32开发者提供了在正点原子探索者开发板上快速移植CANopenNode协议栈的实战指南。文章详细介绍了从环境准备、硬件抽象层适配到协议栈初始化与测试的全过程,并分享了PDO配置与性能优化等关键技巧,帮助开发者高效实现CANopen标准化通信。

weixin_29173777的博客 462

poj2989 All Friends(极大团)

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

一身清贫怎敢入繁华 706

sqoop抽取mysql的数据到hive表里面,字段内容被自动截取,导致字段不全的问题解决

今天央视重新转播NBA,写篇博客纪念一下这个重要的日子,湖人的表现就呵呵了!!!! 强行转到博客的主题来 mysql的字段属性:该字段能存下的值比如:“山东” `province` varchar(3) NOT NULL COMMENT '省份' 用sqoop sqoop import --connect "jdbc:mysql://xxxxxx:3306/xxxxxx?tinyInt1isBit=false&zeroDateTimeBehavior=convertToNull..

放肆桀骜 963

「图论」Bron-Kerbosch 算法

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

weixin_40386663的博客 612

Python | 处理CMIP6 NC数据,以tas为例

各位同学,一般在文章最后一章我们可能会做不同气候情景下变量的未来时空变化特征,类似上图。从cmip6下载的nc数据常需要转换格式、裁剪到研究区和重采样等,本期代码可以解决这类问题。

qq_48539301的博客 1384

人工智能大模型原理与应用实战:AI模型转换为API的步骤和方法

传统的开发模式下,构建复杂的软件系统是非常费时费力的,而通过云计算、微服务等技术手段可以实现快速部署、弹性扩展的能力。在这种背景下,越来越多的公司将重点转移到研发人员的产品思维上,希望能够将自己的AI模型转换为一个可供他人调用的API接口。但是对于许多从事AI领域的研发人员来说,如何将自己的AI模型转换为API是一个比较棘手的问题。在这篇文章中,作者将从AI模型转换为API的过程分为以下几个步骤:AI模型准备阶段——模型选择、数据准备、模型训练。

AI天才研究院 2598

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

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

qq_40678690的博客 1812

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

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

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

lovely_yoshino的博客 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

最大团问题 Bron-Kerbosch算法

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

qq_39678022的博客 2576

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

学习一个 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、付费专栏及课程。

余额充值