我正在尝试在Java中创建一个简单的SIR-EPIDEMICS模型模拟程序。

基本上,SIR由三个微分方程的系统定义:
s'(t)= -l(t) * s(t)
i'(t)= l(t) * s(t)-g(t) * i(t)
r'(t)= g(t) * i(t)

S-易感人,我 - 感染的人,r-恢复的人。

l(t)= [c * x * i(t)] / n(t)

C-接触数量,X-感染性(与病人接触后生病的可能性),n(t) - 总人口(这是恒定的)。

如何在Java中求解如此微分方程?我认为我不知道这样做的任何有用的方法,因此我的实施会产生垃圾。

public class Main {
public static void main(String[] args) {
    int tppl = 100;
    double sppl = 1;
    double hppl = 99;
    double rppl = 0;
    int numContacts = 50;
    double infectiveness = 0.5;
    double lamda = 0;
    double duration = 0.5;
    double gamma = 1 / duration;
    for (int i = 0; i < 40; i++) {
        lamda = (numContacts * infectiveness * sppl) / tppl;
        hppl = hppl - lamda * hppl;
        sppl = sppl + lamda * hppl - gamma * sppl;
        rppl = rppl + gamma * sppl;
        System.out.println (i + " " + tppl + " " + hppl + " " + sppl + " " + rppl); 
    }
}

}

非常感谢任何帮助,非常感谢!

有帮助吗?

解决方案

时间序列微分方程可以通过取dt =少量来数值模拟,并使用几个 数值集成技术 例如 欧拉的方法, , 或者 runge-kutta. 。 Euler的方法可能是原始的,但对于某些方程式来说可以正常工作,并且可以尝试一下。例如:

s'(t)= -l(t) * s(t)

i'(t)= l(t) * s(t)-g(t) * i(t)

r'(t)= g(t) * i(t)

int N = 100;
double[] S = new double[N+1];
double[] I = new double[N+1];
double[] R = new double[N+1];

S[0] = /* initial value */
I[0] = /* initial value */
R[0] = /* initial value */

double dt = total_time / N;

for (int i = 0; i < 100; ++i)
{
   double t = i*dt;
   double l = /* compute l here */
   double g = /* compute g here */

   /* calculate derivatives */
   double dSdt = - I[i] * S[i];
   double dIdt = I[i] * S[i] - g * I[i];
   double dRdt = g * I[i];

   /* now integrate using Euler */
   S[i+1] = S[i] + dSdt * dt;
   I[i+1] = I[i] + dIdt * dt;
   R[i+1] = R[i] + dRdt * dt;
}

艰难的部分是弄清楚使用了多少个步骤。您应该阅读我链接的文章之一。更复杂的微分方程求解器使用可适应每个步骤准确性/稳定性的变量步长。

实际上,我建议使用R,Mathematica或Matlab或八度的数值软件,因为它们包括ODE求解器,您无需自己解决所有麻烦。但是,如果您需要作为较大Java应用程序的一部分进行此操作,至少首先使用数学软件尝试一下,然后了解步骤尺寸是什么以及求解器的工作。

祝你好运!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top