网络的介数中心性(betweenness)及计算方法
2016-04-16 15:14
3731 查看
昨天面试被问到betweenness的计算方法,很尴尬没有自己实现过。平时用的时候通常用Python的networkx包计算,具体算法之前还没了解过。复杂网络的教材通常就介绍了betweenness的意义与定义,直接从定义出发计算的复杂度达到O(n3)
这里介绍一个2001年brandes提出的算法”A faster algorithm for betweenness centrality”,在无权图上复杂度为O(mn),在有权图上复杂度在O(mn+nlogn),在网络稀疏的时候,复杂度接近O(n2).
C
4000
B(v)=∑s≠v≠t∈Vσst(v)σst
其中σst(v)表示经过节点v的s→t的最短路径条数,σst表示s→t的最短路径条数。
直观上来说,betweenness反映了节点v作为“桥梁”的重要程度。
为了方便,定义pair-dependency为
δst(v)=σst(v)σst
则
CB(v)=∑s≠v≠t∈Vδst(v)
Ps(v)={u∈V:{u,v}∈E,dG(s,v)=dG(s,u)+ω(u,v)}
意思就是从节点s到节点v的最短路径中v的前驱节点集。或者说如果从s→t的最短路径包含边(u,v),那么u属于这个集合。
我们会发现下诉关系式成立:∀s≠t,
σsv=∑u∈Ps(v)σsu
理解这个关系式并不难:s→v的最短路径必然先从s→u,再通过边(u,v)到达v,其中u是v的前驱节点。
下面的问题简单多了,对无权图调用BFS算法,对有权图调用Dijkstra’s算法,前者在O(m)时间内算出{σst|t∈V},后者时间为O(m+nlogn)
简单介绍下BFS为什么可以做。我们知道BFS遍历节点的顺序恰好是按照距离节点s的距离升序排列的,而节点u是v的前驱节点必然要求d(s,u)<d(s,v),因此按照BFS遍历顺序,到达节点v时,其前驱节点u的σsu必然已经计算好了。
σst(v)={σsv⋅σvt0d(s,v)+d(v,t)=d(s,t)other
事实上我们并不关心具体的某个δst(v),我们想要的是
∑s,tδst(v)
为此定义
δs⋅(v)=∑t∈Vδst(v)
下面我们要说明下面这个关系式成立:
δs⋅(v)=∑w:v∈Ps(w)σsvσsw(1+δs⋅(w))
如果这个关系式成立的话,根据先驱关系,计算δs⋅(v)需要先计算δs⋅(w),而v是w的先驱,顺序恰好跟BFS相反,因此用个栈就可以了。
我们试图在节点w与它的前驱节点v建立关系。我们可以把通过节点w的最短路径分成两类
通过节点v的路径
不通过节点v的路径
为了推导方便,引入几个符号:δst(v,e)=σst(v,e)σst,σst(v,e)表示s→t最短路径通过节点v和边e的条数。
显然的我们有
δs⋅(v)=∑t∈V∑w:v∈Ps(w)δst(v,{v,w})=∑w:v∈Ps(w)∑t∈Vδst(v,{v,w})
s→t的通过w的最短路径为σst(w)=σswσwt,而σst(v,{v,w})=σsvσwt
后者是因为从s→t经过v,(v,w)要先到达v,然后走(v,w),最后从w→t.
这里我们得到t≠w时
δst(v,{v,w})=σsvσswσst(w)σst
t=w时,
δst(v,{v,w})=σsvσsw
这就有
∑w:v∈Ps(w)∑t∈Vδst(v,{v,w})=∑w:v∈Ps(w)⎛⎝σsvσsw+∑t∈V−{w}σsvσswσst(w)σst⎞⎠=∑w:v∈Ps(w)σsvσsw(1+δs⋅(w))
至此计算就完毕了。
选取源节点s做BFS计算σst
遍历过程中将节点推入栈中,同时保留每个节点作为其他节点前驱的集合。
用公式计算δs⋅(v)
这里介绍一个2001年brandes提出的算法”A faster algorithm for betweenness centrality”,在无权图上复杂度为O(mn),在有权图上复杂度在O(mn+nlogn),在网络稀疏的时候,复杂度接近O(n2).
betweenness定义
betweenness的直接定义式为:C
4000
B(v)=∑s≠v≠t∈Vσst(v)σst
其中σst(v)表示经过节点v的s→t的最短路径条数,σst表示s→t的最短路径条数。
直观上来说,betweenness反映了节点v作为“桥梁”的重要程度。
为了方便,定义pair-dependency为
δst(v)=σst(v)σst
则
CB(v)=∑s≠v≠t∈Vδst(v)
如何计算σst
首先引入一个记号Ps(v)={u∈V:{u,v}∈E,dG(s,v)=dG(s,u)+ω(u,v)}
意思就是从节点s到节点v的最短路径中v的前驱节点集。或者说如果从s→t的最短路径包含边(u,v),那么u属于这个集合。
我们会发现下诉关系式成立:∀s≠t,
σsv=∑u∈Ps(v)σsu
理解这个关系式并不难:s→v的最短路径必然先从s→u,再通过边(u,v)到达v,其中u是v的前驱节点。
下面的问题简单多了,对无权图调用BFS算法,对有权图调用Dijkstra’s算法,前者在O(m)时间内算出{σst|t∈V},后者时间为O(m+nlogn)
简单介绍下BFS为什么可以做。我们知道BFS遍历节点的顺序恰好是按照距离节点s的距离升序排列的,而节点u是v的前驱节点必然要求d(s,u)<d(s,v),因此按照BFS遍历顺序,到达节点v时,其前驱节点u的σsu必然已经计算好了。
计算CB
现在我们计算出所有的了σst,为了得到δst(v)我们可能还要计算σst(v),虽然可以通过下面的关系式计算,但是复杂度又上去了。σst(v)={σsv⋅σvt0d(s,v)+d(v,t)=d(s,t)other
事实上我们并不关心具体的某个δst(v),我们想要的是
∑s,tδst(v)
为此定义
δs⋅(v)=∑t∈Vδst(v)
下面我们要说明下面这个关系式成立:
δs⋅(v)=∑w:v∈Ps(w)σsvσsw(1+δs⋅(w))
如果这个关系式成立的话,根据先驱关系,计算δs⋅(v)需要先计算δs⋅(w),而v是w的先驱,顺序恰好跟BFS相反,因此用个栈就可以了。
我们试图在节点w与它的前驱节点v建立关系。我们可以把通过节点w的最短路径分成两类
通过节点v的路径
不通过节点v的路径
为了推导方便,引入几个符号:δst(v,e)=σst(v,e)σst,σst(v,e)表示s→t最短路径通过节点v和边e的条数。
显然的我们有
δs⋅(v)=∑t∈V∑w:v∈Ps(w)δst(v,{v,w})=∑w:v∈Ps(w)∑t∈Vδst(v,{v,w})
s→t的通过w的最短路径为σst(w)=σswσwt,而σst(v,{v,w})=σsvσwt
后者是因为从s→t经过v,(v,w)要先到达v,然后走(v,w),最后从w→t.
这里我们得到t≠w时
δst(v,{v,w})=σsvσswσst(w)σst
t=w时,
δst(v,{v,w})=σsvσsw
这就有
∑w:v∈Ps(w)∑t∈Vδst(v,{v,w})=∑w:v∈Ps(w)⎛⎝σsvσsw+∑t∈V−{w}σsvσswσst(w)σst⎞⎠=∑w:v∈Ps(w)σsvσsw(1+δs⋅(w))
至此计算就完毕了。
总结
列举下主要计算步骤选取源节点s做BFS计算σst
遍历过程中将节点推入栈中,同时保留每个节点作为其他节点前驱的集合。
用公式计算δs⋅(v)
代码
import networkx as nx from Queue import Queue G = nx.random_graphs.barabasi_albert_graph(100,3) #algorithm from networkx C = nx.centrality.betweenness_centrality(G,normalized=False) CB = dict.fromkeys(G,0.0) for s in G.nodes(): Pred = {w:[] for w in G.nodes()} dist = dict.fromkeys(G,None) sigma = dict.fromkeys(G,0.0) dist[s] = 0 sigma[s] = 1 Q = Queue() Q.put(s) S = [] while not Q.empty(): v = Q.get() S.append(v) for w in G.neighbors(v): if dist[w] == None: dist[w] = dist[v] + 1 Q.put(w) if dist[w] == dist[v] + 1: sigma[w] += sigma[v] Pred[w].append(v) delta = dict.fromkeys(G,0.0) for w in S[::-1]: for v in Pred[w]: delta[v] += sigma[v]/sigma[w]*(1+delta[w]) if w != s: CB[w] += delta[w] for v in CB: CB[v] /= 2.0 #compare with networkx's implements print(sum(abs(CB[v]-C[v]) for v in G)) #1.59428026336e-13
相关文章推荐
- linux下追踪软件执行过程之cflow
- Windows下安装Python + igraph (用于复杂网络分析)
- 复杂网络研究常用载体集
- 【复杂网络资料】实证网络数据和各种程序源码
- 动态大系统方法导论(四)-结构可控性及其在复杂网络中的应用
- 世界上为什么会有圆?
- 节点重要性和相似性
- 复杂网络上的传播动力学
- 《网络科学导论》学习笔记——代表性网络的研究内容
- 社区发现(Community Detection)算法
- 大数据与网络分析的平台和工具
- 讲座:网络科学徜徉 sub-modular,large graphs,计算与存储支撑
- 笔记:复杂网络的关键技术及应用
- 使用Origin画出复杂网络博弈中合作率时间演化图(学术论文)
- 度分布图引发的折腾
- 复杂网络(1)--图论的基本理论
- 复杂网络综述
- 复杂网络分析工具及其比较(转)
- 复杂网络的统计特征
- 社区发现评估指标-NMI