算法分析 | 回溯法 | 最大团问题
一.问题描述
在若干点和若干连线中,找到完全子图,即子图中各个点都和其他点相连
二.代码实现
代码有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;
}
三.总结
难得的一次编译运行,值得纪念

浙公网安备 33010602011771号