2017-11-18 24 views
2

언급 한 모델의 매우 기본적인 구현을 만들었습니다. 그러나 그래프가 올바르게 보일지라도 숫자는 상수까지 합쳐지지 않습니다. 그것은 각 구획에서 감수성이 있거나 감염된/회복 된 사람들의 합계가 N (총 인원수)까지 합쳐야 만합니다. 그러나 어떤 이유에서 그것이 기묘한 10 진수를 더하지는 않습니다. 그것을 3 일 동안보고 난 후에 그것을 고치는 법을 알지 마라.SI, SIS, SIR 모델 (파이썬)의 올바른 구현

는 SI 모델 :

import matplotlib.pyplot as plt 

N = 1000000 
S = N - 1 
I = 1 
beta = 0.6 

sus = [] # infected compartment 
inf = [] # susceptible compartment 
prob = [] # probability of infection at time t 

def infection(S, I, N): 
    t = 0 
    while (t < 100): 
     S = S - beta * ((S * I/N)) 
     I = I + beta * ((S * I)/N) 
     p = beta * (I/N) 

     sus.append(S) 
     inf.append(I) 
     prob.append(p) 
     t = t + 1 

infection(S, I, N) 
figure = plt.figure() 
figure.canvas.set_window_title('SI model') 

figure.add_subplot(211) 
inf_line, =plt.plot(inf, label='I(t)') 

sus_line, = plt.plot(sus, label='S(t)') 
plt.legend(handles=[inf_line, sus_line]) 

plt.ticklabel_format(style='sci', axis='y', scilimits=(0,0)) # use scientific notation 

ax = figure.add_subplot(212) 
prob_line = plt.plot(prob, label='p(t)') 
plt.legend(handles=prob_line) 

type(ax) # matplotlib.axes._subplots.AxesSubplot 

# manipulate 
vals = ax.get_yticks() 
ax.set_yticklabels(['{:3.2f}%'.format(x*100) for x in vals]) 

plt.xlabel('T') 
plt.ylabel('p') 

plt.show() 

SIS 모델 :

import matplotlib.pylab as plt 

N = 1000000 
S = N - 1 
I = 1 
beta = 0.3 
gamma = 0.1 

sus = \[\] 
inf = \[\] 

def infection(S, I, N): 
    for t in range (0, 1000): 
     S = S - (beta*S*I/N) + gamma * I 
     I = I + (beta*S*I/N) - gamma * I 

     sus.append(S) 
     inf.append(I) 


infection(S, I, N) 

figure = plt.figure() 
figure.canvas.set_window_title('SIS model') 

inf_line, =plt.plot(inf, label='I(t)') 

sus_line, = plt.plot(sus, label='S(t)') 
plt.legend(handles=\[inf_line, sus_line\]) 

plt.ticklabel_format(style='sci', axis='y', scilimits=(0,0)) 

plt.xlabel('T') 
plt.ylabel('N') 

plt.show() 

SIR 모델 :

import matplotlib.pylab as plt 

N = 1000000 
S = N - 1 
I = 1 
R = 0 
beta = 0.5 
mu = 0.1 

sus = [] 
inf = [] 
rec = [] 

def infection(S, I, R, N): 
    for t in range (1, 100): 
     S = S -(beta * S * I)/N 
     I = I + ((beta * S * I)/N) - R 
     R = mu * I 

     sus.append(S) 
     inf.append(I) 
     rec.append(R) 

infection(S, I, R, N) 

figure = plt.figure() 
figure.canvas.set_window_title('SIR model') 

inf_line, =plt.plot(inf, label='I(t)') 

sus_line, = plt.plot(sus, label='S(t)') 

rec_line, = plt.plot(rec, label='R(t)') 
plt.legend(handles=[inf_line, sus_line, rec_line]) 

plt.ticklabel_format(style='sci', axis='y', scilimits=(0,0)) 

plt.xlabel('T') 
plt.ylabel('N') 


plt.show() 

답변

1

난 단지 SI 모델을 살펴 보겠습니다.

두 가지 주요 변수는 SI입니다. (이 두 변수의 의미를 뒤집어 썼을 지 모르지만, 여기에 쓰는 것은 아무런 영향을 미치지 않습니다.) 합계가 1000000N이되도록 초기화하십시오.

당신은 당신은 분명히 I에 추가 S에서 같은 값을 빼하려는 라인

S = S - beta * ((S * I/N)) 
I = I + beta * ((S * I)/N) 

에 두 가지 주요 변수를 갱신, 그래서 SI의 합은 변경되지 않습니다. 그러나 실제로는 먼저 S을 변경 한 다음 새 값을 사용하여 I을 변경하므로 더하거나 뺀 값은 실제로 같지 않으며 변수의 합계는 일정하지 않습니다.

한 줄로 여러 변수를 업데이트 할 수있는 Python의 기능을 사용하여이 문제를 해결할 수 있습니다. 동일한 값이 실제로 두 변수에서 추가 감산되도록

S, I = S - beta * ((S * I/N)), I + beta * ((S * I)/N) 

이 변수를 업데이트하기 전에 새로운 값의 양을 계산하여 그 두 라인을 대체. (업데이트 된 값의 임시 변수 나 더하기/빼기 양을 저장하는 임시 변수와 같은 동일한 효과를 얻는 다른 방법이 있지만 파이썬을 사용하기 때문에 기능을 사용할 수도 있습니다.

지금 프로그램을 실행하면

, 나는이 그래프를 얻을 : 내가 생각

enter image description here

당신이 원하는 것입니다.

0

그래서 위의 솔루션은 SIS 모델에서도 작동했습니다.

import matplotlib.pylab as plt 
from scipy.integrate import odeint 
import numpy as np 

N = 1000 
S = N - 1 
I = 1 
R = 0 
beta = 0.6 # infection rate 
gamma = 0.2 # recovery rate 

# differential equatinons 
def diff(sir, t): 
    # sir[0] - S, sir[1] - I, sir[2] - R 
    dsdt = - (beta * sir[0] * sir[1])/N 
    didt = (beta * sir[0] * sir[1])/N - gamma * sir[1] 
    drdt = gamma * sir[1] 
    print (dsdt + didt + drdt) 
    dsirdt = [dsdt, didt, drdt] 
    return dsirdt 


# initial conditions 
sir0 = (S, I, R) 

# time points 
t = np.linspace(0, 100) 

# solve ODE 
# the parameters are, the equations, initial conditions, 
# and time steps (between 0 and 100) 
sir = odeint(diff, sir0, t) 

plt.plot(t, sir[:, 0], label='S(t)') 
plt.plot(t, sir[:, 1], label='I(t)') 
plt.plot(t, sir[:, 2], label='R(t)') 

plt.legend() 

plt.xlabel('T') 
plt.ylabel('N') 

# use scientific notation 
plt.ticklabel_format(style='sci', axis='y', scilimits=(0,0)) 

plt.show() 
다음 SIR 모델로서

는 I 여기 SIR 모델에 대한 간단한 해결책은, odeint를 사용하여 미분 방정식을 해결했다