繁体   English   中英

如何在python 3中的蒙特卡洛模拟中的while循环内写入矩阵

[英]How to write to a matrix within a while loop in a monte carlo simulation in python 3

好的,所以我正在尝试为python中的蒙特卡洛仿真完成感染仿真代码。 我们得到了线程外壳,只需要完成此操作即可。 我还必须添加疫苗功能,但是它应该与感染功能非常相似,因此我试图确保它首先起作用。 我知道我需要从原始矩阵中读取内容,但每天/迭代都要写入一个新矩阵,但是我无法弄清楚如何写入新矩阵。 我尝试使用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)

据我了解,您需要动态改变感染矩阵,tau是邻居感染的可能性。 您可以为此使用3维数组,并按以下方式优化代码:

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

您将创建一个额外的矩阵,并且每次循环时都要交换两个引用。 例如,

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的方法结合起来。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM