Python模拟无法正常工作

时间:2019-05-26 13:32:10

标签: python numpy

我有一个任务,我们必须模拟疾病的传播,它几乎可以正常工作,除非被感染的人死亡时它会删除2个被感染的人,并且只会增加1个死亡,我添加了fixInfected模块来尝试解决它,但这也没有用达到预期的效果(最终我获得的人数基本上比开始时多了100人)

import numpy as np
import random

#Inputs

#Option for using Moore or Von Neumann neighbourhoods (Von Neumann is     default)
moore = input("Use Moore Neighbourhoods? (Y/N): ")

#Input for probability of an uninfected person getting infected
probInfect = input("Enter the probability of an uninfected becoming infected: ")
#Make sure input is a float
try:
    probInfect = float(probInfect)
except:
    probInfect = float(0.5)
#Make sure probability is < 1
if probInfect > 1:
    probInfect = probInfect/10

#Input for probability of an infected person recovering (if they don't recover they die)
probRecover = input("Enter the probability of an infected person recovering: ")
#Make sure input is a float
try:
    probRecover = float(probRecover)
except:
    probRecover = float(0.5)
#Make sure probability is < 1
if probRecover > 1:
    probRecover = probRecover/10

#Input the probability of an infected person dying
probDie = input("Enter the probability of an infected person dying: ")
#Make sure input is a float
try:
    probDie = float(probDie)
except:
    probDie = float(0.5)
#Make sure probability is < 1
if probDie > 1:
    probDie = probDie/10

#Input the person of a recovering person to become immune
probImmune = input("Enter the probability of a recovering person becoming immune: ")
#Make sure input is a float
try:
    probImmune = float(probImmune)
except:
    probImmune = float(0.5)
#Make sure probability is < 1
if probImmune > 1:
    probImmune = probImmune/10

#Initialize


INIT_POP = 100
INIT_INFECTED = 5
NUM_COLS = 15
NUM_ROWS = 10
NUM_STEPS = 10

infected = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)
uninfected = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)
dead = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)
recovering = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)
immune = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)

#Defining Modules

def distribute(grid, num_r, num_c, numpeep):
    for i in range(numpeep):
        rpos = random.randint(0, num_r-1)
        cpos = random.randint(0, num_c-1)
        grid[rpos, cpos] += 1

def makeScatter(grid, num_r, num_c):
    r_values = []
    c_values = []
    count_values = []
    for row in range(num_r):
        for col in range(num_c):
            if grid[row,col] > 0:
                r_values.append(row)
                c_values.append(col)
                count_values.append(grid[row,col]*100)
    return(r_values, c_values, count_values)

def displayGrid(grid, num_r, num_c):
    for row in range(num_r-1, -1, -1):
        for col in range(num_c):
            print(grid[row,col], end=" ")
        print()

def movePeeps(cur, next, r, c, dead):
    for peep in range(cur[r,c]):
        if moore == "Y":
            rMove = random.randint(-1,1)
            cMove = random.randint(-1,1)
        else:
            direction = random.randint(1,4)
            if direction%2 == 1:
                rMove = random.randint(-1,1)
                cMove = 0
            else:
                cMove = random.randint(-1,1)
                rMove = 0
        if (r + rMove) > (NUM_ROWS-1) or (r + rMove) < 0:
            rMove = 0
        if (c + cMove) > (NUM_COLS-1) or (c + cMove) < 0:
            cMove = 0   
        if dead == 0:
            next[r + rMove, c + cMove] +=1
        else:
            next[r,c] +=1

def infect(inf, notinf, r, c, prob):
    prob = prob * inf[r,c]
    if prob:
        for peep in range(notinf[r,c]):
            if random.random() < prob:
                inf[r, c] +=1
                notinf[r, c] -=1
                print("***** New infection (", r, ",", c, ")")


def fixInfected(infected, uninfected, dead, recovering, immune, INIT_POP, INIT_INFECTED, r, c):
#Replaces infected that were removed and not added due to error
    if sum(sum(infected))+sum(sum(uninfected))+sum(sum(dead))+sum(sum(recovering))+sum(sum(immune)) != INIT_POP + INIT_INFECTED:
        Sum = (sum(sum(infected))+sum(sum(uninfected))+sum(sum(dead))+sum(sum(recovering))+sum(sum(immune)))
        errDif = (INIT_POP+INIT_INFECTED)-Sum
        print("errDif is: ", errDif)
        infected[r, c] =+ errDif

def failedRecovery(inf, recovering, r, c, prob):
    prob = prob * inf[r,c]
    if prob:
        for peep in range(recovering[r,c]):
            if random.random() < prob:
                inf[r, c] +=1
                recovering[r, c] -= 1
                print("***** New infection (", r, ",", c, ")")

def recover(inf, recover, r, c, prob):
    prob = prob * inf[r,c]
    if prob:
        for peep in range(inf[r,c]):
            if random.random() < prob:
                recover[r,c] +=1
                inf[r,c] =-1
                print("***** New Recovery (", r, ",", c, ")")

def die(inf, dead, r, c, prob):
    prob = prob * inf[r,c]
    if prob:
        for peep in range(inf[r,c]):
            if random.random() < prob:
                dead[r,c] +=1
                inf[r,c] =-1
                print("***** New Death (", r, ",", c, ")")

def immunity(recover, immune, r, c, prob):
    prob = prob * recover[r,c]
    if prob:
        for peep in range(recover[r,c]):
            if random.random() < probImmune:
                immune[r,c] +=1
                recovering[r,c] -=1
                print("***** New Immunity (", r,",", c, ")")



distribute(infected, NUM_ROWS, NUM_COLS, INIT_INFECTED)
distribute(uninfected, NUM_ROWS, NUM_COLS, INIT_POP)


for timestep in range(NUM_STEPS):
    print("\n###################### TIMESTEP", timestep, "#####################\n")
    print("Sim Report: ")
    print("Number of infected: ", sum(sum(infected)))
    print("Number of uninfected: ", sum(sum(uninfected)))
    print("Number of deaths: ", sum(sum(dead)))
    print("Number of recovering:", sum(sum(recovering)))
    print("Number of immune:", sum(sum(immune)))


    infected2 = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)
    uninfected2 = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)
    dead2 = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)
    recovering2 = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)
    immune2 = np.zeros((NUM_ROWS, NUM_COLS), dtype=np.int)
    for row in range(NUM_ROWS):
        for col in range(NUM_COLS):
            infect(infected, uninfected, row, col, probInfect)
            recover(infected, recovering, row, col, probRecover)
            die(infected, dead, row, col, probDie)
            immunity(recovering, immune, row, col, probImmune)
            failedRecovery(infected, recovering, row, col, (1 - probRecover))
            fixInfected(infected, uninfected, dead, recovering, immune, INIT_POP, INIT_INFECTED, row, col)
            movePeeps(infected, infected2, row, col, 0)
            movePeeps(uninfected, uninfected2, row, col, 0)
            movePeeps(recovering, recovering2, row, col, 0)
            movePeeps(immune, immune2, row, col, 0)
            movePeeps(dead, dead2, row, col, 1)
    infected = infected2
    uninfected = uninfected2
    dead = dead2
    recovering = recovering2
    immune = immune2

print("Sim Report: ")
print("Number of infected: ", np.sum(infected))
print("Number of uninfected: ", np.sum(uninfected))
print("Number of deaths: ", np.sum(dead))
print("Number of recovering:", np.sum(recovering))
print("Number of immune:", np.sum(immune))

print("Done")

2 个答案:

答案 0 :(得分:1)

在不花太多时间研究代码的情况下,我认为第149和158行有错别字。他们应该说:

inf[r,c] -= 1

答案 1 :(得分:0)

inf[r,c] =-1 

应该是

inf[r,c] -= 1

#Make sure probability is < 1
if probDie > 1:
    probDie = probDie/10

应该是

#Make sure probability is < 1
if probDie > 1:
    probDie = probDie/100

如果要处理以百分比形式给出的值