Java 中的微分方程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4357061/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 06:01:45  来源:igfitidea点击:

Differential Equations in Java

javamathodedifferential-equations

提问by Sergei G

I am trying to create a simple simulation program of SIR-epidemics model in java.

我正在尝试用java创建一个简单的SIR流行病模型模拟程序。

Basically, SIR is defined by a system of three differential equations:
S'(t) = - l(t) * S(t)
I'(t) = l(t) * S(t) - g(t) * I(t)
R'(t) = g(t) * I(t)

基本上,SIR 由三个微分方程组定义:
S'(t) = - l(t) * S(t)
I'(t) = l(t) * S(t) - g(t) * I(t)
R'(t) = g(t) * I(t)

S - susceptible people, I - infected people, R - recovered people.

S - 易感者,I - 感染者,R - 康复者。

l(t) = [c * x * I(t)] / N(T)

l(t) = [c * x * I(t)] / N(T)

c - number of contacts, x - infectiveness (probability to get sick after contact with sick person), N(t) - total population (which is constant).

c - 接触次数,x - 传染性(与病人接触后生病的可能性),N(t) - 总人口(常数)。

How can I solve such differential equations in Java? I don't think I know any useful way to do that, so my implementation produces rubbish.

我怎样才能在 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); 
    }
}

}

}

I would greatly appreciate any help, many thanks in advance!

我将不胜感激任何帮助,非常感谢!

回答by Jason S

Time-series differential equations can be simulated numerically by taking dt = a small number, and using one of several numerical integration techniquese.g. Euler's method, or Runge-Kutta. Euler's method may be primitive but it works OK for some equations and it's simple enough that you might give it a try. e.g.:

时间序列微分方程可以通过取 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)

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;
}

The tough part is figuring out how many steps to use. You should read one of the articles I have linked to. More sophisticated differential equation solvers use variable step sizes that adapt to accuracy/stability for each step.

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

I would actually recommend using numerical software like R or Mathematica or MATLAB or Octave, as they include ODE solvers and you wouldn't need to go to all the trouble yourself. But if you need to do this as part of a larger Java application, at least try it out first with math software, then get a sense of what the step sizes are and what solvers work.

我实际上建议使用 R 或 Mathematica 或 MATLAB 或 Octave 等数值软件,因为它们包含 ODE 求解器,您无需自己解决所有麻烦。但是,如果您需要在更大的 Java 应用程序中执行此操作,至少首先使用数学软件进行尝试,然后了解步长是多少以及求解器的工作原理是什么。

Good luck!

祝你好运!