import random
import matplotlib.pyplot as plt
import networkx as nx
# 创建2000个点平均度为10的ER网络
G = nx.random_graphs.erdos_renyi_graph(2000, 10 / 2000)
beta, gamma = 0.1, 0.5
# 初始状态
for node in G.nodes():
G.nodes[node][“state”] = “S”
G.nodes[random.randint(0, 2000)][“state”] = “I”
G.nodes[random.randint(0, 2000)][“state”] = “I”
# 更新状态
def update_state(G, node):
if G.nodes[node][“state”] == “S”: # 感染
p = random.random()
n = 0
for neibor in G.adj[node]:
if G.nodes[neibor][“state”] == “I”:
n += 1
if p < 1 - (1 - beta) ** n:
G.nodes[node][“state”] = “I”
elif G.nodes[node][“state”] == “I”: # 恢复
p = random.random()
if p < gamma:
G.nodes[node][“state”] = “R”
# 获取当前图的状态
def get_state_info(G):
S, I, R = 0, 0, 0
for node in G:
if G.nodes[node][“state”] == “S”:
S += 1
elif G.nodes[node][“state”] == “I”:
I += 1
else:
R += 1
return [S, I, R]
avg = []
last_states = {}
# 进行模拟传播
def transmitted(G):
info = []
while True:
info.append(get_state_info(G))
if info[-1][1] == 0: # 达到稳态
avg.append(info)
break
for node in G: # 遍历图中节点,每一个节点状态进行更新
update_state(G, node)
# 重复实验100次
for i in range(100):
transmitted(G.copy())
#取平均值
temp = avg[0][-1]
for state in avg:
temp = list(map(lambda x: (x[0] + x[1]) / 2, zip(temp,state[-1])))
print(temp)
# 绘制图像
maxl = len(max(avg, key=lambda x: len(x)))
x = [i for i in range(maxl)]
y = [[0] * 3 for i in range(maxl)]
for l in avg:
for i, values in enumerate(l):
if sum(y[i]) == 0:
y[i] = values
continue
y[i] = list(map(lambda x: (x[0] + x[1]) / 2, zip(y[i], values)))
color_ = [‘red’, ‘blue’, ‘green’]
label = [‘S’, ‘I’, ‘R’]
for i in range(3):
y_ = [value[i] for value in y]
plt.plot(x, y_, color=color_[i], label=label[i], linestyle=‘-.’)
plt.title(‘SIR Model’)
plt.ylabel(‘nums’)
plt.xlabel(‘times’)
plt.legend()
plt.show()
asdsadasda
于 2022-05-30 19:19:42 首次发布