import networkx as nx
import numpy as np
import time
def np_normalize_dict(input_dict):
"""
input_dict: {node_name: centrality_float}에서
value를 normalize하여 리턴.
"""
vs = np.array(list(input_dict.values()))
vs /= np.linalg.norm(vs)
return {k: v for k, v in zip(input_dict.keys(), vs)}
def custom_harmonic_centrality(G):
"""
node `u`의 harmonic centrality는
다른 모든 node `v`로 향하는 모든 shortest path length의 역수를 더한다.
"""
r_dict = {n:0 for n in G}
for n1 in G:
for n2 in G:
if n1!=n2:
n2_n1_l = nx.shortest_path_length(G, n2, n1)
#print(n1, n2, n1_n2_l)
r_dict[n1]+=1/n2_n1_l
return r_dict
########################
# Graph generation
N = 10 # node size
p = 0.5
G = nx.fast_gnp_random_graph(N, p, seed=0)
print("=="*20)
print("== custom harmonic centrality")
custom_harmonic_cent = custom_harmonic_centrality(G)
print("== nx - harmonic centrality")
nx_harmonic_cent = nx.harmonic_centrality(G)
# 만약, nx.harmonic_centrality와 다르다면 아래 코드에서 오류가 발생해야 함.
for n in G:
# To ignore underflow rounding.
round_c__h_cent = round(custom_harmonic_cent[n], 8)
round_nx_h_cent = round(nx_harmonic_cent[n], 8)
assert round_c__h_cent == round_nx_h_cent
print("=="*20)
#############################################
# Comparison with pagerank
# Graph generation
N = 100 # node size
p = 0.3
G = nx.fast_gnp_random_graph(N, p, seed=0)
G = nx.scale_free_graph(N)
G = nx.Graph(G)
print(f"nx.is_connected(G): {nx.is_connected(G)}")
print("==")
print("== computation time")
harmonic_time = time.time()
harmonic_cent = nx.harmonic_centrality(G)
harmonic_time = time.time() - harmonic_time
#harmonic_cent = np_normalize_dict(harmonic_cent) # normalize
print(f"harmonic computation time: {harmonic_time:10.6f}")
pagerank_time = time.time()
pagerank_cent = nx.pagerank(G)
pagerank_time = time.time() - pagerank_time
#pagerank_cent = np_normalize_dict(pagerank_cent) # normalize
print(f"pagerank computation time: {pagerank_time:10.6f}")
print(f"harmonic is {pagerank_time/harmonic_time:.2f} times faster than pagerank ")
print("==")
# value distribution
print("== histogram ")
harmonic_cent_v = list(harmonic_cent.values())
pagerank_cent_v = list(pagerank_cent.values())
# np histogram
bins=30
harmonic_bin, h_edge_bin = np.histogram(harmonic_cent_v, bins=bins)
pagerank_bin, p_edge_bin = np.histogram(pagerank_cent_v, bins=bins)
print("== harmonic, pagerank histogram")
MARKER = "="
for h, p in zip(harmonic_bin, pagerank_bin):
# left is harmonic
# right is pagerank
left = f"{MARKER*h:>50s}"
right = f"{MARKER*p:<50s}"
row = left + "|" + right
print(row)
print("=="*20)
========================================
== custom harmonic centrality
== nx - harmonic centrality
========================================
nx.is_connected(G): True
==
== computation time
harmonic computation time: 0.052979
pagerank computation time: 0.036304
harmonic is 0.69 times faster than pagerank
==
== histogram
== harmonic, pagerank histogram
==|===================================================================================
=|=========
===|===
======|=
==|
=============|
|
============|=
|=
=|
===============================|
===================|
=====|
=|=
|
|
=|
=|
|
|
|
=|
|
|
|
|
|
|
|
=|=
========================================
댓글남기기