最大团问题(Maximum Clique Problem, MCP)

概述:


  最大团问题(Maximum Clique Problem,
MCP)是图论中一个经典的组合优化问题,也是一类NP完全问题。最大团问题又称为最大独立集问题(Maximum Independent Set
Problem)。目前,求解MCP问题的算法主要分为两类:确定性算法和启发式算法。确定性算法有回溯法、分支限界法等,启发式算法、蚁群算法、顺序贪婪算法、DLS-MC算法和智能搜索算法等。

问题描述:

  给定无向图G=(V,E),其中V是顶点集;E是V边集。如果U属于V,且对任意两个顶点u,v∈U有(u,v)∈E,则称U是G的完全子图。G的完全子图U是G的一个团当且仅当U不包含在G的更大的完全子图中。G的最大团是指G中所含顶点数最多的团。

  如果U属于V,且对任意u,v∈U有(u,v)不属于E,则称U是G的空子图。G的空子图U是G的独立集当且仅当U不包含在G的更大的空子图中。G的最大独立集是G中所含顶点数最多的独立集。

  对于任一无向图G=(V,E),其补图G‘=(V‘,E‘)定义为:V‘=V,且(u,v)∈E‘当且仅当(u,v)?E。

  如果U是G的完全子图,则它也是G‘的空子图,反之亦然。因此,G的团与G‘的独立集之间存在一一对应的关系。特殊地,U是G的最大团当且仅当U是G‘的最大独立集。

算法分析:

  无向图G的最大团和最大独立集问题都可以用回溯法在O(n2n)时间内解决。图G的最大团和最大独立集问题都可以看作是图G的顶点集V的子集选取问题。因此可用子集树表示问题的解空间。

  设当前扩展节点Z位于解空间树的第 层。在进入左子树前,必须确认从顶点 到已入选的顶点集中每一个顶点都有边相连。在进入右子树之前,必须确认还有足够多的可选择顶点使得算法有可能在右子树中找到更大的团。

算法描述:


 1 #include <fstream>
2 #include <iostream>
3 #include <stdlib.h>
4 #include <conio.h>
5 using namespace std;
6
7 #define MAX_v 50 //定义一个最大顶点个数
8 typedef struct{
9 int a[MAX_v][MAX_v]; //无向图G的邻接矩阵
10 int v; //无向图G的顶点
11 int e; //无向图G的边
12 int x[50]; //顶点与当前团的连接,x[i]=1 表示有连接——即x[i]==1代表在当前最大团的解内
13 int bestx[50]; //当前最优解
14 int cnum; //当前团的顶点数目
15 int bestn; //最大团的顶点数目
16 }MCP;
17
18 void Creat(MCP &G);
19 void Backtrack(MCP &G,int i);
20
21 void Creat(MCP &G){
22 int i,j;
23 ifstream fin("data.txt");
24 if (!fin)
25 {
26 cout<<"不能打开文件:"<<"data.txt"<<endl;
27 exit(1);
28 }
29 fin>>G.v;
30 for (int i=1;i<=G.v;i++)
31 for (int j=1;j<=G.v;j++)
32 fin>>G.a[i][j];
33 for(i=1;i<=G.v;i++) //初始化
34 {
35 G.bestx[i]=0;
36 G.x[i]=0;
37 G.bestn=0;
38 G.cnum=0;
39 }
40 cout<<"———回溯法求解最大团问题———"<<endl;
41 cout<<"输入初始化无向图矩阵为:"<<endl; //初始化
42 for(i=1;i<=G.v;i++)
43 {
44 for(j=1;j<=G.v;j++)
45 cout<<G.a[i][j]<<" ";
46 cout<<endl;
47 }
48 }
49
50 void Backtrack(MCP &G,int i){
51 if (i>G.v){ //output()阶段
52 for (int j=1; j<=G.v; j++)
53 G.bestx[j] = G.x[j]; //记录最优解
54 G.bestn =G.cnum;
55 return ;
56 }
57 //检查顶点i与当前团的连接
58 int OK = 1;
59 for (int j=1; j<=i ; j++)
60 if (G.x[j]&& G.a[i][j]==0){ //G.x[j]:顶点j在当前解的最大团内;G.a[i][j]:待考察i顶点与最大团中前i-1个顶点间边的关系
61 //i不与j相连
62 OK = 0;
63 break;
64 }
65 if (OK) { //进入左子树
66 G.x[i] = 1;//把i加入团
67 G.cnum++;
68 Backtrack(G,i+1);
69 G.x[i]=0;
70 G.cnum-- ;
71 }
72 if (G.cnum+G.v- i>G.bestn){ //进入右子树——剪枝函数
73 G.x[i] = 0;
74 Backtrack(G,i+1);
75 }
76 }
77
78 int main(){
79 MCP G;
80 Creat(G);
81 Backtrack(G,1);
82 cout<<"最大团包含的顶点数为:"<<G.bestn<<endl;
83 cout<<"最大团方案为:( ";
84 for (int i=1;i<=G.v;i++)
85 if(G.bestx[i]==1){
86 cout<<i<<" ";
87 }
88 cout<<")"<<endl;
89 getch();
90 }

 注:问题在于这种解法只能求得其中的一个最大团解!

最大团问题百度百科:http://baike.baidu.com/view/7343867.htm

最大团问题(Maximum Clique Problem, MCP),布布扣,bubuko.com

时间: 2024-10-22 15:43:51

最大团问题(Maximum Clique Problem, MCP)的相关文章

hdu1530 Maximum Clique,最大团 , DP,邻接矩阵

Given a graph G(V, E), a clique is a sub-graph g(v, e), so that for all vertex pairs v1, v2 in v, there exists an edge (v1, v2) in e. Maximum clique is the clique that has maximum number of vertex. #include <cstdio> #include <cstring> #include

Maximum Clique

Maximum Clique Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 92 Accepted Submission(s): 60   Problem Description Given a graph G(V, E), a clique is a sub-graph g(v, e), so that for all vertex

分析公式 Codeforces 528B Clique Problem

http://codeforces.com/contest/528/problem/b Clique Problem time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output The clique problem is one of the most well-known NP-complete problems. Under some

CF527D Clique Problem

CF527D Clique Problem 题意简述 数轴上有n 个点,第i 个点的坐标为xi,权值为wi.两个点i,j之间存在一条边当且仅当 abs(xi-xj)>=wi+wj. 你需要求出这张图的最大团的点数.(团就是两两之间有边的顶点集合) solution 简单贪心 化简原式:就是找xi-wi>=xj-wj 那对于一个点i,设li=xi-wi,ri=xi+wi 把每一个点看作[li,ri]间的一条线段,只要表示两点的 线段不重叠,就有一条边,然后就是一道贪心了 CF里面的神奇思维题,难

Geeks Ford-Fulkerson Algorithm for Maximum Flow Problem 最大网络流问题

很久之前就想攻克一下网络流的问题了,一直拖着,一是觉得这部分的内容好像非常高级,二是还有很多其他算法也需要学习,三是觉得先补补相关算法会好点 不过其实这虽然是图论比较高级的内容,但是基础打好了,那么还是不会太难的,而且它的相关算法并不多,熟悉图论之后就可以学习了,就算法不会二分图也可以学习. 这里使用Ford-Fulkerson算法,其实现的方法叫做:Edmonds-Karp Algorithm 其实两者前者是基本算法思想,后者是具体实现方法. 两个图十分清楚: 图1:原图,求这个图的最大网络流

FZU - 2037 -Maximum Value Problem(规律题)

Let’s start with a very classical problem. Given an array a[1…n] of positive numbers, if the value of each element in the array is distinct, how to find the maximum element in this array? You may write down the following pseudo code to solve this pro

Codeforces 528B Clique Problem dp+线段树(or 树状数组)

题目链接:点击打开链接 题意: 给定数轴上的n个点. 下面n行每行两个数 xi, wi 表示点和点权. 对于任意两个点u, v 若dis(u,v) >= u_w+v_w 则这两个点间可以建一条边.(in other words 若两点间距离大于两点的权值和则可以建边) 找一个最大团,输出这个最大团的点数. 其实对于一个权值点我们可以认为是一个区间 如: 4 5 ,可以认为是区间[-1, 9] 则这个点可以从区间(-inf, 1]转移过来,即val(9) = max(val(9), 区间(-inf

[Lintcode] Maximum Gap Problem

问题描述 在一个无序的数组中,如果对其进行排序,然后扫描一遍有序数组,可以获得相邻两元素的最大差值,比如 {-1, 2, 4, 9},那么最大差值就是4和9之间,是5. 现在如果不对原始数组进行排序,有什么好的方案,来获取有序形式下的最大差值? Given an unsorted array, find the maximum difference between the successive elements in its sorted form. Return 0 if the array

[Codeforces Round #296 div2 D] Clique Problem 【线段树+DP】

题目链接:CF - R296 - d2 - D 题目大意 一个特殊的图,一些数轴上的点,每个点有一个坐标 X,有一个权值 W,两点 (i, j) 之间有边当且仅当 |Xi - Xj| >= Wi + Wj. 求这个图的最大团. 图的点数 n <= 10^5. 题目分析 两点之间右边满足 Xj - Xi >= Wi + Wj (Xi < Xj)       ==>     Xj  - Wj >= Xi + Wi (Xi < Xj) 按照坐标 x 从小到大将点排序.用