如何在python 3中的monte carlo模拟中在while循环中写入矩阵

如何在python 3中的monte carlo模拟中在while循环中写入矩阵,python,matrix,while-loop,simulation,montecarlo,Python,Matrix,While Loop,Simulation,Montecarlo,好的,我正在尝试用python完成monte carlo模拟的感染模拟代码。 我们得到了线程外壳,只需要完成这个。我还需要添加一个疫苗功能,但它应该非常类似于感染功能,所以我试图确保它首先起作用。我知道我需要阅读原始矩阵,但每天/每次迭代都要写入新矩阵,但我不知道如何写入新矩阵。我尝试使用np.append,但它迫使我重新定义原始矩阵A,或者它说列表索引必须是整数,而不是浮点数。我尝试过在这里和其他地方使用示例,但它们似乎都在使用列表,或者它们不涉及调用while循环中的函数。 任何帮助都将不胜

好的,我正在尝试用python完成monte carlo模拟的感染模拟代码。 我们得到了线程外壳,只需要完成这个。我还需要添加一个疫苗功能,但它应该非常类似于感染功能,所以我试图确保它首先起作用。我知道我需要阅读原始矩阵,但每天/每次迭代都要写入新矩阵,但我不知道如何写入新矩阵。我尝试使用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是邻居感染的概率。您可以使用三维数组进行此操作,并按如下方式优化代码:

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

我喜欢Andrei更紧凑的代码,但没有必要每次都创建一个新的副本,因此最好将上述技术与Andrei的方法结合起来

好的,我认为使用for循环可以释放很多不必要的代码,但我只是不确定如何使用副本,谢谢!还有,你是如何定义T的?它会代替迭代吗?knvm弄明白了:当然,我的T和你的K是一样的,当所有矩阵值都是@SaraWiles13时,我能让while循环终止吗?这是一个额外的问题。评论不是一个好地方,因为人们无法告诉你尝试了什么,也无法设置代码格式等。我建议你创建一个新问题。我注意到你对原始问题进行了重大更改,因此阅读该问题的人现在可能很难理解答案,尤其是被接受的答案之间的关系。我强烈反对这样做。澄清是好的,但是上面的问题现在有两个问题,一个是关于不正确的索引,另一个是关于如何在特定条件下终止循环,与a/B副本无关。如果您得到了一个对原始问题有用的答案,您应该撤消上一次编辑以保留原始问题,而是创建两个新问题。
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)