дифференциация модели SEIR в Java
Я пытаюсь смоделировать модель эпидемии SEIR. Он состоит из четырех частей:
- Восприимчивые (незараженные)
- Обнаружен (заражен, но еще не заразен)
- Инфекционные (инфицированные и заразные)
- Удален (восстановлен / мертв)
где гамма γ - частота инфицирования, а бета β - частота повторного выздоровления / смертности.
Ранее я использовал модель SIR, более простую модель, в которой E и I объединены, в которой используются следующие уравнения:
https://wikimedia.org/api/rest_v1/media/math/render/svg/29728a7d4bebe8197dca7d873d81b9dce954522e
Из другого потока я использовал решение для имитации SIR с помощью этого кода:
double dS = (beta * S.get(day) * I.get(day) / N);
double newS = (S.get(day) - dS);
double newI = (I.get(day) + dS - gamma * I.get(day));
double newR = (R.get(day) + gamma * I.get(day));
Это прекрасно работает при использовании метода Эйлера. Однако я пытался манипулировать этим, чтобы попытаться соответствовать модели SEIR (которая имеет эти уравнения:)
https://wikimedia.org/api/rest_v1/media/math/render/svg/feeb0e885c70ec83c36cec8b33f5ea696f3761a6
где u - коэффициент смертности, дельта - коэффициент рождаемости, а - инкубационный период. Я попытался использовать аналогичный метод для работы с SEIR, но мне вообще не удалось смоделировать его хорошо. На самом деле это проблема не с переменными, а с дифференцированием этих сложных уравнений в целом. Интересно, может ли кто-нибудь помочь, спасибо.
1 ответ
На самом деле следовало понять это раньше, но из-за того, что мы возились со случайными изменениями знаков, выяснилось, что все, кроме 'newS', требует получения номера предыдущего дня и добавления нового dS, а не его уменьшения. Мой код SIR уже сделал это. Не знаю, как я это пропустил...
Новый рабочий код:
int totalDays = 160; // How many days/times to loop
int N = 1000; // Population
int I0 = 1; // Starting infected/exposed
double beta = 0.2; // Infection rate
double gamma = 1.0/10.0; // recovery time (days to the -1)
double a = 1.0/2.0; // incubation period (days to the -1)
List<Double> S = new ArrayList<>();
List<Double> E = new ArrayList<>();
List<Double> I = new ArrayList<>();
List<Double> R = new ArrayList<>();
private void createData() {
final int R0 = 0;
final int S0 = N - E0 - R0;
S.add((double) S0);
E.add((double) I0);
I.add(0.0);
R.add(0.0);
for (int day = 1; day < totalDays + 1; day++) {
double[] derivative = deriv(day);
S.add(derivative[0]);
E.add(derivative[1]);
I.add(derivative[2]);
R.add(derivative[3]);
}
}
private double[] deriv(int day) {
day = day - 1;
double dS = (beta * S.get(day) * I.get(day)) / N;
double newS = S.get(day) - (dS);
double newE = E.get(day) + (dS - (a * E.get(day)));
double newI = I.get(day) + ((a * E.get(day)) - (gamma * I.get(day)));
double newR = R.get(day) + (gamma * I.get(day));
return new double[] {newS, newE, newI, newR};
}