import networkx as nx
import itertools
def custom_node_to_node_dispersion(G, u, v):
"""
u, v간의 dispersion을 알고자 함.
ego_graph(G, source)에서 target으로 가는 dispersion을 확인
dispersion: source와 target의 common_neighbor(공통으로 이웃하는 노드)
1) common_neighbor에서 서로 다른 s, t들이,
2) ego_graph(G, source) 상에서 s, t가 서로 직접 연결되지 않았을 때,
3) ego_graph(G, source) 상에서 s, t가 connection이 없을 때(common neighbor 가 없을때)
의 모든 수를 합해서 리턴.
normalize: /len(common_nbrs)
"""
u_nbrs = set(G[u])
v_nbrs = set(G[v])
common_nbrs = u_nbrs.intersection(v_nbrs)
# embeddedness는 공통된 nbrs의 수를 의미함.
embededness = len(common_nbrs)
ego_graph_u = nx.ego_graph(G, u)
# 이 함수에서는 distance를 1 or 0으로 처리했으나,
# 실제 논문에서는 distance function을 변화하여 다양한 경우를 검증.
distance_u_to_v = 0
for (s, t) in itertools.combinations(common_nbrs, 2):
# 1) common_neighbor에서 서로 다른 s, t에 대해서
s_nbrs_excluding_uv = set(ego_graph_u[s]).difference(set([u, v]))
if t not in s_nbrs_excluding_uv:
# 2) ego_graph(G, source) 상에서 s, t가 서로 직접 연결되지 않았을 때(u, v 제외)
t_nbrs_excluding_uv = set(ego_graph_u[t]).difference(set([u, v]))
if s_nbrs_excluding_uv.isdisjoint(t_nbrs_excluding_uv):
# 3) ego_graph에서 s, t가 서로 connection이 없을 때(common neighbor가 없을 때 )
# 이럴 때, 거리를 1로, 아닐 경우, 0.
distance_u_to_v += 1
# normalized
if len(common_nbrs)!=0:
return distance_u_to_v / embededness
else:
return distance_u_to_v
########################
# Graph generation
N = 300 # node size
p = 0.5
G = nx.fast_gnp_random_graph(N, p, seed=0)
G = nx.scale_free_graph(N)
G = nx.Graph(G)
print(nx.is_connected(G))
if True:
# custom_node_dispersion
for n1, n2 in itertools.combinations(G, 2):
custom_disp = custom_node_to_node_dispersion(G, n1, n2)
nx_disp = nx.dispersion(G, n1, n2)
if custom_disp!=nx_disp:
print(f"{n1:3d} => {n2:3d} ::: {custom_disp:.5f} ::: {nx_disp:.5f}")
댓글남기기