Mudanças entre as edições de "Modelos Epidemiológicos"

De Física Computacional
Ir para: navegação, pesquisa
(Implementação modelo SIR com quarentena voluntária)
(Implementação)
Linha 83: Linha 83:
 
== Implementação ==
 
== Implementação ==
  
Os códigos foram realizados na linguagem [https://en.wikipedia.org/wiki/C_(programming_language) C]
+
Os códigos da simulação foram implementados na linguagem [https://en.wikipedia.org/wiki/C_(programming_language) C], para a visualização foi utilizada a linguagem [https://pt.wikipedia.org/wiki/Python Python].
  
 
=== Implementação modelo SIR ===
 
=== Implementação modelo SIR ===
Linha 90: Linha 90:
  
 
=== Implementação modelo SIR com quarentena voluntária ===
 
=== Implementação modelo SIR com quarentena voluntária ===
 
 
  
 
Algumas modificações são realizadas no código anterior: a probabilidade do indivíduo passar de suscetível a infectado depende da escolha pela quarentena e é adicionada a parte da escolha individual.
 
Algumas modificações são realizadas no código anterior: a probabilidade do indivíduo passar de suscetível a infectado depende da escolha pela quarentena e é adicionada a parte da escolha individual.
Linha 150: Linha 148:
 
}
 
}
 
</source>
 
</source>
 +
 +
=== Visualização ===
 +
 +
#!/usr/bin/env python3
 +
# -*- coding: utf-8 -*-
 +
"""
 +
Graficos - trabalho
 +
"""
 +
 +
import matplotlib.pyplot as plt
 +
import pandas as pd
 +
import numpy as np
 +
from matplotlib import animation
 +
 +
#%% Read data
 +
 +
data = pd.read_csv('./output.txt',
 +
                    sep=" ", index_col=False)  # sir x tempo
 +
data.sort_values(by='t', ascending=True, inplace=True)
 +
 +
data.set_index('t', inplace=True)
 +
 +
 +
data_j = pd.read_csv('./output_jogo.txt',
 +
                    sep=" ", index_col=False)  # sir x tempo
 +
data_j.sort_values(by='t', ascending=True, inplace=True)
 +
 +
data_j.set_index('t', inplace=True)
 +
 +
#%% Visualization
 +
 +
data['total'] = data['r'] + data['i'] + data['s']
 +
 +
#%% SIR versus time
 +
 +
plt.title('Evolução temporal da doença')
 +
 +
data = data / data['s'][0]  # normalização da população
 +
# data_j = data_j / data_j['s'][0]  # normalização da população
 +
 +
plt.plot(data['r'], label='R')
 +
plt.plot(data['s'], label='S')
 +
plt.plot(data['i'], label='I')
 +
 +
# data_j = data_j / data_j['s'][0]  # normalização da população
 +
 +
# plt.plot(data_j['r'], label='R jogo')
 +
# plt.plot(data_j['s'], label='S jogo')
 +
# plt.plot(data_j['i'], label='I jogo')
 +
 +
plt.ylabel('Fração da população')
 +
plt.xlabel('Tempo')
 +
 +
plt.grid()
 +
 +
plt.legend()
 +
#%% Dinamica da quarentena voluntaria
 +
 +
dmc_loc = np.loadtxt('./dados/output_dinamica_loc.txt') # lê o arquivo
 +
#%%
 +
L = int(np.sqrt(np.shape(dmc_loc)[1]))
 +
 +
# forma uma malha LxL, pra poder plotar como se fosse x - y - z
 +
 +
x = y = np.arange(0, L, 1)
 +
 +
xv, yv = np.meshgrid(x, y)
 +
 +
 +
def animate(i):
 +
    plt.clf()  # limpa a figura, pra nao ficar sobrepondo figs
 +
 +
    # # titulos
 +
    plt.suptitle('Evolução da dinâmica de quarentenados', fontsize=14)
 +
    plt.title(f'Tempo: {i}', fontsize=10)
 +
   
 +
   
 +
    quarentena = np.zeros(shape=(L, L))
 +
   
 +
   
 +
    for j in range(L):
 +
       
 +
        quarentena[j] = dmc_loc[i, j*L : (j+1) * L]
 +
       
 +
    # # plot
 +
    graph = plt.scatter(xv,yv, c= quarentena, marker='.', vmax=1.0, vmin=0.0)
 +
   
 +
 +
    return graph
 +
 +
fig, ax = plt.subplots()
 +
ani = animation.FuncAnimation(fig, animate, frames = len(dmc_loc), repeat=False, interval=5)
 +
 +
 +
 +
#%% Reorganiza para plot da quantidade por tempo
 +
 +
quarentena, nao_quarentena = [], []
 +
 +
for i in range(len(dmc_loc)):
 +
   
 +
    quarentena.append(len(np.where(dmc_loc[i] == 0)[0])/2500)  # aqui trocar o divisor por L*L
 +
   
 +
   
 +
    nao_quarentena.append(len(np.where(dmc_loc[i] == 1)[0])/2500)  # aqui trocar o divisor por L*L
 +
   
 +
#%% Evolução da quantidade de quarentenados e infectados
 +
 +
fig, ax = plt.subplots()
 +
 +
ax2 = ax.twinx()
 +
 +
plt.title('Evolução da quantidade de quarentenados e infectados')
 +
 +
ax.plot(quarentena, label='QT', color='black', alpha=0.8)
 +
 +
# ax.plot(nao_quarentena, label='QN', color='red', alpha=0.6)
 +
 +
# ax.set_ylim(0, 1600*1.5)
 +
ax2.plot(data['i'], label='I')
 +
# ax.plot(data['r'], label='I')
 +
# ax.plot(data['s'], label='I')
 +
   
 +
ax.legend(loc='lower left')
 +
# ax2.legend(loc='lower right')
  
 
== Resultados ==  
 
== Resultados ==  

Edição das 21h39min de 22 de novembro de 2021

Em construção

Grupo: Gabriel Schmökel, Julia Remus e Luis Gustavo Lang Gaiato


O objetivo do trabalho é realizar a implementação do modelo SIR e de um modelo simplificado do proposto pelo artigo "An epidemiological model with voluntary quarantine strategies governed by evolutionary game dynamics" [1] utilizando Monte Carlo.

Será apresentada uma breve introdução sobre o tema e as equações que envolvem o desenvolvimento dos cálculos, as implementações e seus respectivos resultados.

Introdução

O objetivo do trabalho é realizar a implementação do modelo SIR e de um modelo simplificado do proposto pelo artigo "An epidemiological model with voluntary quarantine strategies governed by evolutionary game dynamics" [1] utilizando Monte Carlo.

O modelo apresentado por Marco Amaral, et al [1] propõe que o indivíduo escolha fazer a quarentena dependendo do risco que observa a partir da quantidade de infectados no sistema. Acoplada à escolha pela quarentena está o modelo SIR com parâmetros distintos para indivíduos não isolados e isolados. Para realizar a simulação os autores utilizam a teoria de campo médio, obtendo ondas de infecção ao longo do tempo.

Neste trabalho, a escolha do indivíduo pela quarentena se dará de acordo com o estado do seus vizinhos mais próximos - utilizado o dilema do prisioneiro -, enquanto a evolução dos infectados no sistema será realizada com o modelo SIR tal como na referência citada. Para a simulação foi utilizado o método de Monte Carlo.

O esquemático do modelo SIR com a escolha da quarentena pode ser visto na seção Modelo SIR com quarentena voluntária.

Modelos

Modelo SIR

Esquemáto modelo SIR

Esse modelo propõe dividir a população em três categorias:

  • Susceptível (S): um componente susceptível é aquele que ainda não passou e não possui a doença, mas poderá ser infectado em contato com I.
  • Infectado (I): um componente infectado com a doença.
  • Recuperado ou Removido (R): aquele que já passou pela doença e já está recuperado dela com imunidade (não pegará novamente); pode ser utilizado o compartimento como sendo de removidos, com o cuidado de retirá-los da simulação.

Modelo SIR com quarentena voluntária

Esquemáto modelo SIR com quarentena voluntária em suscetíveis

No esquemático pode-se ver o modelo utilizado no trabalho, ele é uma simplificação do artigo escrito por Amaral, et al [1]. Nele temos:

  • Componentes suscetíveis podem estar ou não em quarentena. A probabilidade para a escolha da quarentena ocorrer depende de quantos infectados há nos vizinhos.
  • Ao escolher estar ou não em quarentena, esses componentes tem probabilidades diferentes de adquirir a doença ( e ) e se tornar infectados.
  • Infectados possuem a mesma probabilidade de se tornarem recuperados.
  • Após recuperados da doença, as pessoas não conseguem adquiri-lá novamente.
  • Todos os indivíduos escolhem estar ou não isolados, modificando a escolha do vizinho, mas somente a quarentena dos suscetíveis afeta a evolução SIR.


Para simular a quarentena voluntária é utilizado o jogo definido pelo Dilema do Prisioneiro. Esse dilema descreve a situação onde dois condenados (A e B) precisam decidir se colaboram ou não sem saber a decisão do seu par. Para isso temos 4 possibilidades: A e B colaboram (ambos saem com uma recompensa R), A colabora mas B não colabora (B ficaria com o valor da tentação T e A com o custo do sonso S), o caso contrário onde A não colabora e B colabora e A e B não colaboram (ambos ganham com uma penalidade P). [2]

Essas possibilidades podem ser resumidas em uma matriz de perdas e ganhos (matriz de payoff):

A coopera A não coopera
B coopera R / R S / T
B não coopera T / S P / P


Os valores da matriz payoff devem obedecer a ordem T > R > P > S. Além disso, para simulações com várias iterações deve ser obedecido que 2R > T + S. [2]

A proposta de observar a evolução da infecção dependendo da quarentena precisa utilizar mais de um par de interagentes, por isso é definido uma rede onde cada componente possui um ponto fixo. A partir disso, cada um desses componentes interagem com seus quatro vizinhos mais próximos (para os pontos do contorno é utilizado que as bordas são unidas por condições de contorno periódicas). [2]

Segundo Hauert e Szabó [2], os colaboradores tendem a ser extintos em jogos que consideram a interação aleatória, independente da sua concentração inicial, ou seja, todos tendem a não ganhar nada (não colaborar mutuamente) a fim de reduzir custos. Enquanto isso, se for proposto que um componente só escolhe uma estratégia conforme seus vizinhos, é visto é a formação de clusters de cooperadores e de não cooperadores; com isso, os componentes que estão na borda desses espaços, ganham na interação com os vizinhos colaboradores e perdem com a outra interação.


Esse jogo de quarentena é acoplado ao sistema SIR anteriormente descrito. A única diferença para o SIR sem o jogo é que as probabilidades de um componente S se tornar infectado mudam a partir do seu estado de quarentena.

Implementação

Os códigos da simulação foram implementados na linguagem C, para a visualização foi utilizada a linguagem Python.

Implementação modelo SIR

Talvezzzz: Usar essa Analytical solution of SIR-model [3] pra verificar se o código funciona

Implementação modelo SIR com quarentena voluntária

Algumas modificações são realizadas no código anterior: a probabilidade do indivíduo passar de suscetível a infectado depende da escolha pela quarentena e é adicionada a parte da escolha individual.


A função do jogo (escolha pelo isolamento) é definido abaixo.

void jogo(int t){

    /*
    Dinâmica da escolha voluntária do quarentenado ou não
    */
	
    int sitio, i, j, k;
    double prob;
    double sums, sumv;
    int vizinho, dir;

    for (i=0;i<L2;i++){
	    
      sitio = FRANDOM * L2;
      dir = FRANDOM * 4 + 1;
      vizinho = viz[sitio][dir];
      sums = 0;
      sumv = 0;

      for(j=1 ; j < 5 ; j++) {
         sums += payoff[dmc_quarentena[sitio]][dmc_quarentena[viz[sitio][j]]];
         sumv += payoff[dmc_quarentena[vizinho]][dmc_quarentena[viz[vizinho][j]]];
      }
    
      prob = 1.0 / (1.0 + exp(-(sumv - sums) / TEMP ));
    
      if(FRANDOM > prob) {
      	dmc_quarentena[sitio] = dmc_quarentena[vizinho];
      }

    }

    // Escreve o estado de quarentena no arquivo, cada tempo uma linha

    FILE *dmcfile;
    char output2[10000];
    sprintf(output2, "output_dinamica_loc.txt");
    dmcfile = fopen(output2,"a");

    for(k=0; k<L2; k++){

      fprintf(dmcfile," %d ", dmc_quarentena[k]);

    }

    fprintf(dmcfile," \n ");
    fclose(dmcfile);

  return;
}

Visualização

  1. !/usr/bin/env python3
  2. -*- coding: utf-8 -*-

""" Graficos - trabalho """

import matplotlib.pyplot as plt import pandas as pd import numpy as np from matplotlib import animation

  1. %% Read data

data = pd.read_csv('./output.txt',

                   sep=" ", index_col=False)  # sir x tempo

data.sort_values(by='t', ascending=True, inplace=True)

data.set_index('t', inplace=True)


data_j = pd.read_csv('./output_jogo.txt',

                   sep=" ", index_col=False)  # sir x tempo

data_j.sort_values(by='t', ascending=True, inplace=True)

data_j.set_index('t', inplace=True)

  1. %% Visualization

data['total'] = data['r'] + data['i'] + data['s']

  1. %% SIR versus time

plt.title('Evolução temporal da doença')

data = data / data['s'][0] # normalização da população

  1. data_j = data_j / data_j['s'][0] # normalização da população

plt.plot(data['r'], label='R') plt.plot(data['s'], label='S') plt.plot(data['i'], label='I')

  1. data_j = data_j / data_j['s'][0] # normalização da população
  1. plt.plot(data_j['r'], label='R jogo')
  2. plt.plot(data_j['s'], label='S jogo')
  3. plt.plot(data_j['i'], label='I jogo')

plt.ylabel('Fração da população') plt.xlabel('Tempo')

plt.grid()

plt.legend()

  1. %% Dinamica da quarentena voluntaria

dmc_loc = np.loadtxt('./dados/output_dinamica_loc.txt') # lê o arquivo

  1. %%

L = int(np.sqrt(np.shape(dmc_loc)[1]))

  1. forma uma malha LxL, pra poder plotar como se fosse x - y - z

x = y = np.arange(0, L, 1)

xv, yv = np.meshgrid(x, y)


def animate(i):

   plt.clf()  # limpa a figura, pra nao ficar sobrepondo figs
   # # titulos
   plt.suptitle('Evolução da dinâmica de quarentenados', fontsize=14)
   plt.title(f'Tempo: {i}', fontsize=10)
   
   
   quarentena = np.zeros(shape=(L, L))
   
   
   for j in range(L):
       
       quarentena[j] = dmc_loc[i, j*L : (j+1) * L]
       
   # # plot
   graph = plt.scatter(xv,yv, c= quarentena, marker='.', vmax=1.0, vmin=0.0)
   
   return graph

fig, ax = plt.subplots() ani = animation.FuncAnimation(fig, animate, frames = len(dmc_loc), repeat=False, interval=5)


  1. %% Reorganiza para plot da quantidade por tempo

quarentena, nao_quarentena = [], []

for i in range(len(dmc_loc)):

   quarentena.append(len(np.where(dmc_loc[i] == 0)[0])/2500)  # aqui trocar o divisor por L*L
   
   
   nao_quarentena.append(len(np.where(dmc_loc[i] == 1)[0])/2500)  # aqui trocar o divisor por L*L
   
  1. %% Evolução da quantidade de quarentenados e infectados

fig, ax = plt.subplots()

ax2 = ax.twinx()

plt.title('Evolução da quantidade de quarentenados e infectados')

ax.plot(quarentena, label='QT', color='black', alpha=0.8)

  1. ax.plot(nao_quarentena, label='QN', color='red', alpha=0.6)
  1. ax.set_ylim(0, 1600*1.5)

ax2.plot(data['i'], label='I')

  1. ax.plot(data['r'], label='I')
  2. ax.plot(data['s'], label='I')

ax.legend(loc='lower left')

  1. ax2.legend(loc='lower right')

Resultados

Referências

  1. 1,0 1,1 1,2 1,3 AMARAL, Marco; OLIVEIRA, Marcelo de; JAVARONE, Marco, An epidemiological model with voluntary quarantine strategies governed by evolutionary game dynamics. arXiv:2008.05979v2 [physics.soc-ph] .
  2. 2,0 2,1 2,2 2,3 HAUERT, Christoph; SZABÓ, György. Game theory and physics. DOI: 10.1119/1.18485144 .
  3. Analytical solution of SIR-model