Javaの微分方程式
-
08-10-2019 - |
質問
JavaでSir-Epidemicsモデルのシンプルなシミュレーションプログラムを作成しようとしています。
基本的に、サーは3つの微分方程式のシステムによって定義されます。
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 =少数を取得し、いくつかの1つを使用することにより、数値的にシミュレートできます 数値統合技術 例えば オイラーの方法, 、 また 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;
}
厳しい部分は、使用するステップ数を把握することです。私がリンクした記事の1つを読む必要があります。より洗練された微分方程式ソルバーは、各ステップの精度/安定性に適応する可変ステップサイズを使用します。
ODEソルバーが含まれているため、RやMathematica、Matlab、Octaveなどの数値ソフトウェアを実際に使用することをお勧めします。ただし、より大きなJavaアプリケーションの一部としてこれを行う必要がある場合は、少なくとも数学ソフトウェアで最初に試してみてから、ステップサイズが何であり、どのソルバーが機能するかを確認してください。
幸運を!