回溯算法+分支限定--解最大团问题

最大团问题介绍:给定无向图G=<V,E>,G是一个完全子图(任何两点之间都有边)就称为G的一个团,问题是找一个最大团(顶点  数最多的团)(先实现只从中找一个最大团,题目也可能要求找所有的最大团)

/**************************最大团问题********************/

#include <iostream>
using namespace std;

const int N = 10;
int n;//原图顶点数
int A[N][N] = { 0 };//表示图的顶点是否连接的关系矩阵
int tempmax;
int OptimalMax;
int x[N] = { 0 };
int Optimal[N] = { 0 };
//bool OK = true;

int Bound(int k)
{
	x[k] = 0;
	int Cn = 0;//表示符合条件的点集里点的数目
	for (int i = 1; i <k; ++i)
	{
		if (x[i] == 1)
			++Cn;
	}
	
	return Cn+n-k;
}


void Traceback(int k)   //k是新加入的顶点(要考虑第i层)
{
	if (k> n) // 到达叶结点  
	{
		for (int j = 1; j <= n; j++)
		{
			Optimal[j] = x[j];
			cout << x[j] << " ";
		}
		cout << endl;
		OptimalMax = tempmax;
		
	}
	
	else
	{
		bool OK = true;   //这个OK不能是全局变量
		for (int j = 1; j < k; j++)
			if (x[j] && A[k][j] == 0)
			{
				// i与j不相连  
				OK =false;
				break;
			}

		if (OK)// 进入左子树  
		{
			x[k] = 1;
			tempmax++;
			Traceback(k+ 1);//此句之后便是回溯

			x[k] = 0;     //既然回溯,考虑第k个点不加入会更好不
			tempmax--;
		}

		if (tempmax + n - k >= OptimalMax)// 进入右子树  
			//tempmax + n - k是代价函数,OptimalMax是界,右子树要是有比OptimalMax大的希望就走下试试
		{
			x[k] = 0;
			Traceback(k + 1);
		}
	}
	
	
}

int main()
{
	cout << "这是回溯+分支限定解决最大团问题的算法实现:" << endl;
	cout << "/*********************************/" << endl;

	cout << "请输入原图的顶点数n: ";
	cin >> n;

	cout << "请输入A[i][j]"; cout << endl;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
		{
			cin >> A[i][j];
		}


	Traceback(1);

	cout << "最大顶点集的顶点个数是:";
	cout << OptimalMax << endl;

	cout << "与之对应的解向量是:";
	for (int i = 1; i <= n; i++)
	{
		cout << Optimal[i] << " ";
	}
	return 0;

}

参考:https://blog.csdn.net/liufeng_king/article/details/8781554

本文为博主原创文章,未经博主允许不得转载



猜你喜欢

转载自blog.csdn.net/qq_34793133/article/details/80717016
今日推荐