Bron–Kerbosch算法-最大独立集与最大团
来源:互联网 发布:北影的明星 知乎 编辑:程序博客网 时间:2024/05/17 08:25
Bron-Kerbosch 算法计算图的最大全连通分量(团clique)
最大独立集: 顶点集V中取 K个顶点,其两两间无连接。
最大团: 顶点集V中取 K个顶点,其两两间有边连接。
最大团中顶点数量 = 补图的最大独立集中顶点数量
就可以通过求其补图中最大团中顶点数量,就可得出原图中最大独立集中顶点数量了.
对于求解 最大团中顶点数量 的搜索过程中用到的剪枝,如下
1. 剪枝1:常用的指定顺序, 即枚举第i个顶后, 以后再枚举时枝考虑下标比大它的, 避免重复。
2. 剪枝2:自己开始从前往后的枚举顶点, TLE两次. 后来从后往前枚举顶点,发现可以利用顶点之间的承袭性.我用num[i] 记录的可选顶点集合为 V[i, i+1, ... , n] 中的最大团数目, 目标是求num[1].
分析易知, num[i] = num[i+1] 或者 num[i]+1 (num[1...n] 具有非降的单调性,从后往前求)
由这个式子以及num[]信息的记录,使得我们可以增加两处剪枝:
3.上/下剪枝:假设当前枚举的是顶点x, 它的第一个邻接顶是i (标号一定比x大,即num[i]已经求出) 我们可以知道, 若 1 + num[i] <= best, 那么是没没要往下枚举这个顶点x了,因为包含它的团是不可能超过我们目前的最优值的。
4. 立即返回剪枝: 由于num[i]最大可能为num[i+1]+1, 所以在枚举顶点i时,只要一更新best,可知此时的num[i]就为num[i+1]+1了,不需要再去尝试找其他的方案了,所以应立即返回.
2. 剪枝2:自己开始从前往后的枚举顶点, TLE两次. 后来从后往前枚举顶点,发现可以利用顶点之间的承袭性.我用num[i] 记录的可选顶点集合为 V[i, i+1, ... , n] 中的最大团数目, 目标是求num[1].
分析易知, num[i] = num[i+1] 或者 num[i]+1 (num[1...n] 具有非降的单调性,从后往前求)
由这个式子以及num[]信息的记录,使得我们可以增加两处剪枝:
3.上/下剪枝:假设当前枚举的是顶点x, 它的第一个邻接顶是i (标号一定比x大,即num[i]已经求出) 我们可以知道, 若 1 + num[i] <= best, 那么是没没要往下枚举这个顶点x了,因为包含它的团是不可能超过我们目前的最优值的。
4. 立即返回剪枝: 由于num[i]最大可能为num[i+1]+1, 所以在枚举顶点i时,只要一更新best,可知此时的num[i]就为num[i+1]+1了,不需要再去尝试找其他的方案了,所以应立即返回.
#include<cstdio>#include<cstdlib>#include<cstring>int best;int num[maxn];// int x[maxn];int path[maxn]; int g[maxn][maxn], n;bool dfs( int *adj, int total, int cnt ){ // total: 与u相连的顶点数量 , cnt表示当前团的数量 int i, j, k; int t[maxn]; if( total == 0 ){ // 当此团中最后一个点 没有 比起序号大 的顶点相连时 if( best < cnt ){ // 问题1:best为最大团中顶点的数量 // for( i = 0; i < cnt; i++) path[i] = x[i]; best = cnt; return true; } return false; } for( i = 0; i < totl; i++){ // 枚举每一个与 u 相连的顶点 adj[i] if( cnt+(total-i) <= best ) return false; // 剪枝1, 若当前 顶点数量cnt 加上还能够增加的最大数量 仍小于 best则 退出并返回false if( cnt+num[adj[i]] <= best ) return false; // 剪枝2, 若当前 顶点数量cnt 加上 包含adj[i]的最大团顶点数 仍小于 best则 退出并返回false // x[cnt] = adj[i]; for( k = 0, j = i+1, j < total; j++ ) // 扫描 与u相连的顶点 中与 adj[u]相连的顶点 并存储到 数组 t[]中,数量为k if( g[ adj[i] ][ adj[j] ] ) t[ k++ ] = adj[j]; if( dfs( t, k, cnt+1 ) ) return true; } return false;} int MaximumClique(){ int i, j, k; int adj[maxn]; if( n <= 0 ) return 0; best = 0; for( i = n-1; i >= 0; i-- ){ // x[0] = i; for( k = 0, j = i+1, j < n; j++ ) // 遍历 [i+1, n] 间顶点, if( g[i][j] ) adj[k++] = j; dfs( adj, k, 1 ); // *adj, total, cnt num[i] = best; // 得出顶点 i, 出发构成最大团 中顶点数量 } return best;}
关于 Bron-Kerbosch算法
基础形式是一个递归回溯的搜索算法.通过给定三个集合 (R,P,X).
初始化集合R,X分别为空,而集合P为所有顶点的集合.
而每次从集合P中取顶点{v}, 当集合中没有顶点时,两种情况.
1. 集合 R 是最大团, 此时集合X为空.
2. 无最大团,此时回溯.
对于每一个从集合P中取得得顶点{v},有如下处理:
1. 将顶点{v}加到集合R中, 集合P,X 与 顶点{v}得邻接顶点集合 N{v}相交, 之后递归集合 R,P,X
2. 从集合P中删除顶点{v},并将顶点{v}添加到集合X中.
若 集合 P,X都为空, 则集合R即为最大团.
总的来看就是每次从 集合P中取v后,再在 P∩N{v} 集合中取,一直取相邻,保证集合R中任意顶点间都两两相邻...
#include<cstdio>#include<cstring>#define N 1010bool flag[N], a[N][N];int ans, cnt[N], group[N], n, vis[N];// 最大团: V中取K个顶点,两点间相互连接// 最大独立集: V中取K个顶点,两点间不连接 // 最大团数量 = 补图中最大独立集数 bool dfs( int u, int pos ){ int i, j; for( i = u+1; i <= n; i++){ if( cnt[i]+pos <= ans ) return 0; if( a[u][i] ){ // 与目前团中元素比较,取 Non-N(i) for( j = 0; j < pos; j++ ) if( !a[i][ vis[j] ] ) break; if( j == pos ){ // 若为空,则皆与 i 相邻,则此时将i加入到 最大团中 vis[pos] = i; if( dfs( i, pos+1 ) ) return 1; } } } if( pos > ans ){ for( i = 0; i < pos; i++ ) group[i] = vis[i]; // 最大团 元素 ans = pos; return 1; } return 0;} void maxclique(){ ans=-1; for(int i=n;i>0;i--) { vis[0]=i; dfs(i,1); cnt[i]=ans; }}
0 0
- Bron–Kerbosch算法-最大独立集与最大团
- 最大团 Bron–Kerbosch算法
- 最大团 极大团 Bron–Kerbosch算法 poj 2989
- 无向图的极大团、最大团(Bron-Kerbosch算法)
- 最大团,最大独立集
- 学习一个 Bron-Kerbosch 算法
- 无向图的最大团与最大独立集
- Spark GraphX实现Bron–Kerbosch算法-极大团问题
- 图论 最大团,最大独立集
- 独立集,覆盖集,支配集,最大团,最大匹配
- 独立集,覆盖集,支配集,最大团,最大匹配
- 独立集,覆盖集,支配集,最大团,最大匹配
- 独立集,覆盖集,支配集,最大团,最大匹配
- POJ3692 二分图最大团 最大独立集
- POJ 3692 Kindergarten 最大团->最大独立集
- POJ 1419 最大独立集(即最大团)
- POJ 1419 Graph Coloring(最大独立集、最大团)
- 无向图的最大独立集和最大团
- memecached 在Windows下安装多个
- 与窗口SIZE相关的常用WIN API
- 信号经过无线空间的各种损耗,最终测试手机测试到的信号强度肯定在0DB以下啊
- 确定进制
- Windows Server 2003 启动过程分析
- Bron–Kerbosch算法-最大独立集与最大团
- Spring的基本用法(三)
- TCP传输控制协议
- char *const p;与 const char * p;的区别
- GITHUB自学系列之四「向GITHUB 提交代码」
- 欢迎使用CSDN-markdown编辑器
- 深圳图书馆
- jstorm源码分析: zookeeper
- 开始啦