春秋白LU 2023-04-10 10:23 采纳率: 16.7%
浏览 63
已结题

python 实现sir传染病模型,怎么显示传染方向?

请问怎么使用python调整有向图的箭头方向?我的想法是增加一个节点的状态(感染性),如果他有感染性,就有向外的红色箭头,连线也为红色;没有感染性且身边节点都没有感染性,则箭头和连线均为默认方向且为黑色。

import networkx as nx
import matplotlib.pyplot as plt
import random
import numpy as np

#来生成一个有N个节点,连接概率为p,邻居为k的随机网络
N = 20
p = 0.25
k = 4
#er=nx.erdos_renyi_graph(N,p)
er = nx.random_graphs.watts_strogatz_graph(N,k,p)
for i in range(N):
    er.nodes[i]['state'] = 'S'
    edge_color = 'g'
gama = 0.5
beta = 0.1

ps= nx.spring_layout(er)  #nx.spectral_layout(er)nx.circular_layout(er)nx.shell_layout(er)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=50)
nx.draw_networkx_nodes(er,ps,node_color =color ,node_size=50)
nx.draw_networkx_edges(er,ps ,width=1,arrows=True,arrowstyle='->')


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'
        edge_color = 'g'
        arrow_color = 'g'
    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()
                edge_color = 'r'
                if r < beta and G.nodes[node]['state'] == 'S':
                    G.nodes[node]['state'] = 'I'
                    edge_color = 'r'
                    arrow_color = 'r'
                    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=50)
        nx.draw_networkx_edges(er, ps,  width=1, arrows=True, arrowstyle='->')
        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')

  • 写回答

9条回答 默认 最新

报告相同问题?

问题事件

  • 系统已结题 4月18日
  • 赞助了问题酬金20元 4月10日
  • 创建了问题 4月10日

悬赏问题

  • ¥50 comsol温度场仿真无法模拟微米级激光光斑
  • ¥15 上传图片时提交的存储类型
  • ¥15 Ubuntu开机显示器只显示kernel,是没操作系统(相关搜索:显卡驱动)
  • ¥15 VB.NET如何绘制倾斜的椭圆
  • ¥15 在rhel8中安装qemu-kvm时遇到“cannot initialize crypto:unable to initialize gcrypt“报错”
  • ¥15 arbotix没有/cmd_vel话题
  • ¥20 找能定制Python脚本的
  • ¥15 odoo17的分包重新供应路线如何设置?可从销售订单中实时直接触发采购订单或相关单据
  • ¥15 用C语言怎么判断字符串的输入是否符合设定?
  • ¥15 通信专业本科生论文选这两个哪个方向好研究呀