最大团问题(迭代回溯法)

问题

设计一个解最大团问题的迭代回溯法

理解

给定无向连通图 G = (V,E),其中 V 是非空集合,称为顶点集; E 是 V 中元素构成的无序二元组的集合,称为边集,无向图中的边均是顶点的无序对,无序对常用圆括号“()”表示,如果 UϵV ,且对任意两个顶点 u , vϵU 有( u,v) ϵE ,则称 U 是 G 的完全子图,G 的完全子图是 G 的团当前仅当 U 不包含在 G 的更大的完全子图中。 G 的最大团是指 G 中所含顶点数最多的团 。

思路

首先设最大团为一个空团,往其中加入一个顶点,然后依次考虑每个顶点,查看该顶点加入团之后仍然构成一个团,如果可以,考虑将该顶点加入团或者舍弃两种情况,如果不行,直接舍弃,然后递归判断下一顶点。对于无连接或者直接舍弃两种情况,在递归前,可采用剪枝策略来避免无效搜索。

为了判断当前顶点加入团之后是否仍是一个团,只需要考虑该顶点和团中顶点是否都有连接。

程序中采用了一个比较简单的剪枝策略,即如果剩余未考虑的顶点数加上团中顶点数不大于当前解的顶点数,可停止继续深度搜索,否则继续深度递归。

C代码实现

#include <iostream>
using   namespace  std;
class  Clique
{friend   void  MaxClique( int  **, int  *, int  );private :void  Backtrack( int  i);int  **a;  //图的邻接矩阵int  n;  //图 的顶 点数int  *x;  //当前解int  *bestx;  //当前最优解int  cn;  //当前顶点数int  bestn;  //当前 最 大顶点数
};
void  Clique::Backtrack( int  i)
{  //计算最大团if (i>n)  //到达叶子节点 {for ( int  j=1;j<=n;j++)bestx[j]=x[j];bestn=cn;cout<< "最大团:(" ;for ( int  i=1;i<n;i++)cout<<bestx[i]<< "," ;cout<<bestx[n]<< ")" <<endl; return ;} //检 查 当前顶点是否与当前团连接int  ok=1;for ( int  j=1;j<i;j++)if (x[j]&&a[i][j]==0)  //i与j不连接,即j在团中,但是i,j不连接 { ok=0;break ;  }if (ok)  //进入左子树 {x[i]=1;cn++;Backtrack(i+1);  //回溯到下一层节点 x[i]=0;cn--;}//通过上界函数判断是否减去右子树,上界函数用于确认还有足够多的可选择顶点使得算法有可能在右子树中找到更大的团if (cn+n-i>=bestn) {  //修改一下上界函数的条件,可以得到 x[i]=0;  //相同点数时的解 Backtrack(i+1);}
}
void  MaxClique( int  **a, int  *v, int  n)
{  //初始化 YClique Y;Y.x= new   int [n+1];Y.a=a;Y.n=n;Y.cn=0;Y.bestn=0;Y.bestx=v;Y.Backtrack(1);delete  [] Y.x;cout<< "最大团的顶点数:" <<Y.bestn<<endl;
}
int  main()
{int  n;cout<< "please input number of node:" ;cin>>n;//int   a[n+1][n+1]; //由于定义的是int **a,且采用的是二维数组传参,因此 int  **a= new   int  *[n+1];  //两种解决方法,一是给定第二维的大小,二是通过 for ( int  k=0;k<=n;k++)  //动态分配内存,这里采用了动态内存分配解决问题 a[k]= new   int [n+1];for ( int  i=0;i<n+1;i++)for ( int  j=0;j<n+1;j++)a[i][j]=0;int  edge;cout<< "please input number of edge:" ;cin>>edge;cout<< "please input edge:" <<endl;int  v,w;for ( int  x=0;x<edge;x++){cin>>v>>w;a[v][w]=1;a[w][v]=1; } int  *p= new   int [n+1];MaxClique(a,p,n);system( "pause" );return  0;
}

测试

当输入图:

输出:

参考资料

回溯法实验(最大团问题) https://wenku.baidu.com/view/fdb2875fe418964bcf84b9d528ea81c758f52e32.html

C代码实现2

#include <iostream>
using namespace std;
int m[101][101];//有向图的邻接矩阵
int x[101];//当前团的解
int bestx[101];//最优解
int n;//表示图的顶点数
int cn=0;//当前团的大小
int bestn;//当前最优值
void getbestn(int i)
{if(i>n){//递归出口,到根节点时,更新最优值和最优解,返回bestn=cn;//更新最优值for(int j=1;j<=n;j++)bestx[j]=x[j];return ;//返回}x[i]=1;//先假定x[i]=0;for(int j=1;j<i;j++){if(x[j]==1&&m[i][j]==0){x[i]=0;//如果该点与已知解中的点无边相邻break;//则不遍历左子树}}if(x[i]==1){//当且仅当x[i]==1时,遍历左子树cn++;//该点加入当前解getbestn(i+1);//递归调用cn--;//还原当前解}x[i]=0;//假定x[i]==0if(cn+n-i>bestn){//如果当前值+右子树可能选择的节点<当前最优解,不遍历左子树x[i]=0;getbestn(i+1);}return ;
}
int main()
{printf("输入图的顶点数:\n");scanf("%d",&n);//输入图的顶点数//输入图的邻接矩阵printf("输入图的邻接矩阵:\n");for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)scanf("%d",&m[i][j]);//求最优解getbestn(1);//输出最优值printf("最优值:%d\n",bestn);//输出for(int k=1;k<=n;k++)if(bestx[k])//输出最优解printf("最优解:%-2d",k);printf("\n");return 0;
}

测试

参考资料

最大团问题回溯法求解 https://blog.csdn.net/practical_sharp/article/details/102791951

更多

  • 回溯法-最大团问题 https://www.jianshu.com/p/99ed0f46b94c
  • 算法java实现–回溯法–最大团问题
    https://blog.csdn.net/lican19911221/article/details/26228345
  • 算法设计与分析——最大团问题(回溯法) https://www.cnblogs.com/wkfvawl/p/11923848.html
  • 第五章【回溯法】最大团问题和图的m着色问题 https://blog.csdn.net/weinierbian/article/details/50379376

最大团问题(迭代回溯法)相关推荐

  1. 回溯法(算法分析与设计)

    0.回溯法的算法框架 A.简介 回溯法,又称试探法.一般需要遍历解空间,时间复杂度概况:子集树Ω(2^n),排序树Ω(n!),暴力法 B.回溯法解题三步骤 1)定义问题的解空间 如0-1背包问题,当n ...

  2. [XJTUSE 算法设计与分析] 第五章 回溯法

    第五章 回溯法 填空题会有代码填空,大题会手动回溯 学习要点 理解回溯法的深度优先搜索策略. 掌握用回溯法解题的算法框架 (1)递归回溯 (2)迭代回溯 (3)子集树算法框架 (4)排列树算法框架 5 ...

  3. 0027算法笔记——【回溯法】回溯法与装载问题

    1.回溯法 (1)描述:回溯法是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法.  (2)原 ...

  4. c语言实现判断两个子图是否同构问题_经典问题-回溯法-最大团问题

    1. 知识点 注:用回溯法实现最大团问题和用回溯法实现装载问题,解决方案和复杂度是类似的.如果你对回溯法或者子集树问题,并不了解,可以参看一下这篇文章,里面补充了回溯法和子集树的概念. 装载问题-回溯 ...

  5. 回溯法之递归回溯和迭代回溯

      回溯法有通用解题法之称,它可以系统的搜索一个问题的所有解或者任意解.它在问题的解空间树中,按深度优先策略从根节点出发搜索解空间树,算法搜索至解空间树的任意一个结点时,先判断该节点如(子树)是否包含 ...

  6. 回溯法--最大团(部队护卫队问题)

    package com.duoduo.day316; /*** 回溯法--最大团问题* 问题描述:为组织一支队伍,希望选出最多的居民加入队伍中,并保证其中任意两人均不是仇敌,给定仇敌关系图,计算构建护 ...

  7. 回溯法——最大团问题

    回溯法--最大团问题 问题: 给定无向图G=(V,E).如果U∈V,且对任意u,v∈U有(u,v)∈E,则称U是G的完全子图. G的完全子图U是G的团当且仅当U不包含在G的更大的完全子图中. G的最大 ...

  8. 回溯算法背包问题迭代c语言,回溯法解决0_1背包问题(迭代和递归)

    问题:0/1背包问题 例子:weight数组代表物品重量,value数组代表物品价值,M代表背包容量.背包是按单位价值递减的顺序排列的,即value[i]/weight[i]>value[i-1 ...

  9. 【算法分析】实验 4. 回溯法求解0-1背包等问题

    目录 实验内容 实验目的 实验结果 步骤1:描述与分析 步骤2:策略以及数据结构 步骤3 步骤4 步骤5 步骤6 实验总结 实验内容 本实验要求基于算法设计与分析的一般过程(即待求解问题的描述.算法设 ...

  10. 回溯法 -数据结构与算法

    1.回溯法算法思想: 定义: 回溯法(探索与回溯法)是一种选优搜索法,按选优条件向前搜索,以达到目标.但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术 ...

最新文章

  1. 3.4. Wireless Networking
  2. 51nod 2497 数三角形
  3. staruml无法打开mdj文件_StarUML使用说明
  4. 工业互联网工信部苗圩谈-谋定研究:对话中国经济和信息化
  5. VTK:PolyData之ColorCells
  6. Mysql迁移到Oracle方法
  7. 【BZOJ1042】硬币购物(动态规划,容斥原理)
  8. 什么时候我们应谈及性能?
  9. 执行远程服务器上的脚本失败?(环境变量引起的问题)
  10. 通过YAJL生成json语句
  11. 草根站长的你是感觉自豪还是苦逼
  12. 上传,修改头像的使用
  13. 持续交付+springboot+k8s
  14. 文件管理系统:5款优秀的文档管理系统
  15. 360数科知微实验室发布反诈报告:揭秘黑灰产数据流转真相
  16. C语言中-条件编译#ifdef的妙用详解_透彻
  17. 终日乾乾,与时偕行——2022年度吴文俊人工智能最高成就奖:郑南宁院士
  18. Windows下安装 Smarty
  19. angular技巧_提升Angular技能的5个技巧
  20. 滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(7月29日)...

热门文章

  1. 网易面试总结——面试案例1~面试案例4
  2. 《领导力与沟通艺术》
  3. 龙芯 python_在UOS20-龙芯(MIPS64EL)上安装 opencv-python
  4. Long-distance navigation and magnetoreception in migratory animals(迁徙动物中的长距离导航和磁感应)...
  5. Java - JDBC Best Practices
  6. Python——OCR识别
  7. 外网无法访问花生壳域名的解决方法
  8. SAP中一次性客户及供应商的应用浅晰
  9. linux命令cd 什么意思,Linux命令 cd ./.是什么意思
  10. 网上车管所办理驾驶证补证换证