算法分析 | 回溯法 | 最大团问题

一.问题描述

在若干点和若干连线中,找到完全子图,即子图中各个点都和其他点相连

 

二.代码实现

代码有4部分
1.定义全局变量
2.约束函数(限制生成左子树的函数)
3.递归函数
4.调用递归函数的函数,也可以直接写在main()

 

1.定义全局变量

const int M1 = 5;		//元素数
vector< vector<int>>A1 ={	//二维数组记录连接关系
{0,1,1,1,1},
{1,0,1,0,0},
{1,1,0,1,1},
{1,0,1,0,1},
{1,0,1,1,0}
};

int cn1;						//记录当前最优值
vector<bool> cx1(M1, 0);				//记录当前最优策略

int bestn1;						//记录最终最优值
vector<bool> bestx1(M1, 0);		                //记录最终最优策略

2.约束函数(限制生成左子树的函数)

//允许生成左子树的限制条件:第t个结点和0~t-1个结点中已被选中的结点是否全部相连,有假则假
bool MCPplace(int t)
{
	bool flag = true;
	for (int i = 0; i < t; i++)  
	{
		if (cx1[i]==1 &&A1[i][t]==0)					//cx1[i]==1:是被选中的结点 ;    i,t结点未相连
		{
			flag = false;
			break;
		}
	}
	return flag;
}

3.递归函数

void MCPbackpack(int t)		//传入的实参初值是0
{
	//先写终止条件
	if (t>=M1)		//说明遍历完0~M1-1个,此时可以记录一个最终最优值,并退出当前递归
	{
		bestx1 = cx1;
		bestn1 = cn1;
		return;
	}

	//左子树
	if (MCPplace(t))
	{
		cx1[t] = 1;		//标记当前策略
		cn1++;			//标记当前值
		MCPbackpack(t + 1);
		cn1--;			//回溯部分
	}

	//右子树
	if (cn1+(M1-t-1)>bestn1)
	{
		cx1[t] = 0; 
		MCPbackpack(t + 1);
	}
}

 4.调用递归函数

void MCP()
{
	bestn1 = cn1 = 0;
	MCPbackpack(0);
	cout << "最优值=	" << bestn1<<endl;
	cout << "最优策略是";
	for (int i = 0; i < M1; i++)
	{
		if (bestx1[i] == 1)
		{
			cout << i << "\t";
		}
	}
	cout << endl;
}

 

三.总结

难得的一次编译运行,值得纪念

 

posted @ 2020-02-14 17:18  心碎人俱乐部  阅读(32)  评论(0)    收藏  举报