社交或是其余网络一般能够用图来表示,即G=(V,E),其中V表明图中全部节点的集合,E表明图中全部边的集合。本文讨论的是无向图。咱们先对图中一些基本概念的表示以下: git
n github |
节点的个数 算法 |
m 网络 |
边的条数 app |
w(s,t) spa |
节点s,t之间边的权重。对于无向无权重图,全部的w(s,t) = w(t,s) =1 .net |
dG(s,t) 队列 |
图G中两节点s,t之间最短路径的长度,即为这条最短路径上全部边的权重之和。同时dG (s,s)=0,无向图中dG (s,t) = dG (t,s) ip |
σst ci |
图G中两节点s,t之间最短路径的条数。同时σss =1,无向图中σst =σts |
σst(v) |
图G中两节点s,t之间的全部最短路径中通过节点v的条数 |
δst(v) |
即σst(v)/σst,表示点对s、t对节点v的pair-dependency |
Ps(t) |
从节点s到节点t的最短路径上,节点t的前哨节点集。若v∈Ps(t),则表示从节点s到节点t的某条最短路径上,最后一步是经过v到达t的 |
图中各个节点的重要性能够经过节点的中心性(Centrality)来衡量。在不一样的网络中每每采用了不一样的中心性定义来描述网络中节点的重要性。下面是一些基于最短距离度量节点中心性的方法:
能够看到,closeness centrality考虑的是该节点到其余各节点最短路径的长度之和;graph centrality考虑的是该节点到离本身最远的节点的最短路径的长度;stress centrality考虑的是该节点出如今其余两节点之间的最短路径上的次数;而本文讨论的betweenness centrality考虑的是该节点出如今其余两节点之间的最短路径上的比率。
定理:节点v出如今了节点s、t之间的某条最短路径上当且仅当dG(s,t) = dG(s,v) + dG(v,t)
点对s、t对节点v的pair dependency为δst(v) =σst(v)/σst;不妨将pair-dependency理解是对节点v重要性的一种度量,试想若是δst(v)等于1,那么意味着节点s、t之间每条最短路径都得通过节点v。若是从图中撤掉节点v,那么节点s、t之间最短路径的长度就会增长。pair-dependency中的分子σst(v)能够经过下式获得:
因此若是结点v在节点s、t之间的某一条最短路径上,那么δst(v) = σst(v)/σst = σsv*σvt /σst。获得了pair-dependency,经过下式计算betweenness centrality:
由此,betweenness centrality的计算只要分为两步:
第一步:计算各个点对之间最短路径的长度和条数,用于计算pair-dependencies;
第二步:对于每一个节点,累积属于本身的pair-dependencies。
实际中这两步是交替进行的。对于每一个节点s,计算该结点到其余节点的最短路径和条数,记录最短路径上每一个节点的前哨节点,并按离源点s由远及近的方式积累每一个点的pair-dependencies。
第一步:计算最短路径的长度和条数
计算各个点对之间最短路径的长度和条数可使用图的遍历算法。其中BFS和Dijkstra算法都能求单源最短路径,过程都是从队列中取出一节点做为当前节点,再遍历当前节点的相邻结点,把他们标记为已搜索,放进队列中。
对于Ps(v)的定义 Ps(v) = { u∈V : (u,v)∈E , dG(s,v) = dG(s,u) + w(u,v) },咱们能够获得下式:
两节点s,v之间最短路径的条数等于节点s到各个v的前哨节点的最短路径的条数之和。利用BFS求单源最短路径时,则很容易获得节点v的全部前哨节点:若是节点u的相邻结点中包含节点v,且dG(s,u) + w(u,v) = dG(s,v) 或者当前dG(s,v) = -1(表示节点v以前未被搜索到过),那么节点u就是节点v的一个前哨节点。
给定一个源点s,对于有向图能够在O(m+n log n)的时间内,计算s到其余个点的σsx和dG(s,x)。对于无向图,这个时间是O(m)。计算一个图G中的全部σxx和dG(x,x),有向图须要时间O(mn +n2 log n),无向图须要时间O(mn)。
第二步:累积各个点的Pair Dependencies
节点s对节点v的依赖度(dependency)表示为δs· (v):
若是节点s与节点v之间只有一条最短路径,且节点v是节点w的前哨节点,那么
通常的,节点s与节点v之间有多条最短路径,则上式变为:
前一种状况假设节点s与节点v之间只有一条最短路径,理解起来比较简单。下面咱们来证实第二种比较通常的状况。在证实以前先定义δst(v,e) =σst(v,e)/σst,其中σst(v,e) 表示图G中两节点s,t之间的全部最短路径中通过节点v和边e的条数。则
其中可能较难理解的是第二个等号,个人理解是若节点v在两节点s,t之间的某条最短路径上,那么必定存在节点w使v∈Ps(w),固然有可能w就是t。同时咱们能够获得:
对于t!=w的状况,σst(w)/σst表示节点w在两节点s,t之间的某条最短路径上,同时σsv/σsw表示该路径是经过节点v到达的节点w,因此(σsv/σsw)*( σst(w)/σst)表示的是节点w跟其前哨节点v都在两节点s,t之间的某条最短路径上。根据以上两式咱们获得:
实现
无向图中计算Betweenness Centrality的伪代码:
能够证实,在无向图中,该算法的时间复杂度是O(nm),所需的空间是O(n+m)。
Betweenness Centrality 计算的详细介绍参见《A Faster Algorithm for Betweenness Centrality》,上述伪代码的Python实现参见 BetweennessCentrality.py。