1.图:由点、边(点与点之间连线),组成的集合,如点集V=[0,1,2,3,4],边集E=[[1,3,4],[2,3,4],[4],[4],[]],则(V,E)就是一个图,其表达的意思如下:

该图中含有5个端点,分别为0,1,2,3,4,这些点存在V中,如端点1对应V[1]=1端点之间会连着线,称为边,如1和2之间连的边,就对应E中E[1]=[2,3,4]的元素2,如0和4之间连的边就对应E[0]=[1,3,4]含有元素4(E[4]=[]不含元素0是因为0<4,只需在E[0]中记录了4即可)

2.团:一个图可能会有多个团,团是V的子集,记为集合G,且保证G中任意两点之间都有连线如G=[1,3,4],其中1,3,4三点两两相连,一个图的包含元素最多的团称为最大团。

最大团问题网上的求解办法非常多(本身其实这是一个NP问题),这次比较特殊的地方是要求使用Python,而且如果有多个解要输出多个具体的解(也就是说中间结果要记录),总之题目描述就是:

输入:V,E

输出:最大团数目,最大团集合(如果有多个要求全部输出)

采用动态规划的思想就是将问题分段求解,可以将问题分为5段:求含有一个、两个、三个、四个、五个元素的团,其中含有N元素的团必包含含有N-1个元素的团,故只需在上一段问题的答案的基础上,尝试给团添加新的元素。

另外,实际上例如求解出两个元素的团,如本题中的[0,1],[0,3],[0,4],[1,2],[1,3],[1,4],[2,4],[3,4]时,已经裁掉了[0,2],[2,3]的下面的解了,所以也算有一点剪枝的意思。接下来直接看代码实现:

#-*- coding=utf-8 -*-  V=[0,1,2,3,4]
# E=[[1,3,4],[2,4],[4],[4],[]]
E=[[1,3,4],[2,3,4],[4],[4],[]]  ###较小规模的最大团问题
import copy  def isConnected(u,v):  if u==-1 or v==-1:###虚拟节点-1与所有的节点都相连  return 1  edge_points=E[u]  if v in edge_points:  return 1  else:  edge_points = E[v]  if u in edge_points:  return 1  else:  return 0  def isConnectedAll(clique,v):#判断v是否和clique中所有节点相连  flag = 1  for i in clique:  if not isConnected(i,v):  flag =0  break  return flag  class Step:  def __init__(self):  self.maxClique = [] #计算完毕时的解集(每个阶段的实际结果)  self.cliqueList = []#计算时用的解集  self.maxnC = 0  def maxCliqn(self):#计算当前阶段最大值  max = 0  for clique in self.cliqueList:  if max < len(clique):  max = len(clique)  return max  def isNew(self,clique): #判断一个解组合是否已经存在于该阶段的实际解集中  for cl in self.maxClique:#针对每个已存入的解集进行判断  diff = list(set(clique).difference(set(cl)))  # 取解的差集  if (len(diff)):  continue      #差集不为空,说明不同,继续循环  else:  return False  # 差集为空,说明有个解完全一样,返回False return True  def updateMaxClique(self):#更新当前阶段的最大团数目  self.maxnC= self.maxCliqn()  for clique in self.cliqueList:  if(len(clique)==self.maxnC):  if self.isNew(clique):  self.maxClique.append(clique)  if __name__ == "__main__":  n = len(V)  solutions = {}  for i in range(0,n):  solutions[i]= Step()    #初始化n个阶段  for v in V:  a = []  a.append(v)  solutions[0].cliqueList.append(a)  solutions[0].updateMaxClique()#设置初始值  for i in range(1,n):  #cliqList= solutions[i-1].maxClique  preData = solutions[i-1]  cliqList = preData.maxClique  preMax = preData.maxnC  for clique in cliqList:#针对前一阶段的每个clique求解  for v in V:#针对所有的点  tempclique = copy.deepcopy(clique)##必须使用深拷贝  if not v in tempclique:#如果该clique没有包含v  if isConnectedAll(tempclique,v):#如果v与clique的所有点相连  tempclique.append(v)#加入该点  solutions[i].cliqueList.append(tempclique)#加入这个解  solutions[i].updateMaxClique()  if not len(solutions[i].maxClique):#如果已经找不到更多的点加入团,那么后面的也不用计算了(比如找不到4个的团,那么5个的团也没必要再尝试计算)  break  for i in range(0,n):  print("step"+str(i)+": "+str(solutions[i].maxClique))  for i in range(n-1,-1,-1):  solution = solutions[i]  if len(solution.maxClique):  maxn = solution.maxnC  print("最大团数目是"+ str(maxn)+"个")  print("最大团为:")  print(solution.maxClique)  break  

值得注意的一点是,python里面直接用赋值符号得到的对象实例是使用的浅拷贝,跟java类似,所以要使用copy模块的deepcopy函数来建立临时列表做各种判断以及修改添加(因为我也对python不太熟悉,而且原来没仔细考虑过拷贝引用带来的问题,中间错了好一阵)。

输出:

V=[0,1,2,3,4]
E=[[1,3,4],[2,4],[4],[4],[]]

step0: [[0], [1], [2], [3], [4]]
step1: [[0, 1], [0, 3], [0, 4], [1, 2], [1, 4], [2, 4], [3, 4]]
step2: [[0, 1, 4], [0, 3, 4], [1, 2, 4]]
step3: []
step4: []
最大团数目是3个
最大团为:
[[0, 1, 4], [0, 3, 4], [1, 2, 4]]

E=[[1,3,4],[2,3,4],[3,4],[4],[]]

step0: [[0], [1], [2], [3], [4]]
step1: [[0, 1], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
step2: [[0, 1, 3], [0, 1, 4], [0, 3, 4], [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]
step3: [[0, 1, 3, 4], [1, 2, 3, 4]]
step4: []
最大团数目是4个
最大团为:
[[0, 1, 3, 4], [1, 2, 3, 4]]

E=[[1,3,4],[2,3,4],[4],[4],[]]

step0: [[0], [1], [2], [3], [4]]
step1: [[0, 1], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4], [2, 4], [3, 4]]
step2: [[0, 1, 3], [0, 1, 4], [0, 3, 4], [1, 2, 4], [1, 3, 4]]
step3: [[0, 1, 3, 4]]
step4: []
最大团数目是4个
最大团为:
[[0, 1, 3, 4]]

其他的也没怎么测试了,如果有bug,各位读者看着改改吧= =。提供一个思路,仅作参考。

类动态规划求解较小规模的最大团问题(Python实现)相关推荐

  1. 使用动态规划求解算法问题的五大特点总结(附基于Python的参考代码)

    什么样的问题应使用动态规划求解 前言 一.求"最"优解问题(最大值和最小值) 1. 乘积最大子数组 问题描述 示例 题目分析 参考代码 2. 最长回文子串 问题描述 示例 题目分析 ...

  2. 区间类动态规划(dp)

    一.问题引入 给定长为n的序列a[i],每次可以将连续一段回文序列消去,消去后左右两边会接到一起, 求最少消几次能消完整个序列,n≤500.与线性模型不同,这里消去的顺序是任意的,且消完后左右会接起来 ...

  3. python实现动态规划求解给定矩阵的和最大的子数组(矩阵中数字正负均存在)

    本篇博文比较简单没有太多实际意义,只是为了练习一下,动态规划我并不熟悉,也是刚处于学习的阶段. 问题: 给定一个指定的矩阵,维数小于1000,在矩阵的所有子数组中寻找具有最大和的子数组求和输出. 思路 ...

  4. 1008-----算法笔记----------0-1背包问题(动态规划求解)

    1.问题描述 给定n种物品和一个背包,物品i的重量是wi,其价值为vi,背包的容量为C.问:应该如何选择装入背包的物品,使得装入背包中物品的总价值最大? 2.问题分析 上述问题可以抽象为一个整数规划问 ...

  5. 子串、子数组与子序列类型问题的动态规划求解(Leetcode题解-Python语言)

    一般来说,子串和子数组都是连续的,而子序列是可以不连续的,遇到子序列问题基本上都是用动态规划求解. 53. 最大子数组和(剑指 Offer 42. 连续子数组的最大和) class Solution: ...

  6. 提高篇 第五部分 动态规划 第1章 区间类动态规划

    https://blog.csdn.net/guoyangfan_/article/details/81162689 动态规划(四)--区间型动态规划_布纸所云-CSDN博客 [算法详解]区间动态规划 ...

  7. 提高篇 第五部分 动态规划 第4章 状态压缩类动态规划

    例1 骑士(Sgu223) 1592:[例 1]国王 信息学奥赛一本通(C++版)在线评测系统 https://blog.csdn.net/guoyangfan_/article/details/82 ...

  8. python用动态规划求删除路径_Python | 动态规划求解TSP

    解题思路主要有两部分: i为当前节点(城市),S为还没有遍历的节点(城市集合),表示从第i个节点起,经历S集合中所有的点,到达终点的最短路径长度. 回溯找到最优的路径,需要将S集合一一对应一个数字(类 ...

  9. 动态规划求解所有字符的组合数

    一,问题描述 给定若干个字符,求解 这些字符能够表示的最多组合个数.比如{'a','b','c'} 一共有七种组合.(每种组合没有重复的字符 且 组合的种数与顺序无关,如 ab 和 ba 是同一种组合 ...

  10. 01背包问题 动态规划求解方法 动态方程的详细解释 能理解的解释(附python代码)

    01背包问题属于组合优化问题:假设你要出门旅游,你现在有一个书包,这个书包的容量(capacity)有限,有很多物品如牙刷.防晒霜.雨伞.水杯等等,但书包装不下所有物品,因此我们必须有所取舍.那么通常 ...

最新文章

  1. 单端测序(Single end)和双端测序(Pair end和Mate pair)
  2. Linux 内核详解以及内核缓冲区技术
  3. 磁盘 I/O 的概念
  4. 构建之法第四章读后感
  5. 韩国讨论到 2020 年拥抱开源操作系统
  6. android8camera,[Android8.0/9.0/10]Camera:外接 USB 摄像头
  7. 选择比努力更重要,面试新公司,从哪些细节能判断公司的前途?项目的好坏?...
  8. pat 乙级 1018 锤子剪刀布(C++)
  9. 在CentOS6.5上安装Tomcat6
  10. dpkg命令_Linux 命令学习神器!命令看不懂直接给你解释!
  11. (转)认识原型对象和原型链
  12. python 用户登录判断
  13. 全栈工程师可以分为哪几类?
  14. Android File存储
  15. ADL之UI初预览 AJAX 开发
  16. 8款功能强大的最新HTML5特效实例
  17. 一篇文章带你大致了解5G关键技术、协议架构、网络优化覆盖、业务测试与验证
  18. java中 是什么意思_java中?:是什么意思
  19. 学计算机r7000和y7000哪个好,联想拯救者r7000p和y7000p哪个好-联想拯救者r7000p和y7000p评测对比...
  20. CSAPP实验2:bomblab

热门文章

  1. 计算机主板常见故障检修,主板常见故障检查与维修
  2. 类似911的代理ip,911代理的官网,yilu代理软件,911s5替代软件海外代理平台哪里有?
  3. 如何用LOTO示波器TDR方法测试电线长度?
  4. web前端开发分享-css,js进阶篇
  5. 计算机网络工资如何计算,2019 税后工资计算器,能够准确算薪
  6. Zabbix 3.0 监控Web [七]
  7. PHP序列化与反序列化
  8. 【HTB系列】靶机Chaos的渗透测试详解
  9. leetcode-739.每日温度-单调栈
  10. TeamViewer突破地域限制,解决办公难题