好的,我正在尝试在python中完成蒙特卡罗模拟的感染模拟代码。 我们得到了线程shell,只需要完成它。我还必须添加一个疫苗功能,但它应该与感染功能非常相似,所以我试图确保它首先工作。我知道我需要从原始矩阵中读取,但是为每天/迭代写入一个新矩阵,但我无法弄清楚如何写入新矩阵。我尝试使用np.append,但它强迫我重新定义我的原始矩阵A,或者它说列表索引必须是整数,而不是浮点数。我已经尝试过在这里和其他地方的示例,但它们似乎都在使用列表,或者它们不涉及在while循环中调用函数。 任何帮助将不胜感激。
import random
import math
import numpy as np
def infect(Pop,i,j,n,m,tau):
t = 0
if (i > 1) and (i < n) and (j > 1) and (j < m):
if (Pop[i-1,j]>0):
t = (np.random.rand() < tau)
if (Pop[i,j+1]>0):
t = (np.random.rand() < tau)
if (Pop[i+1,j]>0):
t = (np.random.rand() < tau)
if (Pop[i,j-1]>0):
t = (np.random.rand() < tau)
if (i == 1) and (j == 1):
if (Pop[i,j+1]>0):
t = (np.random.rand() < tau)
if (Pop[i+1,j]):
t = (np.random.rand() < tau)
if (i == 1) and (j != m) and (j > 1):
if (Pop[i,j]>0):
t = (np.random.rand() < tau)
if (Pop[i+1,j]>0):
t = (np.random.rand() < tau)
if (Pop[i,j-1]>0):
t = (np.random.rand() < tau)
if (i == 1) and (j == m):
if (Pop[i+1,j]>0):
t = (np.random.rand() < tau)
if (Pop[i,j-1]>0):
t = (np.random.rand() < tau)
if (i == n) and (j == 1):
if (Pop[i-1,j]>0):
t = (np.random.rand() < tau)
if (Pop[i,j+1]>0):
t = (np.random.rand() < tau)
if (i < n) and (i > 1) and (j == 1):
if (Pop[i-1,j]>0):
t = (np.random.rand() < tau)
if (Pop[i,j+1]>0):
t = (np.random.rand() < tau)
if (Pop[i+1,j]>0):
t = (np.random.rand() < tau)
if (i < n) and (i > 1) and (j == m):
if (Pop[i-1,j]>0):
t = (np.random.rand() < tau)
if (Pop[i+1,j]>0):
t = (np.random.rand() < tau)
if (Pop[i,j-1]>0):
t = (np.random.rand() < tau)
if (i == n) and (j > 1) and (j < m):
if (Pop[i-1,j]>0):
t = (np.random.rand() < tau)
if (Pop[i,j+1]>0):
t = (np.random.rand() < tau)
if (Pop[i,j-1]>0):
t = (np.random.rand() < tau)
if (i == n) and (j == m):
if (Pop[i,j-1]>0):
t = (np.random.rand() < tau)
if (Pop[i-1,j]>0):
t = (np.random.rand() < tau)
p = 0
if (t==True):
p = 1
return p
i = 1
j = 1
n = 10
m = 10
k = int(input("Number of Days to Recover from Illness?"))
d = 0.0
tau = 0.5
mu = 0.2
A = np.zeros((n,m))
if d == 0:
n1 = random.sample(range(n),1)
m1 = random.sample(range(m),1)
A[n1,m1] = 1
print(A)
while d < 100:
while True:
if (A[i,j]==0):
x = infect(A,i,j,n,m,tau)
print(x)
#A_new.append(x)
答案 0 :(得分:0)
据我了解,您需要动态感染矩阵,而tau是邻居感染的概率。您可以使用三维数组来优化代码,如下所示:
from copy import copy
import numpy as np
def infect(A, tau):
B = copy(A)
for i in range(m):
for j in range(n):
is_infected = False
for neighbor in [A[i-1,j], A[i+1,j], A[i,j-1], A[i,j+1]]:
if neighbor:
B[i,j] = int(A[i,j] or (np.random.rand() < tau))
return B
D = np.zeros((T + 1, m, n))
A = np.zeros((m, n))
A[i,j] = 1
for t in range(T):
D[t,:,:] = A
A = infect(A, tau)
D[T,:,:] = A
答案 1 :(得分:0)
您创建了一个额外的矩阵,每次循环时都会交换两个引用。例如,
A1 = np.zeros((m, n))
A2 = np.zeros((m, n))
Anow = A1 # reference, not copy
Aafter = A2
while d < 100:
x = infectAll(Anow, Aafter, n,m,tau)
Anow, Aafter = Aafter, Anow
和infectAll()扫过整个矩阵,所以它就像
def infectAll(Ain, Aout, n, m, tau):
for i in range(m):
for j in range(n):
if Anow[i,j] == 0:
Aafter[i,j] = infect(Anow, i, j, n, m, tau)
我喜欢Andrei更紧凑的代码,但不需要每次都创建A的新副本,所以最好将上述技术与Andrei的方法结合起来。