2010-12-05 66 views
10

Estoy tratando de crear un programa de simulación simple del modelo SIR-epidemias en java.Ecuaciones diferenciales en Java

Básicamente, SIR se define por un sistema de tres ecuaciones diferenciales:
S '(t) = - l (t) * S (t)
I' (t) = l (t) * S (t) - g (t) * I (t)
R '(t) = g (t) * I (t)

S - personas susceptibles, I - personas infectadas, R - personas recuperadas.

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

c - número de contactos, x - infecciosidad (probabilidad de conseguir enfermo después del contacto con la persona enferma), N (t) - población total (que es constante).

¿Cómo puedo resolver tales ecuaciones diferenciales en Java? No creo que conozca ninguna forma útil de hacerlo, por lo que mi implementación produce basura.

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

}

Le agradecería cualquier ayuda, muchas gracias de antemano!

+4

las palabras 'simple' y 'Ecuaciones diferenciales' no pertenecen a la misma publicación ... – hvgotcodes

+3

@hvgotcodes: ???!? adaptarse a ti mismo. lo que tiene no es tan complicado. algunos de nosotros sentimos lo mismo acerca de la criptografía, las expresiones regulares, los servicios web o el manejo de mensajes de UI. –

+0

@jason. sí. Supongo que depende de a lo que se haya expuesto. Nunca tuve que tomar DEQ; el grado de CS en mi escuela requirió 2 cálculos numéricos en lugar de DEQ ... – hvgotcodes

Respuesta

15

Las ecuaciones diferenciales de series temporales se pueden simular numéricamente tomando dt = un número pequeño, y usando uno de varios numerical integration techniques p. Ej. Euler's method, o Runge-Kutta. El método de Euler puede ser primitivo, pero funciona bien para algunas ecuaciones y es lo suficientemente simple como para intentarlo. por ejemplo:

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

La parte difícil es decidir cuántos pasos de usar. Deberías leer uno de los artículos a los que me he vinculado. Los solucionadores de ecuaciones diferenciales más sofisticados usan tamaños de pasos variables que se adaptan a la precisión/estabilidad para cada paso.

De hecho, recomendaría utilizar software numérico como R o Mathematica o MATLAB u Octave, ya que incluyen los solucionadores de ODE y usted no tendría que tomarse tantas molestias. Pero si necesita hacer esto como parte de una aplicación Java más grande, al menos pruébela primero con el software matemático, luego tenga una idea de cuáles son los tamaños de los pasos y qué solucionadores funcionan.

¡Buena suerte!

+1

¡Muchas gracias! –

+0

+1 - esto está bien hecho. – duffymo