2010-12-05 4 views
10

Я пытаюсь создать простую симуляционную программу модели SIR-эпидемий в java.Дифференциальные уравнения в Java

В основном, SIR определяется системой трех дифференциальных уравнений:
S '(T) = - L (T) * S (т)
I' (т) = л (т) * S (т) - г (т) * я (т)
R ', (т) = г (т) * я (т)

S - восприимчивые люди, я - инфицированные люди, R - выздоровел людей.

л (т) = [с * х * я (т)]/N (T)

с - число контактов, х - infectiveness (вероятность заболеть после контакта с больным человеком), 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); 
    } 
} 

}

я бы очень признателен за любую помощь, большое спасибо заранее!

+4

слова «простые» и «дифференциальные уравнения» не входят в одно сообщение ... – hvgotcodes 2010-12-05 02:58:09

+3

@hvgotcodes: ???!? одевают. то, что у него есть, не так уж сложно. некоторые из нас так же относятся к криптографии, регулярным выражениям или веб-службам или обработке сообщений пользовательского интерфейса. – 2010-12-05 03:13:13

ответ

15

Дифференциальные уравнения временных рядов можно моделировать численно, принимая dt = небольшое число и используя один из нескольких numerical integration techniques, например. Euler's method, или Runge-Kutta. Метод Эйлера может быть примитивным, но он работает нормально для некоторых уравнений, и он достаточно прост, чтобы вы могли попробовать. например:

S '(т) = - л (т) * S (T)

I' (T) = л (т) * S (T) - г (т) * я (т)

R '(т) = г (т) * I (т)

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 или Octave, так как они включают в себя программные средства ODE, и вам не нужно было самостоятельно решать все проблемы. Но если вам нужно сделать это как часть более крупного приложения Java, по крайней мере, попробуйте сначала с помощью математического программного обеспечения, затем получите представление о том, какие размеры шага и какие решатели работают.

Удачи вам!

Смежные вопросы