最大团(回溯法)

问题描述:

给定一个无向图G=(V,E)。若UÍV,且对任意的u,vÎU, 都有边(u,v)ÎE, 则称U是图G的一个完全子图。 G的完全子图U是一个团,当且仅当U不包含在G的更大的完全子图中。G的最大团是指包含顶点数最多的团。

最大团问题是,对给定的无向图,找出最大团中顶点的个数。

 

算法思路:

首先最大团是一个空团(即不包含任何一个顶点的团),然后把每一个顶点依次加入团中。加入当前顶点i时,需要考虑当前顶点i是否与所有已经加入团的顶点邻接。如果不邻接,直接跳过该顶点,考虑下一个顶点。如果邻接,还需要考虑两种情况:一种是把当前顶点i加入团中,然后递归考虑后面的顶点;另一种是不把当前顶点i放入团中,然后递归考虑后面的顶点。直到所有的顶点都考虑完后,判断当前的最有解是否比之前的最优解更优。如果更优,用当前最优解替代之前的最优解,回溯;如果不是更优,回溯。直到将整个子集树遍历完,算法结束。 

约束函数:当前顶点i要与选入顶点集的每一个顶点邻接

上界函数:有足够多的可选顶点使有可能在右子树找到最大团

 

代码附录:

int n,				//图顶点数 
cn = 0,			// 当前的顶点集的顶点数 
bestn = 0;			// 之前最优解集的顶点数 
	
int **m,				// 图的邻接矩阵 
*x,				// 记录顶点是否放入顶点集 
	*bestx;			// 记录最优解集的顶点 

void BackTrack(int t){
	if(t>n){
		for(int i=1; i<=n; i++) bestx[i] = x[i];
		bestn = cn;
		return;
	}
	
	int ok = 1;
	// 约束函数 
	for(int j=1; j<t; j++){
		if(x[j] && m[j][t] == 0 ){
			ok = 0;
			break;
		}
	}
	// 当前顶点t与顶点集的顶点邻接,并将顶点t放入顶点集 
	if(ok){
		x[t] = 1;
		cn++;
		BackTrack(t+1);
		cn--;
		x[t] = 0;
	}
	// 上界函数 
	if(cn+n-t > bestn){
		x[t] = 0;
		BackTrack(t+1);
	}
}

 

  • 1
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值