zoukankan      html  css  js  c++  java
  • 极大团(maximal clique)算法:Born_kerbosch算法

    不了解极大团(maximal clique)的,请看极大团这篇文章

    参考资料:

    Bron_Kerbosch算法

    团、极大团、最大团介绍

    当给出一个图后,我们应该怎么去寻找其中的极大子团呢?

    寻找极大子团的最简单的思想是:

    1.生成原始图的所有子图(可能的子图有2*n个,n代表顶点个数)

    2.判断这些子图是不是团

    3.将不是极大团的团删除

    Born_Kerbosch算法

    这个算法主要构造三个集合:

    R集合:存储当前极大团中加入的顶点

    P集合:存储可能还加入的点

    X集合:存储的是已经假如过某个极大团的点(作用是判重,因为会从每个顶点开始,枚举所有团,如果不对已经加入到某个极大团的顶点进行标记,可能会有重复极大团的出现)

    基础Born_kerbosch算法

    1.对于任意一个在集合P中的顶点V,我们把V加入到R集合(集合P中的每一个顶点均与R集合中所有的点是连接的,所以加入顶点V后,依然能保证集合R是个团),然后对在P集合中且与V相连的这部分点中,寻找下一个可能加入到R集合的点。(意思就时加入点v至R集合后更新P集合,使P集合中的任意一个点依然能和R集合中每一个点都是连接的。因为这里新R集合中加入了V,所以只要是原p集合中且与v顶点相连的这些顶点就是与新R集合中所有顶点相连)

    2.回溯时把顶点V从P中移除并加入到X集合,表示在当前状态下包含顶点V的极大团已经计算完毕。

    3.R集合为极大团时,必须满足P与X都是空的。P存放的是还可能加入到极大团R中的点,P集合为空表示已经没有点能加入到R中了。而X中存放的是已经完成极大团计算的点,且X集合中的任意一个点必然是与R中每个顶点都连接(因为我们每次向下dfs时,还对P和X分别进行取与R集合内都连接的操作来保证,而且X中的点就是从R中取出的点,当然会和R集合中的每个点都连接),即X中的点必然可以和R集合构成极大团。如果X集合不为空的话,可以把X的点加入到R集合中从而构成一个团R1,R1的顶点数大于R,说明R就不是一个极大团,R1集合中的极大团是之前计算包含x集合中的点的极大团的时候计算过了的,故当且仅当P、X集合都为空时R才是一个极大团。

    算法图例

    Born_Kerbosch算法的优化

    在上面这个方法中,我们进行了许多不必要的判断,例如在我们找到了极大团{1、2、3}之后,依然去对{1、3},{2、3},{3}这些团进行了判断,然而这些显然不是极大团。所以现在考虑的是对其进行优化,使程序不用进行不必要的递归。
    当我们将一个结点u,放入到R集合后,再取下一个结点,取的必然是u的邻居结点(因为再更新P和X时,会将不是邻居结点的结点都过滤掉)。通俗的讲就是如果取完u之后我们再取与u相邻的点v也能加入到极大团,那么我们只取u就好了,因为我们由u开始递归,已经找到了u及其邻居结点v等等结点构成的极大团了,没有必要再去从v开始寻找极大团,这会增加不必要的计算。至于v可能可以其他结点构成另一个极大团,如果这个极大团包括了u,那么由u开始就已经找到了这个极大团了;如果这个极大团不包括u,那说明这个极大团里面一定存在和u结点不相连的结点k,那没必要从v开始寻找这个极大团了,从u的非邻居结点k开始,一样可以找到这个极大团。这样对u及其邻居结点构成的极大团,只需要从u开始寻找一次就可以了,接下来就直接从u的非邻居结点k开始寻找极大团,这样可以减少许多不必要的计算。
  • 相关阅读:
    网友心得 说说.NET中的反射(转帖)
    javascript的函数(转)
    asp.net基于窗体的身份验证
    创建ASP.NET WEB自定义控件(转)
    .net调用Oracle存储过程
    写字间里程序员
    世界四大杀毒软件调侃
    技巧/诀窍:在ASP.NET中重写URL(转)
    VS2008中JavaScript编辑调试器的秘密
    如何用C#语言构造蜘蛛程序
  • 原文地址:https://www.cnblogs.com/lfxiao/p/12501744.html
Copyright © 2011-2022 走看看