稠密子图算法分析(2022阅读论文总结)

792 阅读19分钟

注:每一小节的“来源”注明了该小节的内容出处,大部分是论文,小部分出自图书。

k-core

定义

k-core是一个极大子图,图中每个顶点的度数k\geq k

性质

(1) k-core的划分是唯一的

(2) 每个顶点有唯一的core-number,代表包含该顶点的最大core

(3) k+1-core一定是k-core的子图

image.png

算法

Peeling算法

一、来源:Cohesive Subgraph Computation over Large Sparse Graphs 3.2.1节

二、功能:计算出每个顶点的core-number,从而达到core划分的目的。

三、原理:维护一个“当前core-number”,设为max_core。每次循环找到当前图中度最小的点u,如果u的度数小于或等于max_core,则u的core-number就是max_core,否则设置max_core为u的度数。更新完u的core-number后将u从图中删去,并更新u的邻居的度数,然后重复循环直到图中所有的顶点都被删除。

image.png

线性堆优化的Peeling算法

一、来源:Cohesive Subgraph Computation over Large Sparse Graphs 2.1节

二、原理:Peeling算法中需要不断找到度最小的元素,并将它删去,这个本可以用小根堆实现,但删除元素的同时会改变其他元素的大小,因此普通的小根堆就无法实现了,需要用到线性堆。

这本书中提到的线性堆其实就是一个keys为所有可能度——即0到N——的哈希表,解决冲突的方式是链表。下面两图展示了一个无向图和构造对应线性堆的一个例子。

image.png

image.png

线性堆的操作包括插入、删除、单个元素修改、查询最小元素,需要维护max_key和min_key表示当前最大和最小的键值,上图中max_key=4,min_key=1。

(1) 插入(类似链表的插入,插入在对应键值的头部):

image.png

(2) 删除(类似链表的删除):

image.png

(3) 单个元素的键值修改:

其实是分两步进行,先把该元素在哈希链表中删除,然后将更新键值的元素再插入到哈希链表中。

image.png

(4) 查询最小元素并删除它:

首先要更新min_key,找到min_key后在min_key对应的链表中随便选一个元素都是最小元素,这里直接选取了表头。

image.png

结合线性堆,Peeling Algorithm的时间复杂度可以降到O(E)O(|E|)

针对特定的k求解k-core的算法

一、来源:Cohesive Subgraph Computation over Large Sparse Graphs 3.2.2节

二、原理:由于只需要计算特定的k——而不是所有可能的k——对应的k-core,因此可以不用线性堆而是BFS的方法求解。构造一个队列Q,初始时队列中存放所有度小于k的顶点(顺序无所谓),然后做BFS,终止条件是Q为空,每次弹出Q队首元素u并将它从队列中删去,同时将u的邻居度数-1,并判断该邻居更新后的度数是否小于k,如果小于k则把它加入队尾。

image.png

Core Hierarchy Tree

一、来源:Cohesive Subgraph Computation over Large Sparse Graphs 3.2.3节

二、功能:k-core的划分并没有考虑连通性信息,即对于任意k、k-core都有可能是不连通的,core hierarchy tree可以快速找到k-core的每个连通分量

三、原理:

由于k+1-core必定被包含在k-core中,所以k+1-core的各个连通分量也一定是某个k-core的子图。

基于这个特点,可以构造一棵Core Hierarchy Tree。对于Tree中的任意子树,这棵子树表示某个连通的k-core,子树的根节点是一个set、该集合包含了所有该连通k-core中core-number恰好为k的顶点,这个根节点有若干个儿子节点,每个儿子节点又是一棵子树的根节点、每棵子树分别是该连通k-core中的每个连通的k+1-core……以此类推可以看出Core Hierarchy Tree的全貌:

image.png

image.png

构造Core Hierarchy Tree需要用到并查集,在构造之前需要用前文提到的Peeling Algorithm先计算出每个顶点的core-number。然后根据Peeling Algorithm中访问顶点顺序的逆序来构造新树,具体方法见下图(其实就是并查集的构造过程)

image.png

计算k-core的分布式算法

一、来源:Parallel and Streaming Algorithms for K-Core Decomposition

二、功能:用分布式并行算法计算k-core,但不能保证准确性(准确率用概率描述、近似算法)

三、原理:

(1) Approximate k-core

1ε1-\varepsilon approximate k-core:设某个子图HH满足vH,dH(v)(1ε)k\forall v\in H, d_H(v)\geq (1-\varepsilon)k,则HH是一个1ε1-\varepsilon approximate k-core

1ε1-\varepsilon approximate core-labeling:类似于core-number,每个顶点会被标记一个数字,这个数字称为1ε1-\varepsilon approximate core-labeling,它的数值是顶点真实的core-number和真实core-number乘以1/(1ε)1/(1-\varepsilon)之间的任意一个数

image.png

(2) 采样图:对每条边赋予一个概率,由概率决定这条边是否被选取,这种通过概率构造出的子图HH就是采样图

(3) 近似算法基本原理:如果在子图GG'中顶点v的core-number大于某个数值ll,则可认为v在原图GG中core-number为LL

四、算法步骤:

step1:以p为采样概率构造一个采样图HH

step2:计算HH中每个顶点在HH的core-number,根据原理(3),可以得到一些顶点在原图GG中的core-number

step3:将step2中得到原图GG中core-number的顶点删去,然后将采样概率p翻倍,回到step1

image.png

image.png

分布式并行方法:采样阶段,将原图划分为若干部分,每个部分交给一个处理器进行采样。计算符合原理(3)在子图中core-number高的顶点在原图中的core-number时采用集中式处理,具体见下图,

image.png

Colorful Star k-core

一、来源:Colorful h-star Core Decomposition

二、功能:定义了一种全新的core结构,即“colorful h-star core”,并给出了在无向图中划分这种core结构的方法。

在定义colorful h-star core之前,首先要给出两个前置定义:

(1) linear time greedy colorful algorithm

将所有顶点按度的降序排列,然后依次尽可能小编号的颜色染色,每次染色要保证和相邻的已经染色顶点颜色不相同。

举例

image.png

(2) h-star

在使用线性贪心染色算法的前提下,由一个中心节点连接h-1个其他节点的结构(这h个节点都有不同的颜色)称为h-star

举例

image.png

下面给出colorful h-star k-core的定义

(3) colorful h-star k-core

一个GG极大子图GG',满足GG'中每个顶点都在k个h-star中

三、原理&算法步骤:

设Group(i)={vNG(v)v\in N_G(v),color(v)=i},cnt(i)=|Group(i)|

DP(i,j)表示从前i个Group中选择j个不同颜色节点的方案数

(1) 计算单个节点的DP值

显然这是一个01背包问题

image.png

image.png

既然是01背包,就可以进行空间压缩,只用一维数组来做,只需要内层j的循环从大到小即可

image.png

(2) 某个节点删除时,更新其他节点的DP值

由于图可能会动态更新(即增加或删除节点),因此要考虑在更新时如何维护节点的DP值。在删除某个节点v时,cnt(color(v))会随之减小,因此它只会影响等式(1)中前半式("+"前的部分)代表的情况、即“选择color(i)”,而不会影响等式(2)中后半式代表的情况、即“不选择color(i)”。令F(i)和G(i)分别代表这两者的方案数,则有:

image.png

根据这一思路,可以得到具体算法:

image.png

在Counting阶段,可以认为被删的节点始终是颜色1(Line11),但在Updating阶段,被删的节点颜色是确定的color(v)(Line17)。

(3) colorful h-star k-core decomposition

Counting算法计算了每个节点的“彩色”度、即每个顶点被包含在几个h-star中。

Updating算法计算了删除某个节点后它的邻居的彩色度变化情况。

基于这两个算法、以及计算k-core的Peeling算法,可以得到colorful h-star k-core decomposition算法:

image.png

k-VCC

定义

k-Vertex Connect Component,指的是无向图G中的极大子图G',G'至少要删去k个顶点才能使G'变得不连通。

举例:下图中的G1,G2,G3,G4G_1,G_2,G_3,G_4都是4-VCC,因为它们都是至少删除4个顶点才会变得不连通

image.png

性质

以下性质皆来源于论文:Enumerating k-Vertex Connected Components in Large Graphs

(1)度小于k的顶点一定不在k-VCC中,因为删除它的所有邻居就能使得图变得不连通。由此可见k-VCC一定是k-core的子图。

(2)划分k-VCC的基本思路:不断找当前子图G'中小于k的割,将G'分为若干个子图,再在每个子图中继续找小于k的割并划分,直到划分出的子图不存在小于k的割,则每个子图都是一个k-VCC。以找4-VCC举例:

image.png

基本思路算法化:

image.png

(3)Sparse Certificate

定理:无向图GG是k-VCC当且仅当GG的Sparse Certificate是k-VCC

生成GG的Sparse Certificate方式如下:令G0=GG_0=G,然后总共进行k轮操作,第i轮操作在Gi1G_{i-1}上进行BFS,生成的搜索树记作FiF_i,则Gi=(V,E(Gi1)E(Fi))G_i=(V,E(G_{i-1})-E(F_i))。最后F1F2...FkF_1\cup F_2\cup ... F_k就是GG的Sparse Certificate。

举例

image.png

(4)找无向图中最小割的基本思路:任选一个源点u,一般选度最小的点,设最小割为SS,可以分两种情况讨论:

Case1:uSu\notin S,计算u和其他所有顶点之间的最小割。

Case2:uSu\in S,计算u的邻居之间的最小割。

具体算法如下;

image.png

算法

中心式的优化算法

一、来源:Enumerating k-Vertex Connected Components in Large Graphs

二、功能:高效找到无向图中所有的k-VCC

三、原理

(1) Neighbor Sweep 1

定义side-vertex,不存在一个小于k的割集S使得uSu\in S

aba\equiv b表示a和b之间有至少k条顶点不相交路径

关于side-vertex的三条性质:1.如果ab,bca\equiv b,b\equiv c且b是side-vertex,则aba\equiv b,2.如果u的任意两个邻居v,v'满足N(v)N(v)k|N(v)\cap N(v')|\geq k,则u一定是side-vertex且被称为strong side-vertex,3.如果(v,w)E(v,w)\in E,则一定有vwv\equiv w

根据以上3条性质可以得出优化策略:设u是源点,如果v满足1.uvu\equiv v,2.v是strong side-vertex,3.w是v的邻居。则w和u之间一定不存在小于k的割集

(2)Neighbor Sweep 2

GiG_i是G被割集S分割后的子图之一,则有以下两条性质:1.如果u在GiG_i中是strong side-vertex,则u在G中一定是strong side-vertex(它的逆否命题很有用),2.如果u在G中是strong side-vertex,且N(u)S=N(u)\cap S=\emptyset,则u在GiG_i中仍是strong side-vertex

基于这两条性质,在GiG_i中判断顶点是否是strong side-vertex时,只需要判断同时满足1.在G中是strong side-vertex、2.N(u)SN(u)\cap S\neq \emptyset的点。因为不满足这二者任一的点在GiG_i中一定不是strong side-vertex

(3)Neighbor Sweep 3

定理:设u是源点,如果v的邻居中有至少k个点满足uwu\equiv w,则有uvu\equiv v

定义:deposit(v)表示v的邻居中满足uwu\equiv w的顶点个数。

由此得到优化策略:给定源点u,如果顶点v满足deposit(v)>=k,则v和u之间不存在小于k的割

(4)Group Sweep

定义side-group:如果cc中任意两点u,v都满足uvu\equiv v,则cc是一个side-group。显然给定源点u后,如果uvu\equiv v,则和v同属一个cc的顶点必定和u之间不存在小于k的割集。

定理:构造sparse certificate时的bfs树FkF_k是cc

定义1:uccu\equiv cc,u与cc中任意顶点w满足uwu\equiv w。如果u与cc中至少k个顶点满足uwu\equiv w,则有uccu\equiv cc

定义2:g-deposit(cc),cc中与源点u满足uwu\equiv w的顶点w个数。g-deposit(cc)是一个动态更新的值,每当一个顶点v被判定为uvu\equiv v,就给v所在的cc更新g-deposit(cc)=g-deposit(cc)+1。

基于以上性质可得优化策略:给定源点u,如果g-deposit(cc)>=k,则cc中所有顶点和u之间都不存在小于k的割。

此外还有一个简单优化:设u是源点,如果u的两个邻居va,vbv_a,v_b同属一个cc,则vav_avbv_b之间不存小于k的割集

综合以上四条优化策略,可以得到综合后的算法:

image.png

image.png

image.png

分布式与中心式结合的k-VCC算法

一、来源:Towards k-vertex connected component discovery from large networks

二、功能:分布式的算法有很多优点,但完全用分布式算法找到图中的k-VCC比较困难,因此这篇文章提出了一个分布式和中心式结合的找出k-VCC的方法

三、算法步骤

image.png

image.png

STEP2:expand和merge种子图

(1)expanding

设G[S]是一个k-点联通子图,如果u和G[S]中至少k个顶点相连,则u可以加入到S中形成一个更大的k-点联通子图

(2)merging

设G[S]和G[S']都是k-点联通子图,如果SS+min{NS§(S§),NS§(S§)}k|S\cap S'|+min\{|N_{S'\S}(S\S')|,|N_{S\S'}(S'\S)|\}\geq k,则G[SSS\cup S']也是k-点联通子图

扩展后的种子图成为k-VCC的条件:设G[S]是一个k-点联通子图,如果G[S]满足1.不存在顶点v,v与S中至少k+1个顶点相连、2.min{δS,δGS|\delta_S|,|\delta_{G-S}|}<k(δS\delta_S表示S中在G-S中有邻居的顶点),则G[S]是一个k-VCC。

基于expanding和merging可以扩展种子图:

image.png

image.png

image.png

STEP3:继续合并扩展后的种子图

image.png

image.png

image.png

image.png

k-truss

定义

给定无向图GG,k-truss是指GG极大子图GG'GG'中的每一条边都满足边的两个端点有至少k-2个公共邻居

(k,h)-truss:和k-truss定义基本相同,只是将“公共邻居”改为“h跳公共邻居”

image.png

性质

(k,h)-truss和k-core有一些类似的性质

(1) (k,h)truss的划分是唯一的。

(2) 给定h后,数值大的(k,h)-truss一定是数值小的(k,h)-truss的子图

算法

(k,h)-truss划分算法

一、来源:Higher-Order Truss Decomposition in Graphs

二、功能:给定无向图,类似k-core划分一样对无向图进行(k,h)-truss划分。普通k-truss划分相当于h=1的特殊情况

三、具体算法

image.png

ϕτ(e,G)\phi_\tau(e,G)表示边e的truss-number,即包含边e的k值最大的(k,τ\tau)-truss

最简单算法(无优化):

image.png

(1) 优化思路一:延迟更新

image.png

image.png

image.png

(2)优化思路二:提前剪枝

对于e=(u,v)e=(u,v),如果dh(u)k1d_h(u)\leq k-1dh(v)k1d_h(v)\leq k-1,则必有ϕ(e)k\phi(e)\leq k。基于这个性质,在处理某条边时、可以计算它两个端点的h-hop degree,处理某个顶点时、如果dh(v)k1d_h(v)\leq k-1则与其相连的边在处理(k,h)-truss时可以跳过。

(3)优化思路三:Unchanged Support Dedection

image.png

结合优化思路后的算法:

image.png

image.png

k-clique

定义

cliqueclique)是一个无向图(undirected graph )的子图,该子图中任意两个顶点之间均存在一条边。

极大团 maximal clique是一个团,该团不能被更大的团所包含,换句话说,再也不存在一个点与该团中的任意顶点之间存在一条边。

团的大小 size是指一个团中包含的顶点数,size=k的团,称为k-clique

image.png

1-团有23个(点),2团有42个(边),3-团有19个(浅蓝色和深蓝色),4-团有2个(深蓝色),极大团有18个(11个3-团、2个4-团和5个2-团),最大团2个(深蓝色4-团)。

算法

最大团算法

一、来源:Parallel Maximum Clique Algorithms with Applications to Network Analysis and Storage

二、功能:找出一个无向图的一个最大团

三、原理:

(1) 设无向图G中最大团的大小(顶点个数)为w(G),G中度数最大的顶点度为D(G),最大的core-number为K(G),用贪心算法染色需要的颜色数为L(G),则必有

w(G)L(G)K(G)D(G)w(G)\leq L(G)\leq K(G)\leq D(G)

(2) 最大团一定被包含在某个顶点的邻域图中(v的邻域图指v和它的邻居们构成的导出子图)

(3) 在任意顶点v的邻域图GVG_V中,依然有

w(Gv)L(Gv)K(Gv)D(Gv)w(G_v)\leq L(G_v)\leq K(G_v)\leq D(G_v)

四、算法思路:

(1) 暴力求解-对每个顶点v,构造v的邻域图GvG_v,在GvG_v中找到最大团CvC_v,在所有的CvC_v中找出最大的,就是G的最大团。

(2) 在求邻域图GvG_v中的最大团时,并不是直接找到最优解,而是用启发式算法找到一个启发式的解HvH_v。具体方法是维护一个团HvH_v,初始是空集,然后按core-number的降序不断尝试向HvH_v中添加顶点,具体见下图:

image.png

这其中加入了优化:设当前最优解为HH,如果顶点uu的core-number小于H|H|,那么uu一定不可能被包含在最优解中

Algorithm1会得到一个启发式的解HH,根据这个解再去精确地求每个顶点邻域图中的最大团。算法地主干部分是这样的:先根据上一段中的优化删掉一些肯定不会被包含在最优解中的点,然后每次循环求当前图中度最小的点的邻域图,在一个顶点计算完成后将其标记而不是立即删去,在处理了一定数量的顶点后再批量地将顶点从图中删去(Line9)。具体可见下图,

image.png

INITIALBRANCH(u)是计算顶点u的邻域图中最大团的具体过程,这里用到了原理(3)中的三个限制条件,在判断出当前顶点u不可能被最优解包含时立即退出(Line13, Line16, Line19),如果三次检验都通过、即当前顶点u的邻域图中可能包含更优的解,则调用BRANCH具体计算u的邻域图中最大团,在调用时删除了一些必定不可能被包含在最优解中的点。具体算法见下图,

image.png

BRANCH(C,P)是计算某个顶点邻域图中的最大团,C是当前解,P是候选集,由于程序采用了递归的方式(Line29)并在循环中搜索了每个顶点(Line23),因此一定可以找到最优解。之所以比直接暴力求解效率高很多,是因为(1)通过Algorithm1的优化删去了很多顶点(2)通过原理3中的不等式删去了很多顶点。具体算法见下图:

image.png

并行方法:

(1) Algorithm1的并行方法很简单,将顶点分配给各个处理器,分别完成各自的工作量即可。

(2) Algorithm2中,首先主程序MAXCLIQUE充当任务分配器,构造一个任务队列和全局广播通道,将顶点分配给各个处理器。在各个处理器处理各自的任务时,每当有一个处理器计算出新的更优解、或删除一个顶点时,则通知其他所有处理器暂停当前的工作。

算法性能:

image.png

极大团算法

一、来源:维基百科Bron–Kerbosch algorithm

二、功能:找出无向图中所有的极大团

三、原理:

转自zhuanlan.zhihu.com/p/91398530

关于算法原理,谈一些个人理解。算法开始时,RR是空集,PP是顶点集;算法结束时, RR是最大团, PP是空集。搜索最大团的过程就是顶点vv从集合PP移动到集合RR的过程。

采用回溯策略的原因是,我们并不知道某个顶点vv最终是否是最大团中的成员。如果递归算法选择vv作为最大团的成员时,并没有找到最大团,那么应该回溯,并查找最大团中没有vv的解。

在递归的过程中,RR最终要形成一个最大团,RR的元素就是递归过程中当前找到的最大团的组成元素。PP是最大团的候选顶点集合,PP不断地去掉递归完成的顶点vv,在递归时取只在N(v)N(v)中的元素,因为最大团中的每个顶点之间是互相连接的,要找到的最大团的下一个顶点,一定是vv的邻接顶点。类似地,XX是回溯过程中被放弃的顶点的集合,递归过程中每次也只需关注N(v)N(v)的部分。

algorithm BronKerbosch1(R, P, X) is
    if P and X are both empty then
        report R as a maximal clique
    for each vertex v in P do
        BronKerbosch1(R ⋃ {v}, P ⋂ N(v), X ⋂ N(v))
        P := P \ {v}
        X := X ⋃ {v}

s-bundle

定义

设一个子图GG'有n'个顶点,对于一个正整数s(1sn1\leq s\leq n'),如果GG'是n'-s连通的,则称GG'是一个s-bundle

性质

image.png

image.png

算法

寻找图中最大s-bundle的算法

一、来源:An effective branch-and-bound algorithm for the maximum s-bundle problem

二、原理

三、详细算法

主程序MSB-Rec维护两个集合SSCC,分别表示当前解和候选集。SS^* 表示当前最优解

初始化:调用MSB-Rec(G,s,\emptyset,V),S=S^* =\emptyset

image.png

image.png

image.png

image.png

image.png

(3) Bounding算法

在第(1)部分提到,算法的核心思路是不断尝试将候选集CC中的顶点加入当前解SS,Bounding算法就是计算CC中能加入SS的顶点数量的上界,设这个值为q,如果S+q<S|S|+q<|S^* |,那么就不用详细计算把CC每个顶点加入SS后的情况了。

Color-bound:设G[C]G'[C]最少需要用k种颜色染色,把每种颜色的顶点归于一个集合,令P={C1,C2,...,CkC_1,C_2,...,C_k},则CC中s-bundle顶点个数的上限是i=1kmin{Ci,s}\sum_{i=1}^{k}min\{|C_i|,s\}

Color-bound具体方法:

step1:初始令k=1

step2:新开一个CkC_k,不断将CC中和CkC_k中顶点不相邻的点加入CkC_k,直到找不到这样的点。

step3:令C=CCkC=C-C_k,如果C不为空,则令k=k+1并返回step2。如果CC为空,则根据前文所述的原理得到CC中s-bundle大小的上界。

degree-bound:简单运用Property 4,给定图G'=S+C,设图CC中度最大的顶点的度为ΔG(C)\Delta_{G'}(C),则G'中s-bundle大小的上界是ΔG(C)+s\Delta_{G'}(C)+s

(4) reduction算法

bounding算法是最优性剪枝,reduciton算法则是可行性剪枝

剪枝1: image.png

剪枝2:如果NG(v)+s<S|N_{G'}(v)|+s<|S^* |,则v不可能存在于包含S的s-bundle中,寻找大于S|S^* |的最优解时可以不考虑v

剪枝3:设vCv\in C

image.png

image.png

综合以上算法基本框架和剪枝,可以得出最终的优化算法:

image.png