-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSimulacion_Red_SIR_correcta.py
154 lines (129 loc) · 8.56 KB
/
Simulacion_Red_SIR_correcta.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import networkx as nx
import EoN
import random
import matplotlib.pyplot as plt
#----------------------------------------------------------------------------------------------------
# Función que genera la red
def generar_red(kave, numero_de_individuos):
# Ajustar infec_ratio para obtener el grado promedio kave
infec_ratio = kave / (numero_de_individuos - 1)
G_i = nx.fast_gnp_random_graph(numero_de_individuos, infec_ratio) # Crear red con N nodos y grado promedio kave
return G_i # Retornar la red generada
#----------------------------------------------------------------------------------------------------
# Función que aplica la simulación Gillespie SIR
def aplicar_gillespie(G, tau, gamma, rho, t):
sim = EoN.Gillespie_SIR(G, tau, gamma, rho=rho, tmax=t, return_full_data=True)
return sim
#----------------------------------------------------------------------------------------------------
# Función que muestra los nodos infectados y recuperados en t=i
def mostrar_estados(G, sim, i):
susceptibles = [nodo for nodo in G.nodes() if sim.get_statuses(time=i)[nodo] == 'S']
infectados = [nodo for nodo in G.nodes() if sim.get_statuses(time=i)[nodo] == 'I']
recuperados = [nodo for nodo in G.nodes() if sim.get_statuses(time=i)[nodo] == 'R']
print(f"En el tiempo {i}:Susceptibles - {susceptibles} Infectados - {infectados}, Recuperados - {recuperados}")
return infectados, recuperados
#----------------------------------------------------------------------------------------------------
# Función que registra el estatus de los nodos en t=i
def registrar_estatus(sim, i):
estatus_tiempo=sim.get_statuses(time=i)
print(f"Estatus de los nodos en el tiempo {i}:")
for nodo, estado in estatus_tiempo.items():
print(f"Nodo {nodo}: {estado}")
#----------------------------------------------------------------------------------------------------
# Función que actualiza y muestra el árbol de transmisión
def actualizar_arbol_transmision(G, infectados, arbol_transmision, i):
nuevos_infectados=set()
for nodo in infectados:
for vecino in G.neighbors(nodo):
if vecino not in infectados: # Asegurarse de que el vecino no está infectado
nuevos_infectados.add(vecino)
arbol_transmision.add_edge(nodo, vecino, tiempo=i)
return nuevos_infectados
#----------------------------------------------------------------------------------------------------
# Serie temporal de Saludables, infectados y Recuperados.
# Función que genera y muestra la serie temporal de S, I, R
def serie_temporal(sim, t):
tiempos = range(t + 1)
S, I, R = [], [], [] # Listas para almacenar saludables, infectados y recuperados en cada tiempo
for i in tiempos:
estatus_tiempo = sim.get_statuses(time=i)
s_count = sum(1 for estado in estatus_tiempo.values() if estado == 'S')
i_count = sum(1 for estado in estatus_tiempo.values() if estado == 'I')
r_count = sum(1 for estado in estatus_tiempo.values() if estado == 'R')
S.append(s_count)
I.append(i_count)
R.append(r_count)
# Graficar la serie temporal de S, I, R
plt.figure(figsize=(10, 6))
plt.plot(tiempos, S, label="Saludables (S)", color='green')
plt.plot(tiempos, I, label="Infectados (I)", color='red')
plt.plot(tiempos, R, label="Recuperados (R)", color='Aqua')
plt.xlabel("Tiempo")
plt.ylabel("Número de individuos")
plt.title("Serie Temporal de Saludables, Infectados y Recuperados")
plt.legend()
plt.grid()
plt.show()
#------------------------------------------------------------------------------------------------------------------------------------------------
# Función principal que organiza la simulación y las visualizaciones
def generar_redes_transmision(t, tau, gamma, N, kave, rho, numero_de_individuos):
for z in range(1, N + 1):
G = generar_red(kave, numero_de_individuos) # Genera la red con grado promedio kave
sim = aplicar_gillespie(G, tau, gamma, rho, t) # Ejecuta la simulación
arbol_transmision = nx.DiGraph() # Grafo para el árbol de transmisión
for i in range(1, t + 1):
print(f"\n--- Tiempo {i} ---")
print(f"simulación de red numero:{z} ")
# Mostrar los estados de los nodos en tiempo t=i
infectados, recuperados = mostrar_estados(G, sim, i)
# Actualizar el árbol de transmisión y obtener los nuevos infectados
nuevos_infectados = actualizar_arbol_transmision(G, infectados, arbol_transmision, i)
# Registrar el estatus de los nodos
registrar_estatus(sim, i)
# Graficar el árbol de transmisión
pos = nx.spring_layout(arbol_transmision)
fig = plt.figure(figsize=(10, 7))
ax = fig.add_subplot(111)
# Asignar colores a los nodos en el árbol de transmisión
color_map = []
for nodo in arbol_transmision.nodes():
if nodo in infectados:
color_map.append('red') # Infectados en rojo
elif nodo in recuperados:
color_map.append('Aqua') # Recuperados en Aqua.
else:
color_map.append('green') # Otros nodos
nx.draw(arbol_transmision, pos, ax=ax, with_labels=True, node_color=color_map, node_size=500, arrows=True)
plt.title(f"Árbol de Transmisión hasta el tiempo {i}")
plt.show()
# Llamamos la función de serie temporal para ver el comportamiento en cada tiempo i
serie_temporal(sim, i)
#---------------------------------------------------------------------------------------------------------------------------------------------------------------
#Funcion primordial dos para simulación de transmisión compleja.
#generar_redes_complejas()
#en un futuro agregare la parte compleja para ver el comportamiento.
#--------------------------------------------------------------------------------------------------------------------------------------------
# Parámetros de simulación
t = 10 # Duración de la simulación.
N = 2 # Número de redes que se quieren simular, se muestra una red primero y despues una nueva red, cada una diferente y pueden ser varias.
#---------------------------------------------------------------------------------------------------------------------------------------------------
gamma = 0.1 # Tasa de recuperación. L = 1/gamma o donde L es la tasa de recuperación en caso de no saber como calcular L simplemente es el promedio.
# de el tiempo que tarda en recuperarse cada persona entre el numero de personas, L= suma de dias de cada individuo para recuperarse/'n' numero de personas. Gamma simplemente se
#calcula despejando la misma variable gamma de la ecuación.
#---------------------------------------------------------------------------------------------------------------------------------------------------
rho = 0.01 # fraccion inicial de nodos infectados. Los valores deben de estar entre 0<=rho<=1 ya que 0 representa el 0% de nodos iniciales infectados
# y 1 representa el 100% de los nodos infectados.
#---------------------------------------------------------------------------------------------------------------------------------------------------
kave = 5 # Grado promedio de conexiones en la red.
tau = 2 * gamma / kave # Tasa de transmisión. (Esta formula es parecida a la tasa de transmision de datos o información).
numero_de_individuos = 200
#Numero de individuos que se tendra en la poblacion a simular.
#--------------------------------------------------------------------------------------------------------------------------------------------------
#Llamado de la funcion la cual tiene como objetivo realizar toda la simulacion solo agregando parametros
generar_redes_transmision(t, tau, gamma, N, kave, rho, numero_de_individuos)
#Como se puede observar el codigo es muy parecido al algoritmo sim_red_dim_SIR.py (Se encuentra en el repositorio de GitHub) ya que el objetivo era trabajar mientras se generalizaba
#el proceso, para generar una red dinamica adecuada y reutilizable en el momento que sea necesario.
#Por eso mismo la generacion de funciones, para simplemente poder ensamblar partes del codigo y tener los calculos,
#datos y herramientas para futuros proyectos. Quien logre poner antecion en los comentarios de este codigo recuerden que
#este codigo me llevo horas extra de servicio social en el INMEGEN y bastante tiempo de analisis. (Echo por Jesús Mauricio Flores de Modelación Matemática SLT UACM)
#M4uroCube.