-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsirmodel.h
89 lines (71 loc) · 2.26 KB
/
sirmodel.h
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
#include <cmath>
#include <random>
#include <vector>
#include <iostream>
#define PI 3.141592
#define BOXSIZE 30
#define MAXVEL 1
using namespace std;
static double getRandomDouble(double min, double max) {
static random_device rd;
static mt19937 gen(rd());
uniform_real_distribution<double> dis(min, max);
return dis(gen);
}
class Dot {
public:
double x, y, vx, vy;
int state; // 0: Susceptible, 1: Infected, 2: Recovered
int infected_no = 0;
int infected_days = 0;
Dot() { // initialize random position and velocity
x = getRandomDouble(0, BOXSIZE);
y = getRandomDouble(0, BOXSIZE);
double randangle = getRandomDouble(0, 2 * PI);
double v = getRandomDouble(0.5 * MAXVEL, MAXVEL);
vx = v * sin(randangle);
vy = v * cos(randangle);
state = 0;
}
void move() {
x += vx;
y += vy;
// Boundary conditions
if (x < 0 || x > BOXSIZE) vx *= -1;
if (y < 0 || y > BOXSIZE) vy *= -1;
if (state == 1) infected_days++;
}
};
class DotArray {
public:
vector<Dot> dots;
int susceptible = 0, infected = 0, recovered = 0;
DotArray(int N) {
dots.reserve(N);
for (int i = 0; i < N; ++i) {
dots.emplace_back();
}
dots[0].state = 1; // Start with one infected dot
}
void update(double infection_radius, double infection_probability, int infection_duration) {
for (Dot& dot : dots) {
dot.move();
}
for (int i = 0; i < dots.size(); i++) {
if (dots[i].state == 2) continue;
for (int j = i + 1; j < dots.size(); j++) {
if (dots[j].state + dots[i].state != 1) continue;
double dx = dots[i].x - dots[j].x;
double dy = dots[i].y - dots[j].y;
// Distance check + probability check
if (dx * dx + dy * dy <= infection_radius * infection_radius && getRandomDouble(0, 1) < infection_probability) {
dots[j].state = 1; // infected
}
}
}
for (Dot& dot : dots) {
if (dot.state == 1 && dot.infected_days > infection_duration)
dot.state = 2;
}
}
};