最近在做子图匹配算法的相关优化工作,发现core结构在量化子图结构方面比较常用,现总结如下。
基本概念
在图(Graph)模型中,常常会有一些概念用来描述图的某些特征,core就是其中之一。core主要用来描述图中点之间的紧密(cohesive)程度,core的定义为:
设有简单无向图G = (V, E),其中V为点集,E为边集,∃S = (V', E'),V'⊆V, E'⊆E,∀v∈V' d(v) >= k, 且不存在u∈V - V',使得∀v∈V'∪{u} d(v) >= k, 则称S为k-core,其中d(v)表示v的度数(与点v相连的边数,下同)
用白话说就是如果图G中的存在一个最大子图S,S里面的点的度数都大于等于k,则称子图S为k-core,k称为 core S 的阶数
下图为k-core的一个例子:
从上图的例子中我们可以发现:
- k-core一定是 (k-n)-core (k>=0, n <=k),比如2-core一定是1-core,也一定是0-core
- k-core不一定是连通图
那么k-core有什么用呢?其最常见的应用就是挖掘社交网络中用户之间的紧密程度。如在下图所示的社交网络中,可以把每一个用户当作一个点,用户之间如果有联系的话就用一条边将他们连接起来,这时,k-core就可以用来挖掘这个社交网络中那些互相之间联系紧密的用户群体。
在实际应用中,我们通常更关心图中每一个点的core-value (又被称为core-number),什么是core-value呢?就是该点所在的最高阶的core,用白话说就是如果一个点 v 可以在k-core中,但是却无法在 (k+1)-core 中,则称点v的core-value为k,记作 v.core-value = k
设图G中最大的core-value为x, 则我们把图G中[0,x]-core都找出来称为图G的core分解,通常情况下我们只需要得到图G中每一个点的core-value即可。
下面我将介绍图core分解的经典算法
基础算法
首先,我们可以想象一下如果要计算core-value的话,图中哪一个点的core-value是最容易计算的?我们可以从定义入手,定义要求k-core中任何一个点的度数都要大于等于k,这个其实等价于k-core中最小度数的点的度数要大于等于k,据此我们可以尝试先从图中最小度数的点开始算起。
设图G中最小度数的点为v,因为点v是图G中度数最小的点,那么v肯定也是图G任意子图度数最小的点(图G中没有度数比v更小的点),也就是说任意包含点v的子图,core的最高阶数一定是d(v),因为子图中其他的点的度数都大于等于d(v),此时子图中的所有点一定是都在d(v)-core里面的,同时由于v点自身度数的限制,v点是一定不能在 (d(v)+1)-core 里面的,这个时候我们就直接得到了点v的core-value是d(v),即 v.core-value = d(v)
在我们得到了点v的core-value之后,我们可以把图G分为两个部分,一个是与点v连通的部分,另一个是与点v不连通的部分。
- 与点v不连通的部分
与点v不连通的部分很简单,我们可以继续在不连通的部分选取度数最小的点,然后按处理点v的方式对这个点进行处理即可。
- 与点v连通的部分
在与点v连通的部分,我们又可以将里面的点分为两种类型,一种是度数等于d(v)的点,另一种是度数大于d(v)的点(不可能存在度数小于d(v)的点,因为v是图中度数最小的点)。
- 度数等于d(v)的点
对于度数等于d(v)的点,我们可以直接得到这些点的core-value也等于d(v),理由与得到v.core-value的理由一致。
- 度数大于d(v)的点
对于度数大于d(v)的点,为了方便表述,我们不失一般性地设在与点v相连的这部分子图中有点u,且d(u) > d(v),即u是度数大于d(v)的点,那么既然我们都已经明确地知道了u的度数一定是大于d(v)的,那么是不是也意味着u.core-value也一定是大于d(v)的呢?答案其实是否定的,我们可以考虑一个极端情况:除了u以外,其他点的度数都是d(v),这时,u.core-value 也等于 d(v),因为此时如果包含点u的core里面存在其他的点,core的最高阶数只能是d(v),而如果包含点u的core里面只有点u一个点,那么此时core的阶数只能是0,按照core-value取最高阶数的定义,即这种极端情况下u.core-value = d(v)。那么u.core-value有可能大于d(v)吗?答案是肯定的,我们考虑另一种极端情况:除了点v以外,其他点的度数都是大于d(v) 的且点v的邻居点(与点v直接相邻的点)的度数是大于d(v) + 1的,在这种情况下,我们只需要将包含点u的core把点v排除在外即可,这时剩下的点度数都是大于d(v)的,所以u.core-value也一定是大于d(v)的。通过上面的分析我们可以发现,对于度数大于d(v)的点,我们是无法直接确定它们的core-value的,需要进行进一步地搜索。
那么我们该如何进行进一步地搜索呢?通过上