networkx+python实现复杂网络经典的传染病SIR模型(根据度中心性,介数中心性,接近中心性指标选择感染源)

import networkx as nx
import matplotlib.pyplot as plt
import random
import numpy as np
#来生成一个有N个节点,连接概率为p的随机网络
N = 200
p = 0.02
er=nx.erdos_renyi_graph(N,p)

for i in range(N):
    er.nodes[i]['state'] = 'S'
gama = 0.5
beta = 0.1
ps=nx.spring_layout(er)#布置框架
colors={"R":'b',"I":'r',"S":'g'}
states= nx.get_node_attributes(er, 'state')############ 获得节点的isCore属性     
color=[colors[states[i]] for i in range(N)]

nx.draw(er,ps,node_color =color ,with_labels=True,node_size=300)
plt.show()

在这里插入图片描述

def centrality(G):
    #计算度中心性,降序
    dc = nx.algorithms.centrality.degree_centrality(G)
    return    sorted(dc.items(), key=lambda x: x[1],reverse = True)
def betweenness(G):
    #计算介数中心性,降序
    dc = nx.betweenness_centrality(G)
    return sorted(dc.items(), key=lambda x: x[1],reverse = True)
def closeness(G):
    #计算接近中心性,降序
    dc = nx.closeness_centrality(G)
    return sorted(dc.items(), key=lambda x: x[1],reverse = True)
def spread(G,beta,initial,func,gamma = 0 ):
    colors={"R":'b',"I":'r',"S":'g'}
    y = []
    n = len(G.nodes)#总人数
    for i in range(n):#所有人默认为易感染
        G.nodes[i]['state'] = 'S'
    s = n - initial #易感染人数
    desc_dc = func(G)
    
    i_nodes = []
    #选择前inttial个度中心性最高的节点设为感染源
    for i in range(initial):
        G.nodes[desc_dc[0][0]]['state'] = 'I'
        i_nodes.append(desc_dc[0][0])
        desc_dc.remove(desc_dc[0])
    y.append( (  (s, (len(i_nodes)),0 )  ))
    #开始传播,直到所有人被传染
    
    r_nodes = nx.Graph()
    while len(i_nodes) != 0:
        print(s)
        #当前轮被传染的人数
        i_temp = []
        #当前恢复人数 gamma 概率
        for i in i_nodes:
            if random.random() < gamma:
                r_nodes.add_node(i)
                i_nodes.remove(i)
                G.nodes[i]['state'] = 'R'
        i_nodes_temp = nx.Graph()
        i_nodes_temp.add_nodes_from(i_nodes)
        
        
        for i in i_nodes_temp.nodes:
           
            #按beta概率传染I节点的邻居节点
            for node in G.neighbors(i):
                r= random.random()
                
                if r < beta and G.nodes[node]['state'] == 'S':
                   
                    G.nodes[node]['state'] = 'I'
                    i_temp.append(node)
        for t in i_temp :
            if t not in i_nodes:
                i_nodes.append(t)
        s = n - len(i_nodes) -len(r_nodes.nodes)
        
        i = len(i_nodes)
        r = len(r_nodes.nodes)     
        y.append((s,i,r))
        states= nx.get_node_attributes(G, 'state')############ 获得节点的属性  
        color=[colors[states[i]] for i in range(n)]
        nx.draw(G,ps,node_color =color ,with_labels=True,node_size=300)
        plt.show()
    return np.array(y)

#选择度中心性最高的5个点作为感染源
result = spread(er,0.3,5,centrality,0.1)
print(result)
plt.plot(result[:,0], 'g', label='Susceptibles')
plt.plot(result[:,1], 'r', label='Infectious')
plt.plot(result[:,2], 'b', label='Recovereds')
plt.legend(loc='right')
plt.xlabel('time')
plt.ylabel('number of people')
195

在这里插入图片描述

183

在这里插入图片描述

160

在这里插入图片描述

141

在这里插入图片描述

121

在这里插入图片描述

99

在这里插入图片描述

76

在这里插入图片描述

60

在这里插入图片描述

43

在这里插入图片描述

省略一些传播过程的网络图

11

在这里插入图片描述

11

在这里插入图片描述

11

在这里插入图片描述

[[195   5   0]
 [183  17   0]
 [160  39   1]
 [141  55   4]
 [121  71   8]
 [ 99  84  17]
 [ 76  93  31]
 [ 60 102  38]
 [ 43 106  51]
 [ 34 108  58]
 [ 24 107  69]
 [ 17 105  78]
 [ 15  98  87]
 [ 13  90  97]
 [ 12  77 111]
 [ 12  70 118]
 [ 12  62 126]
 [ 11  59 130]
 [ 11  57 132]
 [ 11  53 136]
 [ 11  47 142]
 [ 11  44 145]
 [ 11  38 151]
 [ 11  36 153]
 [ 11  28 161]
 [ 11  24 165]
 [ 11  24 165]
 [ 11  22 167]
 [ 11  19 170]
 [ 11  17 172]
 [ 11  17 172]
 [ 11  14 175]
 [ 11  13 176]
 [ 11  12 177]
 [ 11  11 178]
 [ 11  10 179]
 [ 11  10 179]
 [ 11   9 180]
 [ 11   7 182]
 [ 11   6 183]
 [ 11   6 183]
 [ 11   6 183]
 [ 11   5 184]
 [ 11   4 185]
 [ 11   4 185]
 [ 11   4 185]
 [ 11   4 185]
 [ 11   4 185]
 [ 11   4 185]
 [ 11   4 185]
 [ 11   4 185]
 [ 11   4 185]
 [ 11   3 186]
 [ 11   3 186]
 [ 11   2 187]
 [ 11   2 187]
 [ 11   2 187]
 [ 11   1 188]
 [ 11   1 188]
 [ 11   1 188]
 [ 11   1 188]
 [ 11   1 188]
 [ 11   1 188]
 [ 11   1 188]
 [ 11   1 188]
 [ 11   1 188]
 [ 11   0 189]]





Text(0, 0.5, 'number of people')

在这里插入图片描述



版权声明:本文为HolllllldOn原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。