关于python:Python大作业耦合网络信息传播

41次阅读

共计 2841 个字符,预计需要花费 8 分钟才能阅读完成。

import random
import matplotlib.pyplot as plt

ER 随机网络

ER = [[]],

BA 无标度网络

BA = [[]]

ER 网络感化的状况,S 示意为衰弱,I 示意已感化,R 示意已痊愈

ER_SIR = []
BA_SIR = []

用于记录每日数据的数组

slist = []
ilist = []
rlist = []

生成 ER 随机网络,n 示意点个数,p 示意生成边的概率

def generateER(n, p):

global ER
# 防止浅拷贝
ER = [([0] * n) for i in range(n)]
for i in range(0, n):
    for j in range(i + 1, n):
        # 随机生成的数
        x = random.random()
        # 概率生成边
        if x < p:
            ER[i][j] = 1
            ER[j][i] = 1

在下标 0 到 end 的 klist 列表中依据 k 的权重来寻找一个下标返回, 不包含 exclude_list 中的节点

def findOne(klist, end, exclude_list):

flag = True
k_sum = 0
for i in range(0, end):
    k_sum += klist[i]
result = end - 1
while flag:
    x = random.random() * k_sum
    pre = 0
    for i in range(0, end):
        pre += klist[i]
        if pre > x:
            result = i
            break
    flag = False
    # 查看后果是否在 exclude_list 中,如果是则重来,否则返回后果
    for i in exclude_list:
        if i == result:
            flag = True
            break
return result

依据 BA 无标度网络的规定在 klist(下标为 0 到 end 之间) 中寻找 m 个数

为了简化逻辑,这里参加竞争(k!=0)的节点数必然大于 m

def find(k_list, m, end):

# 后果数组
result = []
# 初始化
for i in range(0, m):
    j = findOne(k_list, end, result)
    # 减少后果
    result.append(j)
return result

生成 BA 无标度网络,n 示意点个数,m0 示意初始节点数

def generateBA(n, m0, m):

global BA
# 初始 BA 无标度网络 (利用生成器创立防止浅拷贝)
BA = [([0] * n) for i in range(n)]
# 初始化前 m0 个节点都为连通网络
for i in range(0, m0):
    for j in range(i + 1, m0):
        BA[i][j] = 1
        BA[j][i] = 1
# 初始度数组
k_list = [m0 - 1] * m0 + [0] * (n - m)
# 遍历前面的节点,模仿退出
for i in range(m0, n):
    # 选出 m 个节点
    nodes = find(k_list, m, i)
    for j in nodes:
        BA[i][j] = 1
        BA[j][i] = 1
        # 更新度数组
        k_list[i] += 1
        k_list[j] += 1

对 ER 网络的 i 节点进行解决,i 示意节点下标,t 示意天数,b 示意感化系数,y 示意痊愈系数

def er_sir_one(i, t, b, y):

global ER, BA, ER_SIR, BA_SIR, slist, ilist, rlist
if ER_SIR[i] == 'S':
    # 开始统计四周节点感化的数量
    inum = 0
    for x in range(len(ER_SIR)):
        if (not x == i) and ER[i][x] == 1 and ER_SIR[x] == 'I':
            inum += 1
    # 因为是双层网络,所以 BA 也要思考
    if BA_SIR[i] == 'I':
        inum += 1
        ilist[t] += 1
    p = random.random()
    # 有 1 -(1-b)^inum 概率感化
    if p < 1 - (1 - b) ** inum:
        ER_SIR[i] = 'I'
        ilist[t] += 1
        return
    slist[t] += 1
elif ER_SIR[i] == 'I':
    p = random.random()
    # 有 y 的几率痊愈
    if p < y:
        ER_SIR[i] = 'R'
        rlist[t] += 1
        return
    ilist[t] += 1
else:
    rlist[t] += 1

对 BA 网络的 i 节点进行解决,i 示意节点下标,t 示意天数,b 示意感化系数,y 示意痊愈系数

def ba_sir_one(i, t, b, y):

global ER, BA, ER_SIR, BA_SIR, slist, ilist, rlist
if BA_SIR[i] == 'S':
    # 开始统计四周节点感化的数量
    inum = 0
    for x in range(len(BA_SIR)):
        if (not x == i) and BA[i][x] == 1 and BA_SIR[x] == 'I':
            inum += 1
    # 因为是双层网络,所以 ER 也要思考
    if ER_SIR[i] == 'I':
        inum += 1
    p = random.random()
    # 有 1 -(1-b)^inum 概率感化
    if p < 1 - (1 - b) ** inum:
        BA_SIR[i] = 'I'
        ilist[t] += 1
        return
    slist[t] += 1
# 有 y 的几率痊愈
elif BA_SIR[i] == 'I':
    p = random.random()
    if p < y:
        BA_SIR[i] = 'R'
        rlist[t] += 1
        return
    ilist[t] += 1
else:
    rlist[t]+=1

def sir(b, y, t):

global ER_SIR, BA_SIR, slist, ilist, rlist
n = len(ER[0])
# 初始化 ER_SIR,BA_SIR
ER_SIR = ['S'] * n
BA_SIR = ['S'] * n
# 初始化每日统计数据的数组
slist = [0] * t
ilist = [0] * t
rlist = [0] * t
# 随机感化 ER 网络中的一个节点
x = random.randint(0, n - 1)
ER_SIR[x] = 'I'
# 遍历 t 天,[利率期货](https://www.gendan5.com/ff/if.html) 模仿过了 t 天
for day in range(t):
    # 遍历所有节点
    for node in range(n):
        # 对双层网络状态进行一遍刷新
        er_sir_one(node, day, b, y)
        ba_sir_one(node, day, b, y)
# 画图
plt.plot(list(range(t)), slist, linewidth=4,label=u'S')
plt.plot(list(range(t)), ilist, linewidth=4,label=u'I')
plt.plot(list(range(t)), rlist, linewidth=4,label=u'R')
plt.legend()  # 让图例失效
plt.xlabel(u"t")  # X 轴标签
plt.ylabel("N(t)")  # Y 轴标签
plt.title("SIR model result")  # 题目
plt.show()

def main():

generateER(1000, 0.006)
generateBA(1000, 3, 3)
sir(0.2, 0.5, 50)

if name == ‘__main__’:

main()

正文完
 0