毕业设计的后一个部分是挖掘网络中的关键节点组,基于目前国内外所发表的相关论文,整合并结合自身的需要,现提供如下参考代码,希望给予相关意见。
目前,主要验证节点组选取的好坏是通过传染病模型进行仿真实验,通过给定传染率、恢复率,以及关键节点组(也就是种子),查看传染病传染达到稳定状态时,整个网络中R型节点的占比。
代码初版如下所示:
import networkx as nx
import random
import matplotlib.pyplot as plt
def sir_one(graph, seeds, beta=0.4, mu=0.1):
"""单接触SIR模型
传染率beta;恢复率mu"""
I_set = set(seeds)
S_set = set(graph.nodes()).difference(I_set)
R_set = set()
t = 0
while len(I_set) > 0:
Ibase = I_set.copy()
for i in Ibase:
# I --> R
if random.random() < mu:
I_set.remove(i)
R_set.add(i)
# S --> I
if random.random() < beta:
tmp = list(set(graph.neighbors(i)).intersection(S_set).copy())
if len(tmp) > 0:
s = random.choice(tmp)
S_set.remove(s)
I_set.add(s)
t += 1
per_R = len(R_set) / len(graph.nodes())
# print(t)
# print("The percentage of R: " + str(per_R))
return per_R
def sir_more(graph, seeds, beta=0.4, mu=1):
"""全接触SIR模型
传染率beta;恢复率mu"""
I_set = set(seeds)
S_set = set(graph.nodes()).difference(I_set)
R_set = set()
t = 0
while len(I_set) > 0:
Ibase = I_set.copy()
for i in Ibase:
# I --> R
if random.random() < mu:
I_set.remove(i)
R_set.add(i)
# S --> I
tmp = list(set(graph.neighbors(i)).intersection(S_set).copy())
for s in tmp:
if random.random() < beta:
S_set.remove(s)
I_set.add(s)
t += 1
per_R = len(R_set) / len(graph.nodes())
# print(t)
# print("The percentage of R: " + str(per_R))
return per_R
def centrality_index(graph, num):
"""复杂网络中心性指标"""
# degree
degree_graph = dict(nx.degree(graph))
trans_degree = list(zip(degree_graph.values(), degree_graph.keys()))
trans_degree.sort(reverse=True)
# print(trans_degree)
degree_seed = []
for i in range(num):
degree_seed.append(trans_degree[i][1])
# core
core_graph = dict(nx.core_number(graph))
trans_core = list(zip(core_graph.values(), core_graph.keys()))
trans_core.sort(reverse=True)
# print(trans_core)
core_seed = []
for i in range(num):
core_seed.append(trans_core[i][1])
# betweenness
betweenness_graph = nx.betweenness_centrality(graph)
trans_betweenness = list(zip(betweenness_graph.values(), betweenness_graph.keys()))
trans_betweenness.sort(reverse=True)
# print(trans_betweenness)
betweenness_seed = []
for i in range(num):
betweenness_seed.append(trans_betweenness[i][1])
return degree_seed, core_seed, betweenness_seed
def count_r(graph, index):
"""传染病模型仿真达到稳定状态下R占整个网络的比例"""
res_one = []
res_more = []
for a in range(1000):
res_one.append(sir_one(graph, index))
res_more.append(sir_more(graph, index))
print("单接触SIR", sum(res_one) / len(res_one))
print("全接触SIR", sum(res_more) / len(res_more))
print("-----------------")
if __name__ == '__main__':
G = nx.read_edgelist(r"E:\NE_DATA\email\email-Eu-core.edgelist")
# nx.draw_networkx(graph)
# plt.show()
degrees, cores, betweennesses = centrality_index(G, 5)
print("Degree Top 5: ", degrees)
count_r(G, degrees)
print("Core Top 5: ", cores)
count_r(G, cores)
print("Betweenness Top 5: ", betweennesses)
count_r(G, betweennesses)
nes = ['659', '928', '385', '713', '500']
print("NE Top 5: ", nes)
count_r(G, nes)
后通过查看论文,和进行对比分析,改进了第一版本的代码。第一版的代码中,每个I态节点尝试去感染邻居中S态的节点;而真实的定义中,每个I态节点尝试去感染邻居,并没有要求必须是S态节点。由第一版代码会导致在后续的对比分析实验中,无法去验证某种方法在接触有效性方面的效果,故而修改了第一版代码,如下所示。
# 每个I态节点尝试去感染其邻居节点,如果被感染节点为S态节点,即为有效接触,否则是无效接触
def sir_one(graph, seeds, beta=0.35, mu=0.1):
"""单接触SIR模型
传染率beta;恢复率mu"""
I_set = set(seeds)
S_set = set(graph.nodes()).difference(I_set)
R_set = set()
t = 0
while len(I_set) > 0:
Ibase = I_set.copy()
for i in Ibase:
# I --> R
if random.random() < mu:
I_set.remove(i)
R_set.add(i)
# S --> I
tmp = list(graph.neighbors(i))
s = random.choice(tmp)
if random.random() < beta:
if s in S_set:
S_set.remove(s)
I_set.add(s)
t += 1
return len(R_set)
def sir_more(graph, seeds, beta=0.35, mu=1):
"""全接触SIR模型
传染率beta;恢复率mu"""
I_set = set(seeds)
S_set = set(graph.nodes()).difference(I_set)
R_set = set()
t = 0
while len(I_set) > 0:
Ibase = I_set.copy()
for i in Ibase:
# I --> R
if random.random() < mu:
I_set.remove(i)
R_set.add(i)
# S --> I
tmp = list(graph.neighbors(i))
for s in tmp:
if random.random() < beta:
if s in S_set:
S_set.remove(s)
I_set.add(s)
t += 1
return len(R_set)