-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimppeliEpidemiaMalli.m
163 lines (129 loc) · 4.75 KB
/
SimppeliEpidemiaMalli.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
% Yksinkertainen malli tarttuvan taudin leviämiselle. Tämä ei perustu
% differentiaaliyhtälöihin vaan todennäköisyyspohjaisiin siirtymisiin
% kategoriasta toiseen. Pohjalan on SIR-malli, jossa jokainen henkilö
% kuuluu yhteen seuraavista kategorioista:
% S sairaudelle alttiit (Susceptile)
% I infektoituneet (Infected)
% R rentoutuneet (taudin sairastaneet ja immuuniksi muuttuneet) (Recovered)
%
% Mallin taustalla on klassinen SIR-malli, katso esimerkiksi
% https://www.maa.org/press/periodicals/loci/joma/the-sir-model-for-spread-of-disease-the-differential-equation-model
%
% Samuli Siltanen maaliskuu 2020
%% Valmisteluja
% Kuinka monta epidemiaa mallinnetaan
Nepidemics = 100;
% Graafisia parametreja
fsize = 30;
lwidth = 3;
% Ihmisten määrä mallissa
N = 10000;
% Kuinka monta päivää simulaatiota ajetaan
Nt = 100;
% Montako muuta ihmistä yksi henkilö tapaa päivässä keskimäärin
Nmeet = 20;
% Montako päivää kestää parantua taudista
Nrecov = 5;
% Sairaudelle alttiin henkilön todennäköisyys saada tartunta,
% kun on kohdannut infektoituneen henkilön
Pinf = .5;
% Montako sairaalasänkyä on käytössä
Nbeds = round(N/3);
Nbeds = 2500;
% Perusta ikkuna kuvaa varten
figure(1)
clf
% Piirrä perustilanne kuvaan
plot([1,Nt],[Nbeds,Nbeds],'k','linewidth',2)
t1 = text(.35*Nt,1.1*Nbeds,'Sairaalapaikkojen määrä');
set(t1,'fontsize',fsize)
axis([1 Nt 0 N])
xlabel('Aika (päiviä)','fontsize',fsize)
ylabel('Tartunnan saaneiden määrä','fontsize',fsize)
set(gca,'ytick',[1000:1000:N],'fontsize',fsize)
hold on
%% For-luuppi epidemioiden yli
for ppp = 1:Nepidemics
% Alustetaan tilannematriisi, joka kuvaa epidemian kulun päivä päivältä.
% Jokaiselle päivälle on oma sarakkeensa.
% Ensimmäinen rivi kertoo infektoituneiden ihmisten määrän I
% Toinen rivi kertoo rentoutuneiden ihmisten määrän R
% Jokaisena päivänä S = N-(I+R).
SIRmat = zeros(2,Nt);
% N-ulotteinen vektori, jossa on ihmisten tilanteet listattuna
% 1 = Susceptible
% 2 = Infected
% 3 = Recovered
peoplevec = ones(1,N);
% Ensimmäisenä päivänä on yksi sairastunut
peoplevec(randi(N)) = 2;
SIRmat(1,1) = 1;
% For-luuppi päivien yli, alkaen päivästä 2
for iii = 2:Nt
% Uudet infektiot.
% Poimitaan satunnaisesti ihmiset, jotka ovat kohdanneet sairastuneen.
% Otetaan heistä esiin sairaudelle alttiit; tästä joukosta
% sairastuu osa todennäköisyyden Pinf mukaisesti
peoplevec = peoplevec(randperm(length(peoplevec))); % Satunnainen sekoitus
N_met_sick = Nmeet*SIRmat(1,iii-1); % Näin moni kohtasi sairastuneen
for jjj = 1:min(N_met_sick,N)
if (peoplevec(jjj)==1)&(rand<Pinf)
peoplevec(jjj) = 2;
end
end
% Rentoituneiden luominen eli sairaudesta paraneminen.
if iii>Nrecov % Paraneminen alkaa Nrecov päivän jälkeen
for jjj = 1:N
if (peoplevec(jjj)==2)&(rand<(1/Nrecov))
peoplevec(jjj) = 3;
end
end
end
% Päivitä tilannematriisi
SIRmat(1,iii) = length(find(peoplevec==2));
SIRmat(2,iii) = length(find(peoplevec==3));
end
% Piirrä kuva
figure(1)
plot([1:Nt],SIRmat(1,:),'r','linewidth',lwidth)
axis([1 Nt 0 N])
t2 = text(.1*Nt,17/25*N,[num2str(Nmeet),' kohtaamista päivässä']);
set(t2,'fontsize',fsize,'color',[1 0 0])
drawnow
end
%% Lasketaan, mitä tapahtuu, kun vähennämme ihmisten välisiä kohtaamisia
% Muuten lasku on täysin sama kuin yllä; siksi jätän kommentit pois.
% Montako muuta ihmistä yksi henkilö tapaa päivässä keskimäärin
Nmeet = 1;
for ppp = 1:Nepidemics
SIRmat = zeros(2,Nt);
peoplevec = ones(1,N);
peoplevec(randi(N)) = 2;
SIRmat(1,1) = 1;
for iii = 2:Nt
peoplevec = peoplevec(randperm(length(peoplevec)));
N_met_sick = Nmeet*SIRmat(1,iii-1);
for jjj = 1:min(N_met_sick,N)
if (peoplevec(jjj)==1)&(rand<Pinf)
peoplevec(jjj) = 2;
end
end
if iii>Nrecov
for jjj = 1:N
if (peoplevec(jjj)==2)&(rand<(1/Nrecov))
peoplevec(jjj) = 3;
end
end
end
SIRmat(1,iii) = length(find(peoplevec==2));
SIRmat(2,iii) = length(find(peoplevec==3));
end
% Piirrä kuva
figure(1)
plot([1:Nt],SIRmat(1,:),'b','linewidth',lwidth)
axis([1 Nt 0 N])
t3 = text(.5*Nt,4.5/25*N,[num2str(Nmeet),' kohtaaminen päivässä']);
set(t3,'fontsize',fsize,'color',[0 0 1])
title('Samun simppeli epidemiamalli','fontsize',fsize)
drawnow
end