class Simulador(): SADIO = 0 INFECTADO_TIPO_1 = 1 #assintomáticos e o infectado inicial INFECTADO_TIPO_2 = 2 #sintomático CURADO = 3 MORTO = 4 def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica percentual_inicial_tipo1, #percentual inicial da população que será infectada tipo 1 percentual_inicial_tipo2, #percentual inicial da população que será infectada tipo 2 chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura ): #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 self.num_atualizacoes = 0 self.lista_infectados_tipo_2 = [] self.lista_infectados_tipo_1 = [] self.num_curados = 0 self.num_mortos = 0 self.chance_infeccao = chance_infeccao self.chance_infeccao_tipo2 = chance_infeccao_tipo2 self.chance_morte = chance_morte self.atualizacoes_cura = atualizacoes_cura self.populacao_inicial = int(tamanho_matriz**2) self.num_inicial_tipo2 = int(self.populacao_inicial * percentual_inicial_tipo2) self.num_inicial_tipo1 = 1 + int( self.populacao_inicial * percentual_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - ( self.num_inicial_tipo2 + self.num_inicial_tipo1) self.matriz_status = lil_matrix( (tamanho_matriz, tamanho_matriz), dtype=np.uint8 ) # np.zeros((tamanho_matriz, tamanho_matriz),dtype= np.uint8)# self.matriz_atualizacoes_cura = lil_matrix( (tamanho_matriz, tamanho_matriz), dtype=np.uint8 ) #np.zeros((tamanho_matriz, tamanho_matriz),dtype= np.uint8)# #self.matriz_status = self.df_individuos.to_numpy() self.popular(tamanho_matriz) self.lista_matrizes_status = [] #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) dict = { 'num_sadios': self.num_inicial_sadios, 'num_infect_t1': self.num_inicial_tipo1, 'num_infect_t2': self.num_inicial_tipo2, 'num_curados': 0, 'num_mortos': 0 } #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(dict, index=[0]) self.salvar_posicionamento() def criar_individuo(self, status, posicao): self.matriz_status[posicao[0], posicao[1]] = status if status == self.INFECTADO_TIPO_1 or status == self.INFECTADO_TIPO_2: self.matriz_atualizacoes_cura[posicao[0], posicao[1]] = self.atualizacoes_cura else: self.matriz_atualizacoes_cura[posicao[0], posicao[1]] = 0 def salvar_posicionamento(self): self.lista_matrizes_status.append(self.matriz_status) def verificar_infeccao(self, lista_infectantes): lista_novos_infectados_tipo1 = [] lista_novos_infectados_tipo2 = [] #itera sobre sobre a lista de individuos que infectam e cada um realiza a tividade de infectar for indice_infectante in lista_infectantes: #busca os vizinhos do infectante atual lista_vizinhos = self.matriz_esferica.get_vizinhos( indice_infectante) #Para cada vizinho, se ele for sadio, é gerado um número aleatório para verificar se foi infectado for indice_vizinho in lista_vizinhos: #verificação de SADIO if self.verifica_status(indice_vizinho) == self.SADIO: #verificação do novo status novo_status = self.infectar(chance_infeccao, chance_infeccao_tipo2) #se for um infectado tipo 1 if novo_status == Individuo.INFECTADO_TIPO_1: #adiciona na lista de novos tipo 1 lista_novos_infectados_tipo1.append(indice_vizinho) if novo_status == Individuo.INFECTADO_TIPO_2: #adiciona na lista de novos tipo 2 lista_novos_infectados_tipo2.append(indice_vizinho) return lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 def checagem_morte_individual(self, chance_morte): rng_morte = random.random() if rng_morte <= chance_morte: return self.MORTO else: return self.INFECTADO_TIPO_2 def checar_cura_individual(self, indice): self.matriz_atualizacoes_cura[ indice[0], indice[1]] = self.matriz_atualizacoes_cura[indice[0], indice[1]] - 1 if self.matriz_atualizacoes_cura[indice[0], indice[1]] == 0: return self.CURADO else: return self.matriz_status[indice[0], indice[1]] def checagem_morte_lista(self, lista_infectantes): lista_mortos = [] for indice_infectante in lista_infectantes: novo_status = self.checagem_morte_individual(self.chance_morte) if novo_status == Individuo.MORTO: lista_mortos.append(indice_infectante) return lista_mortos def checagem_cura_lista(self, lista_infectantes): lista_curados = [] for indice_infectante in lista_infectantes: novo_status = self.checar_cura_individual(indice_infectante) if novo_status == Individuo.CURADO: lista_curados.append(indice_infectante) return lista_curados def iterar(self): #Verifica os novos infectados por infectantes do tipo 1 e 2 #print(self.lista_infectados_tipo_1+self.lista_infectados_tipo_2) lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 = self.verificar_infeccao( self.lista_infectados_tipo_1 + self.lista_infectados_tipo_2) for indice in lista_novos_infectados_tipo1: self.criar_individuo(self.INFECTADO_TIPO_1, indice) for indice in lista_novos_infectados_tipo2: self.criar_individuo(self.INFECTADO_TIPO_2, indice) #Verifica morte dos infectados tipo 2 lista_mortos = self.checagem_morte_lista(self.lista_infectados_tipo_2) #retira os indices dos individuos mortos da lista de infectados self.lista_infectados_tipo_2 = [ indice for indice in self.lista_infectados_tipo_2 if indice not in lista_mortos ] #Instancia individuos mortos na matriz for indice in lista_mortos: self.criar_individuo(self.MORTO, indice) #atualiza o número de mortos na matriz self.num_mortos = self.num_mortos + len(lista_mortos) #Verifica cura dos infectados tipo 1 lista_curados_t1 = self.checagem_cura_lista( self.lista_infectados_tipo_1) #Verifica cura dos infectados tipo 2 lista_curados_t2 = self.checagem_cura_lista( self.lista_infectados_tipo_2) #Instancia individuos mortos na matriz for indice in lista_curados_t1 + lista_curados_t2: self.criar_individuo(self.CURADO, indice) #atualiza o número de curados na matriz self.num_curados = self.num_curados + len(lista_curados_t1 + lista_curados_t2) #Atualiza a lista de infectados após a cura dos individuos self.lista_infectados_tipo_1 = [ indice for indice in self.lista_infectados_tipo_1 if indice not in lista_curados_t1 ] self.lista_infectados_tipo_2 = [ indice for indice in self.lista_infectados_tipo_2 if indice not in lista_curados_t2 ] #movimentação nova_lista_t1 = [] for indice in self.lista_infectados_tipo_1: nova_lista_t1.append(self.mover_infectante(indice)) self.lista_infectados_tipo_1 = nova_lista_t1 nova_lista_t2 = [] for indice in self.lista_infectados_tipo_2: nova_lista_t2.append(self.mover_infectante(indice)) self.lista_infectados_tipo_2 = nova_lista_t2 matriz_infectantes = self.matriz_status[ (self.matriz_status == self.INFECTADO_TIPO_1) + (self.matriz_status == self.INFECTADO_TIPO_2)] # matriz_infectantes = matriz_infectantes[matriz_infectantes < 3] indices_infectados = list(zip(*self.matriz_status.nonzero())) #indices_infectados = [indice in indices_infectados if indice not in self.lista_infectados_tipo_1 and indice not in self.lista_infectados_tipo_1 ] # self.num_curados = 0 #self.num_mortos = 0 novos_infectados_tipo_1 = [] novos_infectados_tipo_2 = [] for indice in indices_nao_sadios: status = self.matriz_status[indice[0], indice[1]] if status == self.INFECTADO_TIPO_1: novos_infectados_tipo_1.append(indice) # self.lista_infectados_tipo_1.append(indice) if status == self.INFECTADO_TIPO_2: novos_infectados_tipo_2.append(indice) # self.lista_infectados_tipo_2.append(indice) # if status == self.CURADO: # self.num_curados +=1 # if status == self.MORTO: # self.num_mortos +=1 self.lista_infectados_tipo_1 = self.lista_infectados_tipo_1 + novos_infectados_tipo_1 self.lista_infectados_tipo_2 = self.lista_infectados_tipo_2 + novos_infectados_tipo_1 dict = { 'num_sadios': self.populacao_inicial - len(self.lista_infectados_tipo_1) - len(self.lista_infectados_tipo_2) - self.num_curados - self.num_mortos, 'num_infect_t1': len(self.lista_infectados_tipo_1), 'num_infect_t2': len(self.lista_infectados_tipo_2), 'num_curados': self.num_curados, 'num_mortos': self.num_mortos } self.dataframe = self.dataframe.append(dict, ignore_index=True) self.salvar_posicionamento() #adiciona 1 ao número de atualizações realizadas na matriz self.num_atualizacoes += 1 def infectar(self, chance_infeccao, chance_infeccao_tipo2): saida = Individuo.SADIO #número aleatório para chance de infectar o vizinho rng_infeccao = random.random() if rng_infeccao <= chance_infeccao: #número aleatório para chance de infecção tipo 1 ou 2 rng_infeccao_tipo2 = random.random() if rng_infeccao_tipo2 <= chance_infeccao_tipo2: saida = Individuo.INFECTADO_TIPO_2 else: saida = Individuo.INFECTADO_TIPO_1 return saida def popular(self, tamanho_matriz): #lista de possíveis combinações de índices da matriz de dados permutacoes = permutations(list(range(tamanho_matriz)), 2) #conversão para lista de tuplas(x,y) lista_indices = list(permutacoes) #embaralhamento dos índices random.shuffle(lista_indices) #cria o primeiro tipo1: indice = lista_indices.pop() self.criar_individuo(Individuo.INFECTADO_TIPO_1, indice) self.lista_infectados_tipo_1.append(indice) #cria o restante dos tipos 1 for i in range(self.num_inicial_tipo1 - 1): indice = lista_indices.pop() self.criar_individuo(Individuo.INFECTADO_TIPO_1, indice) self.lista_infectados_tipo_1.append(indice) #cria o restante dos tipo 2: for indice in range(self.num_inicial_tipo2): indice = lista_indices.pop() self.criar_individuo(Individuo.INFECTADO_TIPO_2, indice) self.lista_infectados_tipo_2.append(indice) def trocar(self, matriz, ponto_ini, ponto_final): x_ini = ponto_ini[0] y_ini = ponto_ini[1] x_fin = ponto_final[0] y_fin = ponto_final[1] aux = matriz[x_fin, y_fin] matriz[x_fin, y_fin] = matriz[x_ini, y_ini] matriz[x_ini, y_ini] = aux def verifica_status(self, indice): return self.matriz_status[indice[0], indice[1]] def mover_infectante(self, posicao_inicial): pos_x, pos_y = posicao_inicial[0], posicao_inicial[1] rng_posicao = random.random() if rng_posicao <= 0.25: #move pra cima pos_x -= 1 elif rng_posicao <= 0.5: #move pra baixo pos_x += 1 elif rng_posicao <= 0.75: #move para esquerda pos_y -= 1 else: #move para direita pos_y += 1 posicao_final = self.matriz_esferica.valida_ponto_matriz(pos_x, pos_y) self.trocar(self.matriz_status, posicao_inicial, posicao_final) self.trocar(self.matriz_atualizacoes_cura, posicao_inicial, posicao_final) return posicao_final
class Simulador(): def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica percentual_inicial_tipo1, #percentual inicial da população que será infectada tipo 1 percentual_inicial_tipo2, #percentual inicial da população que será infectada tipo 2 chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura ): #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 self.num_atualizacoes = 0 self.lista_infectados_tipo_2 = [] self.lista_infectados_tipo_1 = [] self.num_curados = 0 self.num_mortos = 0 self.chance_infeccao = chance_infeccao self.chance_infeccao_tipo2 = chance_infeccao_tipo2 self.chance_morte = chance_morte self.atualizacoes_cura = atualizacoes_cura self.populacao_inicial = int(tamanho_matriz**2) self.num_inicial_tipo2 = int(self.populacao_inicial * percentual_inicial_tipo2) self.num_inicial_tipo1 = 1 + int( self.populacao_inicial * percentual_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - ( self.num_inicial_tipo2 + self.num_inicial_tipo1) self.df_individuos = pd.DataFrame(self.criar_individuo( Individuo.SADIO, (0, 0)), index=range(tamanho_matriz), columns=range(tamanho_matriz)) self.matriz_status = lil_matrix((tamanho_matriz, tamanho_matriz), dtype=np.uint8) #self.matriz_status = self.df_individuos.to_numpy() self.popular(tamanho_matriz) self.lista_matrizes_posicionamento = [] #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) dict = { 'num_sadios': self.num_inicial_sadios, 'num_infect_t1': self.num_inicial_tipo1, 'num_infect_t2': self.num_inicial_tipo2, 'num_curados': 0, 'num_mortos': 0 } #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(dict, index=[0]) self.salvar_posicionamento() def criar_individuo(self, status, posicao): return Individuo(status, self.atualizacoes_cura, posicao) def salvar_posicionamento(self): self.matriz_status = self.df_individuos.to_numpy() self.lista_matrizes_posicionamento.append(self.matriz_status) def verificar_infeccao(self, lista_infectantes): lista_novos_infectados_tipo1 = [] lista_novos_infectados_tipo2 = [] #itera sobre sobre a lista de individuos que infectam e cada um realiza a tividade de infectar print(lista_infectantes) for X, Y in lista_infectantes: print("Infectante na posição: ", (X, Y)) #busca os vizinhos do infectante atual lista_vizinhos = self.matriz_esferica.get_vizinhos(X, Y) print("Lista vizinhos: ", lista_vizinhos) #Para cada vizinho, se ele for sadio, é gerado um número aleatório para verificar se foi infectado for x, y in lista_vizinhos: print("posição vizinho: ", (x, y)) print("tipo de individuo ", type(self.df_individuos.iloc[x, y])) #verificação de SADIO if self.df_individuos[x][y].status == Individuo.SADIO: #verificação do novo status novo_status = self.infectar(chance_infeccao, chance_infeccao_tipo2) #se for um infectado tipo 1 if novo_status == Individuo.INFECTADO_TIPO_1: #adiciona na lista de novos tipo 1 lista_novos_infectados_tipo1.append((x, y)) #modifica o status na matriz de status print( "Tipo antes de atribuir: ", self.criar_individuo(Individuo.INFECTADO_TIPO_1, (x, y))) self.df_individuos.iloc[x, y] = self.criar_individuo( Individuo.INFECTADO_TIPO_1, (x, y)) print("Tipo depois de atribuir: ", self.df_individuos.loc[x, y]) self.matriz_status[x, y] = Individuo.INFECTADO_TIPO_1 if novo_status == Individuo.INFECTADO_TIPO_2: #adiciona na lista de novos tipo 2 lista_novos_infectados_tipo2.append((x, y)) #modifica o status na matriz de status self.df_individuos.iloc[x, y] = self.criar_individuo( Individuo.INFECTADO_TIPO_2, (x, y)) self.matriz_status[x, y] = Individuo.INFECTADO_TIPO_2 print(self.df_individuos) return lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 def verificar_morte(self, lista_infectantes_tipo2): lista_curados = [] lista_mortos = [] for x, y in lista_infectantes_tipo2: novo_status = self.df_individuos.loc[x, y].checagem_morte( self.chance_morte) if novo_status == Individuo.MORTO: self.matriz_status[x, y] = Individuo.MORTO lista_mortos.append((x, y)) if novo_status == Individuo.CURADO: self.matriz_status[x, y] = Individuo.CURADO lista_curados.append((x, y)) return lista_mortos, lista_curados def verificar_cura(self, lista_infectantes): lista_curados = [] for x, y in lista_infectantes: print("AQUI======>: ", self.df_individuos.loc[x, y]) novo_status = self.df_individuos.loc[x, y].checagem_cura() if novo_status == Individuo.CURADO: self.matriz_status[x, y] = Individuo.CURADO lista_curados.append((x, y)) return lista_curados def iterar(self): #Verifica os novos infectados a partir dos atuais infectantes na matriz lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 = self.verificar_infeccao( self.lista_infectados_tipo_1) lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 = self.verificar_infeccao( self.lista_infectados_tipo_2) #Verifica morte dos tipo 2 lista_mortos_atualizacao, lista_curados_t2_atualizacao = self.verificar_morte( self.lista_infectados_tipo_2) self.lista_infectados_tipo_2 = [ indice for indice in self.lista_infectados_tipo_2 if indice not in lista_mortos_atualizacao and indice not in lista_curados_t2_atualizacao ] #atualiza o novo número de mortos self.num_mortos += len(lista_mortos_atualizacao) #Verificar cura lista_curados_t1_atualizacao = self.verificar_cura( self.lista_infectados_tipo_1) self.lista_infectados_tipo_1 = [ indice for indice in self.lista_infectados_tipo_1 if indice not in lista_curados_t1_atualizacao ] #adiciona os novos curados na lista geral de curados self.num_curados = self.num_curados + len( lista_curados_t1_atualizacao) + len(lista_curados_t2_atualizacao) # self. #movimentar infectantes: # for x,y in self.lista_infectados_tipo_1: # self.mover_infectante((x,y)) # for x,y in self.lista_infectados_tipo_2: # self.mover_infectante((x,y)) #adicionar os novos infectados tipo 1 e 2 para as respectivas listas self.lista_infectados_tipo_2 = self.lista_infectados_tipo_2 + lista_novos_infectados_tipo2 self.lista_infectados_tipo_1 = self.lista_infectados_tipo_1 + lista_novos_infectados_tipo1 dict = { 'num_sadios': self.populacao_inicial - self.num_mortos - self.num_curados - len(self.lista_infectados_tipo_1) - len(self.lista_infectados_tipo_2), 'num_infect_t1': len(self.lista_infectados_tipo_1), 'num_infect_t2': len(self.lista_infectados_tipo_2), 'num_curados': self.num_curados, 'num_mortos': self.num_mortos } self.dataframe = self.dataframe.append(dict, ignore_index=True) print("num t1: ", len(self.lista_infectados_tipo_1)) print("num t2: ", len(self.lista_infectados_tipo_2)) print("num curados: ", self.num_curados) print("num mortos: ", self.num_mortos) print("---------") #salva a nova matriz de status self.salvar_posicionamento() #adiciona 1 ao número de atualizações realizadas na matriz self.num_atualizacoes += 1 def infectar(self, chance_infeccao, chance_infeccao_tipo2): saida = Individuo.SADIO #número aleatório para chance de infectar o vizinho rng_infeccao = random.random() if rng_infeccao <= chance_infeccao: #número aleatório para chance de infecção tipo 1 ou 2 rng_infeccao_tipo2 = random.random() if rng_infeccao_tipo2 <= chance_infeccao_tipo2: saida = Individuo.INFECTADO_TIPO_2 else: saida = Individuo.INFECTADO_TIPO_1 return saida def popular(self, tamanho_matriz): #self.df_individuos.iloc[:,:] = self.criar_individuo(Individuo.SADIO,(0,0)) #lista de possíveis combinações de índices da matriz de dados permutacoes = permutations(list(range(tamanho_matriz)), 2) #conversão para lista de tuplas(x,y) lista_indices = list(permutacoes) #embaralhamento dos índices random.shuffle(lista_indices) #cria o primeiro tipo1: indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.lista_infectados_tipo_1.append((ind_x, ind_y)) #print(indice) self.df_individuos.loc[ind_x, ind_y] = self.criar_individuo( Individuo.INFECTADO_TIPO_1, (ind_x, ind_y)) #print(self.df_individuos) self.matriz_status[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 #cria o restante dos tipos 1 for i in range(1, self.num_inicial_tipo1): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.lista_infectados_tipo_1.append((ind_x, ind_y)) self.df_individuos.loc[ind_x, ind_y] = self.criar_individuo( Individuo.INFECTADO_TIPO_1, (ind_x, ind_y)) self.matriz_status[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 #cria o restante dos tipo 2: for indice in range(self.num_inicial_tipo2): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.lista_infectados_tipo_2.append((ind_x, ind_y)) self.df_individuos.loc[ ind_x, ind_y] = self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_2, (ind_x, ind_y)) self.matriz_status[ind_x, ind_y] = Individuo.INFECTADO_TIPO_2 def trocar_status_localizacao(self, ponto_ini, ponto_final): x_ini = ponto_ini[0] y_ini = ponto_ini[1] x_fin = ponto_final[0] y_fin = ponto_final[1] aux = self.df_individuos.loc[x_fin, y_fin] print("Aux2====>: ", self.df_individuos.loc[x_fin, y_fin]) self.df_individuos.loc[x_fin, y_fin], self.df_individuos.loc[ x_ini, y_ini] = self.df_individuos.loc[ x_ini, y_ini], self.df_individuos.loc[x_fin, y_fin] # self.df_individuos.loc[x_fin,y_fin] = self.df_individuos.loc[x_ini,y_ini] # self.df_individuos.loc[x_ini,y_ini] = aux2 self.matriz_status[x_fin, y_fin] = self.df_individuos.loc[x_fin, y_fin].status self.matriz_status[x_ini, y_ini] = self.df_individuos.loc[x_ini, y_ini].status def mover_infectante(self, posicao_inicial): pos_x, pos_y = posicao_inicial[0], posicao_inicial[1] rng_posicao = random.random() if rng_posicao <= 0.25: #move pra cima pos_x -= 1 elif rng_posicao <= 0.5: #move pra baixo pos_x += 1 elif rng_posicao <= 0.75: #move para esquerda pos_y -= 1 else: #move para direita pos_y += 1 posicao_final = self.matriz_esferica.valida_ponto_matriz(pos_x, pos_y) self.trocar_status_localizacao(posicao_inicial, posicao_final)
def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura, #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 inserir_infectados_aleatorios): self.num_atualizacoes = 0 self.lista_infectados_tipo_2 = [] self.lista_infectados_tipo_1 = [] self.num_curados = 0 self.num_mortos = 0 self.chance_infeccao = chance_infeccao self.chance_infeccao_tipo2 = chance_infeccao_tipo2 self.chance_morte = chance_morte self.atualizacoes_cura = atualizacoes_cura self.populacao_inicial = int(tamanho_matriz**2) num_inicial_infectados = random.randint( 0, tamanho_matriz * tamanho_matriz - 1) proporcao_t1_t2 = random.random() self.num_inicial_tipo1 = round(inserir_infectados_aleatorios * proporcao_t1_t2 * num_inicial_infectados) print("self.num_inicial_tipo1: ", self.num_inicial_tipo1) self.num_inicial_tipo2 = round(inserir_infectados_aleatorios * (1 - proporcao_t1_t2) * num_inicial_infectados) print("self.num_inicial_tipo2: ", self.num_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - ( self.num_inicial_tipo2 + self.num_inicial_tipo1) self.matriz_status = np.zeros( (tamanho_matriz, tamanho_matriz), dtype=np.uint8 ) #lil_matrix((tamanho_matriz, tamanho_matriz),dtype= np.uint8) # self.matriz_atualizacoes_cura = np.zeros( (tamanho_matriz, tamanho_matriz), dtype=np.uint8 ) #lil_matrix((tamanho_matriz, tamanho_matriz),dtype= np.uint8)# self.dict_resumo = {} #self.matriz_status = self.df_individuos.to_numpy() self.popular(tamanho_matriz) self.lista_matrizes_status = [] #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) dict = { 'num_sadios': self.num_inicial_sadios, 'num_infect_t1': self.num_inicial_tipo1, 'num_infect_t2': self.num_inicial_tipo2, 'num_curados': 0, 'num_mortos': 0 } #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(dict, index=[0]) self.salvar_posicionamento()
class Simulador(): def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica percentual_inicial_tipo1, #percentual inicial da população que será infectada tipo 1 percentual_inicial_tipo2, #percentual inicial da população que será infectada tipo 2 chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura ): #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 self.num_atualizacoes = 0 self.lista_infectados_tipo_2 = [] self.lista_infectados_tipo_1 = [] self.num_curados = 0 self.num_mortos = 0 self.chance_infeccao = chance_infeccao self.chance_infeccao_tipo2 = chance_infeccao_tipo2 self.chance_morte = chance_morte self.populacao_inicial = int(tamanho_matriz**2) self.num_inicial_tipo2 = int(self.populacao_inicial * percentual_inicial_tipo2) self.num_inicial_tipo1 = int(self.populacao_inicial * percentual_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - ( self.num_inicial_tipo2 + self.num_inicial_tipo1) self.fabrica_individuo = Fabrica_individuo(atualizacoes_cura) self.df_individuos = pd.DataFrame(index=range(tamanho_matriz), columns=range(tamanho_matriz)) self.popular(tamanho_matriz) self.lista_matrizes_posicionamento = [] #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) self.matriz_status = lil_matrix((tamanho_matriz, tamanho_matriz), dtype=np.uint8) dict = { 'num_sadios': self.num_inicial_sadios, 'num_infect_t1': self.num_inicial_tipo1, 'num_infect_t2': self.num_inicial_tipo2, 'num_curados': 0, 'num_mortos': 0 } #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(index=[0]) self.salvar_posicionamento() def salvar_posicionamento(self): self.lista_matrizes_posicionamento.append(self.matriz_status) def verificar_infeccao(self, lista_infectantes): lista_novos_infectados_tipo1 = [] lista_novos_infectados_tipo2 = [] #itera sobre sobre a lista de individuos que infectam e cada um realiza a tividade de infectar for X, Y in lista_infectantes: #busca os vizinhos do infectante atual lista_vizinhos = self.matriz_esferica.get_vizinhos(X, Y) #Para cada vizinho, se ele for sadio, é gerado um número aleatório para verificar se foi infectado for x, y in lista_vizinhos: #verificação de SADIO if self.matriz_status[x, y] == Individuo.SADIO: #verificação do novo status novo_status = self.infectar(chance_infeccao, chance_infeccao_tipo2) #se for um infectado tipo 1 if novo_status == Individuo.INFECTADO_TIPO_1: #adiciona na lista de novos tipo 1 lista_novos_infectados_tipo1.append((x, y)) #modifica o status na matriz de status self.df_individuos.loc[ x, y] = self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_1, (x, y)) self.matriz_status[x, y] = Individuo.INFECTADO_TIPO_1 if novo_status == Individuo.INFECTADO_TIPO_2: #adiciona na lista de novos tipo 2 lista_novos_infectados_tipo2.append((x, y)) #modifica o status na matriz de status self.df_individuos.loc[ x, y] = self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_2, (x, y)) self.matriz_status[x, y] = Individuo.INFECTADO_TIPO_2 return lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 def verificar_morte(self, lista_infectantes_tipo2): num_mortos = 0 num_curados = 0 for x, y in lista_infectantes_tipo2: novo_status = self.df_individuos.loc[x, y].checagem_morte( self.chance_morte) if novo_status == Individuo.MORTO: num_mortos += 1 self.matriz_status[x, y] = Individuo.MORTO lista_infectantes_tipo2.remove((x, y)) if novo_status == Individuo.CURADO: num_curados += 1 self.matriz_status[x, y] = Individuo.CURADO lista_infectantes_tipo2.remove((x, y)) return num_mortos, num_curados def verificar_cura(self, lista_infectantes): num_curados = 0 for x, y in lista_infectantes: novo_status = self.df_individuos.loc[x, y].checagem_cura() if novo_status == Individuo.CURADO: num_curados += 1 self.matriz_status[x, y] = Individuo.CURADO lista_infectantes.remove((x, y)) return num_curados def iterar(self): #Verifica os novos infectados a partir dos atuais infectantes na matriz lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 = self.verificar_infeccao( self.lista_infectados_tipo_1 + self.lista_infectados_tipo_2) #Verifica morte dos tipo 2 num_mortos_atualizacao, num_curados_t2_atualizacao = self.verificar_morte( self.lista_infectados_tipo_2) # #retirar os mortos da atualização da lista de infectados tipo 2 # self.lista_infectados_tipo_2 = [i for i in self.lista_infectados_tipo_2 if i.status != Individuo.MORTO] #atualiza o novo número de mortos self.num_mortos += num_mortos_atualizacao #Verificar cura num_curados_t1_atualizacao = self.verificar_cura( self.lista_infectados_tipo_1) # #retirar os curados das lista de infectados tipo 1 e 2 # self.lista_infectados_tipo_2 = [i for i in self.lista_infectados_tipo_2 if i.status != Individuo.CURADO] # self.lista_infectados_tipo_1 = [i for i in self.lista_infectados_tipo_1 if i.status != Individuo.CURADO] #adiciona os novos curados na lista geral de curados self.num_curados = self.num_curados + num_curados_t1_atualizacao + num_curados_t2_atualizacao # self. #movimentar infectantes: for x, y in self.lista_infectados_tipo_1: self.mover_infectante((x, y)) for x, y in self.lista_infectados_tipo_2: self.mover_infectante((x, y)) #adicionar os novos infectados tipo 1 e 2 para as respectivas listas self.lista_infectados_tipo_2 = self.lista_infectados_tipo_2 + lista_novos_infectados_tipo2 self.lista_infectados_tipo_1 = self.lista_infectados_tipo_1 + lista_novos_infectados_tipo1 num_tipo_1 = len(self.lista_infectados_tipo_1) num_tipo_2 = len(self.lista_infectados_tipo_2) dict = { 'num_sadios': self.populacao_inicial - self.num_mortos - self.num_curados - num_tipo_1 - num_tipo_2, 'num_infect_t1': num_tipo_1, 'num_infect_t2': num_tipo_2, 'num_curados': self.num_curados, 'num_mortos': self.num_mortos } self.dataframe = self.dataframe.append(dict, ignore_index=True) print("num t1: ", num_tipo_1) print("num t2: ", num_tipo_2) print("num curados: ", self.num_curados) print("num mortos: ", self.num_mortos) print("---------") #salva a nova matriz de status self.salvar_posicionamento() #adiciona 1 ao número de atualizações realizadas na matriz self.num_atualizacoes += 1 def infectar(self, chance_infeccao, chance_infeccao_tipo2): saida = Individuo.SADIO #número aleatório para chance de infectar o vizinho rng_infeccao = random.random() if rng_infeccao <= chance_infeccao: #número aleatório para chance de infecção tipo 1 ou 2 rng_infeccao_tipo2 = random.random() if rng_infeccao_tipo2 <= chance_infeccao_tipo2: saida = Individuo.INFECTADO_TIPO_2 else: saida = Individuo.INFECTADO_TIPO_1 return saida def popular(self, tamanho_matriz): # for index, row in self.df_individuos.iterrows(): # for item in row: # item = self.fabrica_individuo.criar_individuo(Individuo.SADIO,(0,0)) self.df_individuos.iloc[:, :] = self.fabrica_individuo.criar_individuo( Individuo.SADIO, (0, 0)) #lista de possíveis combinações de índices da matriz de dados permutacoes = permutations(list(range(tamanho_matriz)), 2) #conversão para lista de tuplas(x,y) lista_indices = list(permutacoes) #embaralhamento dos índices random.shuffle(lista_indices) #cria o primeiro tipo1: indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.lista_infectados_tipo_1.append((ind_x, ind_y)) self.df_individuos.loc[ind_x, ind_y] = self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_1, (ind_x, ind_y)) #cria o restante dos tipos 1 for i in range(1, self.num_inicial_tipo1): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.lista_infectados_tipo_1.append((ind_x, ind_y)) self.df_individuos.loc[ ind_x, ind_y] = self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_1, (ind_x, ind_y)) #cria o restante dos tipo 2: for indice in range(self.num_inicial_tipo2): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.lista_infectados_tipo_2.append((ind_x, ind_y)) self.df_individuos.loc[ ind_x, ind_y] = self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_2, (ind_x, ind_y)) def trocar_status_localizacao(self, ponto_ini, ponto_final): x_ini = ponto_ini[0] y_ini = ponto_ini[1] x_fin = ponto_final[0] y_fin = ponto_final[1] aux1 = self.matriz_status[x_fin, y_fin] self.matriz_status[x_fin, y_fin] = self.matriz_status[x_ini, y_ini] self.matriz_status[x_ini, y_ini] = aux1 aux2 = self.df_individuos.loc[x_fin, y_fin] self.df_individuos.loc[x_fin, y_fin] = self.df_individuos.loc[x_ini, y_ini] self.df_individuos.loc[x_ini, y_ini] = aux2 def mover_infectante(self, posicao_inicial): pos_x, pos_y = posicao_inicial[0], posicao_inicial[1] rng_posicao = random.random() if rng_posicao <= 0.25: #move pra cima pos_x -= 1 elif rng_posicao <= 0.5: #move pra baixo pos_x += 1 elif rng_posicao <= 0.75: #move para esquerda pos_y -= 1 else: #move para direita pos_y += 1 novo_x, novo_y = self.matriz_esferica.valida_ponto_matriz(pos_x, pos_y) #descobre qual individuo ocupa atualmente a posição para atribuí-lo a posição de quem o está substituindo status = self.matriz_status[novo_x, novo_y] # if status == Individuo.INFECTADO_TIPO_1: # individuo_ocupante_destino = self.matriz_localizacao[novo_x, novo_y] # print(status) # print(individuo_ocupante_destino) # print(len(self.lista_infectados_tipo_1)) # self.lista_infectados_tipo_1[individuo_ocupante_destino].posicao = infectante.posicao # elif status == Individuo.INFECTADO_TIPO_2: # individuo_ocupante_destino = self.matriz_localizacao[novo_x, novo_y] # print(status) # print(individuo_ocupante_destino) # print(len(self.lista_infectados_tipo_2)) # self.lista_infectados_tipo_2[individuo_ocupante_destino].posicao = infectante.posicao # elif status == Individuo.CURADO: # individuo_ocupante_destino = self.matriz_localizacao[novo_x, novo_y] # self.lista_curados[individuo_ocupante_destino].posicao = infectante.posicao # elif status == Individuo.MORTO: # individuo_ocupante_destino = self.matriz_localizacao[novo_x, novo_y] # self.lista_matrizes_posicionamento[individuo_ocupante_destino].posicao = infectante.posicao self.trocar_status_localizacao(posicao_inicial, (novo_x, novo_y))
class Simulador(): def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica percentual_inicial_tipo1, #percentual inicial da população que será infectada tipo 1 percentual_inicial_tipo2, #percentual inicial da população que será infectada tipo 2 chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura ): #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 self.num_atualizacoes = 0 self.lista_infectados_tipo_2 = [] self.lista_infectados_tipo_1 = [] self.lista_curados = [] self.lista_mortos = [] #lista que guarda o posicionamento self.lista_matrizes_posicionamento = [] #guarda em matriz esparsa o status de saúde de cada elemento self.matriz_status = lil_matrix((tamanho_matriz, tamanho_matriz), dtype=np.uint8) #guarda em matriz esparsa a localização do objeto em sua respectiva lista self.matriz_localizacao = lil_matrix((tamanho_matriz, tamanho_matriz), dtype=np.uint32) self.fabrica_individuo = Fabrica_individuo(chance_infeccao, chance_infeccao_tipo2, chance_morte, atualizacoes_cura) #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) self.populacao_inicial = int(tamanho_matriz**2) self.num_inicial_tipo2 = int(self.populacao_inicial * percentual_inicial_tipo2) self.num_inicial_tipo1 = int(self.populacao_inicial * percentual_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - ( self.num_inicial_tipo2 + self.num_inicial_tipo1) self.popular(tamanho_matriz) dict = { 'num_sadios': self.num_inicial_sadios, 'num_infect_t1': self.num_inicial_tipo1, 'num_infect_t2': self.num_inicial_tipo2, 'num_curados': 0, 'num_mortos': 0 } #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(index=[0]) self.salvar_posicionamento() def salvar_posicionamento(self): self.lista_matrizes_posicionamento.append(self.matriz_status) def verificar_infeccao(self, lista_infectantes): lista_novos_infectados_tipo1 = [] lista_novos_infectados_tipo2 = [] #itera sobre sobre a lista de individuos que infectam e cada um realiza a tividade de infectar for infectante in lista_infectantes: indice_x = infectante.posicao[0] indice_y = infectante.posicao[1] #busca os vizinhos do infectante atual lista_vizinhos = self.matriz_esferica.get_vizinhos( indice_x, indice_y) #Para cada vizinho, se ele for sadio, é gerado um número aleatório para verificar se foi infectado for vizinho in lista_vizinhos: x = vizinho[0] y = vizinho[1] #verificação de SADIO if self.matriz_status[x, y] == Individuo.SADIO: #verificação do novo status novo_status = infectante.infectar() #se for um infectado tipo 1 if novo_status == Individuo.INFECTADO_TIPO_1: #adiciona na lista de novos tipo 1 lista_novos_infectados_tipo1.append( self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_1, (x, y))) #modifica o status na matriz de status self.matriz_status[x, y] = Individuo.INFECTADO_TIPO_1 self.matriz_localizacao[ x, y] = len(lista_novos_infectados_tipo1) - 1 if novo_status == Individuo.INFECTADO_TIPO_2: #adiciona na lista de novos tipo 2 lista_novos_infectados_tipo2.append( self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_2, (x, y))) #modifica o status na matriz de status self.matriz_status[x, y] = Individuo.INFECTADO_TIPO_2 self.matriz_localizacao[ x, y] = len(lista_novos_infectados_tipo2) - 1 return lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 def verificar_morte(self, lista_infectantes_tipo2): lista_mortos = [] for infectante in lista_infectantes_tipo2: novo_status = infectante.checagem_morte() if novo_status == Individuo.MORTO: lista_mortos.append(infectante) self.matriz_status[infectante.posicao[0], infectante.posicao[1]] = Individuo.MORTO return lista_mortos def verificar_cura(self, lista_infectantes): lista_curados = [] for infectante in lista_infectantes: novo_status = infectante.checagem_cura() if novo_status == Individuo.CURADO: lista_curados.append(indice) self.matriz_status[infectante.posicao[0], infectante.posicao[1]] = Individuo.CURADO return lista_curados def iterar(self): #Verifica os novos infectados a partir dos atuais infectantes na matriz lista_novos_infectados_tipo1_1, lista_novos_infectados_tipo2_1 = self.verificar_infeccao( self.lista_infectados_tipo_1) lista_novos_infectados_tipo1_2, lista_novos_infectados_tipo2_2 = self.verificar_infeccao( self.lista_infectados_tipo_2) #Verifica morte dos tipo 2 lista_mortos = self.verificar_morte(self.lista_infectados_tipo_2) #retirar os mortos da atualização da lista de infectados tipo 2 self.lista_infectados_tipo_2 = [ i for i in self.lista_infectados_tipo_2 if i not in lista_mortos ] #adiciona os novos mortos na lista geral de mortos self.lista_mortos = self.lista_mortos + lista_mortos #Verificar cura lista_curados_tipo1 = self.verificar_cura(self.lista_infectados_tipo_1) lista_curados_tipo2 = self.verificar_cura(self.lista_infectados_tipo_2) #retirar os curados das lista de infectados tipo 1 e 2 self.lista_infectados_tipo_2 = [ i for i in self.lista_infectados_tipo_2 if i not in lista_curados_tipo2 ] self.lista_infectados_tipo_1 = [ i for i in self.lista_infectados_tipo_1 if i not in lista_curados_tipo1 ] #adiciona os novos curados na lista geral de curados self.lista_curados = self.lista_curados + lista_curados_tipo1 + lista_curados_tipo2 # self. #movimentar infectantes: for infectante in self.lista_infectados_tipo_1: self.mover_infectante(infectante) for infectante in self.lista_infectados_tipo_2: self.mover_infectante(infectante) #adicionar os novos infectados tipo 1 e 2 para as respectivas listas self.lista_infectados_tipo_2 = self.lista_infectados_tipo_2 + lista_novos_infectados_tipo2_1 + lista_novos_infectados_tipo2_2 self.lista_infectados_tipo_1 = self.lista_infectados_tipo_1 + lista_novos_infectados_tipo1_1 + lista_novos_infectados_tipo1_2 #salva os resultados da atualização no dataframe: num_mortos = len(self.lista_mortos) num_curados = len(self.lista_curados) num_tipo_1 = len(self.lista_infectados_tipo_1) num_tipo_2 = len(self.lista_infectados_tipo_2) dict = { 'num_sadios': self.populacao_inicial - num_mortos - num_curados - num_tipo_1 - num_tipo_2, 'num_infect_t1': num_tipo_1, 'num_infect_t2': num_tipo_2, 'num_curados': num_curados, 'num_mortos': num_mortos } self.dataframe = self.dataframe.append(dict, ignore_index=True) #salva a nova matriz de status self.salvar_posicionamento() #adiciona 1 ao número de atualizações realizadas na matriz self.num_atualizacoes += 1 def popular(self, tamanho_matriz): #lista de possíveis combinações de índices da matriz de dados permutacoes = permutations(list(range(tamanho_matriz)), 2) #conversão para lista de tuplas(x,y) lista_indices = list(permutacoes) #embaralhamento dos índices random.shuffle(lista_indices) #cria o primeiro tipo1: indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.lista_infectados_tipo_1.append( self.fabrica_individuo.criar_individuo(Individuo.INFECTADO_TIPO_1, (ind_x, ind_y))) self.matriz_status[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 self.matriz_localizacao[ind_x, ind_y] = 0 #cria o restante dos tipos 1 for i in range(1, self.num_inicial_tipo1): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.lista_infectados_tipo_1.append( self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_1, (ind_x, ind_y))) self.matriz_status[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 self.matriz_localizacao[ind_x, ind_y] = len( self.lista_infectados_tipo_1) - 1 #cria o restante dos tipo 2: for indice in range(self.num_inicial_tipo2): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.lista_infectados_tipo_2.append( self.fabrica_individuo.criar_individuo( Individuo.INFECTADO_TIPO_2, (ind_x, ind_y))) self.matriz_status[ind_x, ind_y] = Individuo.INFECTADO_TIPO_2 self.matriz_localizacao[ind_x, ind_y] = len( self.lista_infectados_tipo_2) - 1 def trocar_status_localizacao(self, ponto_ini, ponto_final): x_ini = ponto_ini[0] y_ini = ponto_ini[1] x_fin = ponto_final[0] y_fin = ponto_final[1] aux1 = self.matriz_status[x_fin, y_fin] self.matriz_status[x_fin, y_fin] = self.matriz_status[x_ini, y_ini] self.matriz_status[x_ini, y_ini] = aux1 aux2 = self.matriz_localizacao[x_fin, y_fin] self.matriz_localizacao[x_fin, y_fin] = self.matriz_localizacao[x_ini, y_ini] self.matriz_localizacao[x_ini, y_ini] = aux2 def mover_infectante(self, infectante): pos_x, pos_y = infectante.posicao[0], infectante.posicao[1] rng_posicao = random.random() if rng_posicao <= 0.25: #move pra cima pos_x -= 1 elif rng_posicao <= 0.5: #move pra baixo pos_x += 1 elif rng_posicao <= 0.75: #move para esquerda pos_y -= 1 else: #move para direita pos_y += 1 novo_x, novo_y = self.matriz_esferica.valida_ponto_matriz(pos_x, pos_y) #descobre qual individuo ocupa atualmente a posição para atribuí-lo a posição de quem o está substituindo status = self.matriz_status[novo_x, novo_y] if status == Individuo.INFECTADO_TIPO_1: individuo_ocupante_destino = self.matriz_localizacao[novo_x, novo_y] self.lista_infectados_tipo_1[ individuo_ocupante_destino].posicao = infectante.posicao elif status == Individuo.INFECTADO_TIPO_2: print(individuo_ocupante_destino) individuo_ocupante_destino = self.matriz_localizacao[novo_x, novo_y] self.lista_infectados_tipo_2[ individuo_ocupante_destino].posicao = infectante.posicao # elif status == Individuo.CURADO: # individuo_ocupante_destino = self.matriz_localizacao[novo_x, novo_y] # self.lista_curados[individuo_ocupante_destino].posicao = infectante.posicao # elif status == Individuo.MORTO: # individuo_ocupante_destino = self.matriz_localizacao[novo_x, novo_y] # self.lista_matrizes_posicionamento[individuo_ocupante_destino].posicao = infectante.posicao self.trocar_status_localizacao(infectante.posicao, (novo_x, novo_y))
class Simulador(): SADIO = 0 INFECTADO_TIPO_1 = 1 #assintomáticos e o infectado inicial INFECTADO_TIPO_2 = 2 #sintomático CURADO = 3 MORTO = 4 def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura, #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 inserir_infectados_aleatorios): self.num_atualizacoes = 0 self.lista_infectados_tipo_2 = [] self.lista_infectados_tipo_1 = [] self.num_curados = 0 self.num_mortos = 0 self.chance_infeccao = chance_infeccao self.chance_infeccao_tipo2 = chance_infeccao_tipo2 self.chance_morte = chance_morte self.atualizacoes_cura = atualizacoes_cura self.populacao_inicial = int(tamanho_matriz**2) num_inicial_infectados = random.randint( 0, tamanho_matriz * tamanho_matriz - 1) proporcao_t1_t2 = random.random() self.num_inicial_tipo1 = round(inserir_infectados_aleatorios * proporcao_t1_t2 * num_inicial_infectados) print("self.num_inicial_tipo1: ", self.num_inicial_tipo1) self.num_inicial_tipo2 = round(inserir_infectados_aleatorios * (1 - proporcao_t1_t2) * num_inicial_infectados) print("self.num_inicial_tipo2: ", self.num_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - ( self.num_inicial_tipo2 + self.num_inicial_tipo1) self.matriz_status = np.zeros( (tamanho_matriz, tamanho_matriz), dtype=np.uint8 ) #lil_matrix((tamanho_matriz, tamanho_matriz),dtype= np.uint8) # self.matriz_atualizacoes_cura = np.zeros( (tamanho_matriz, tamanho_matriz), dtype=np.uint8 ) #lil_matrix((tamanho_matriz, tamanho_matriz),dtype= np.uint8)# self.dict_resumo = {} #self.matriz_status = self.df_individuos.to_numpy() self.popular(tamanho_matriz) self.lista_matrizes_status = [] #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) dict = { 'num_sadios': self.num_inicial_sadios, 'num_infect_t1': self.num_inicial_tipo1, 'num_infect_t2': self.num_inicial_tipo2, 'num_curados': 0, 'num_mortos': 0 } #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(dict, index=[0]) self.salvar_posicionamento() def criar_individuo(self, status, posicao): self.matriz_status[posicao[0], posicao[1]] = status if status == self.INFECTADO_TIPO_1 or status == self.INFECTADO_TIPO_2: self.matriz_atualizacoes_cura[posicao[0], posicao[1]] = self.atualizacoes_cura else: self.matriz_atualizacoes_cura[posicao[0], posicao[1]] = 0 def salvar_posicionamento(self): self.lista_matrizes_status.append(copy.deepcopy(self.matriz_status)) def verificar_infeccao(self, lista_infectantes): lista_novos_infectados_tipo1 = [] lista_novos_infectados_tipo2 = [] #itera sobre sobre a lista de individuos que infectam e cada um realiza a tividade de infectar for indice_infectante in lista_infectantes: #busca os vizinhos do infectante atual lista_vizinhos = self.matriz_esferica.get_vizinhos( indice_infectante) #Para cada vizinho, se ele for sadio, é gerado um número aleatório para verificar se foi infectado for indice_vizinho in lista_vizinhos: #verificação de SADIO if self.verifica_status(indice_vizinho) == self.SADIO: #verificação do novo status novo_status = self.infectar(self.chance_infeccao, self.chance_infeccao_tipo2) #se for um infectado tipo 1 if novo_status == Individuo.INFECTADO_TIPO_1: #adiciona na lista de novos tipo 1 lista_novos_infectados_tipo1.append(indice_vizinho) if novo_status == Individuo.INFECTADO_TIPO_2: #adiciona na lista de novos tipo 2 lista_novos_infectados_tipo2.append(indice_vizinho) return lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 def checagem_morte_individual(self, chance_morte): rng_morte = random.random() if rng_morte <= chance_morte: return self.MORTO else: return self.INFECTADO_TIPO_2 def checar_cura_individual(self, indice): self.matriz_atualizacoes_cura[ indice[0], indice[1]] = self.matriz_atualizacoes_cura[indice[0], indice[1]] - 1 if self.matriz_atualizacoes_cura[indice[0], indice[1]] == 0: return self.CURADO else: return self.matriz_status[indice[0], indice[1]] def checagem_morte_lista(self, lista_infectantes): lista_mortos = [] for indice_infectante in lista_infectantes: novo_status = self.checagem_morte_individual(self.chance_morte) if novo_status == Individuo.MORTO: lista_mortos.append(indice_infectante) return lista_mortos def checagem_cura_lista(self, lista_infectantes): lista_curados = [] for indice_infectante in lista_infectantes: novo_status = self.checar_cura_individual(indice_infectante) if novo_status == Individuo.CURADO: lista_curados.append(indice_infectante) return lista_curados def iterar(self): #Verifica os novos infectados por infectantes do tipo 1 e 2 #print(self.lista_infectados_tipo_1+self.lista_infectados_tipo_2) lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 = self.verificar_infeccao( self.lista_infectados_tipo_1 + self.lista_infectados_tipo_2) for indice in lista_novos_infectados_tipo1: self.criar_individuo(self.INFECTADO_TIPO_1, indice) for indice in lista_novos_infectados_tipo2: self.criar_individuo(self.INFECTADO_TIPO_2, indice) #Verifica morte dos infectados tipo 2 lista_mortos = self.checagem_morte_lista(self.lista_infectados_tipo_2) #retira os indices dos individuos mortos da lista de infectados self.lista_infectados_tipo_2 = [ indice for indice in self.lista_infectados_tipo_2 if indice not in lista_mortos ] #Instancia individuos mortos na matriz for indice in lista_mortos: self.criar_individuo(self.MORTO, indice) #atualiza o número de mortos na matriz self.num_mortos = self.num_mortos + len(lista_mortos) #Verifica cura dos infectados tipo 1 lista_curados_t1 = self.checagem_cura_lista( self.lista_infectados_tipo_1) #Verifica cura dos infectados tipo 2 lista_curados_t2 = self.checagem_cura_lista( self.lista_infectados_tipo_2) #Instancia individuos mortos na matriz for indice in lista_curados_t1 + lista_curados_t2: self.criar_individuo(self.CURADO, indice) #atualiza o número de curados na matriz self.num_curados = self.num_curados + len(lista_curados_t1 + lista_curados_t2) #Atualiza a lista de infectados após a cura dos individuos self.lista_infectados_tipo_1 = [ indice for indice in self.lista_infectados_tipo_1 if indice not in lista_curados_t1 ] self.lista_infectados_tipo_2 = [ indice for indice in self.lista_infectados_tipo_2 if indice not in lista_curados_t2 ] #movimentação nova_lista_t1 = [] for indice in self.lista_infectados_tipo_1: nova_lista_t1.append(self.mover_infectante(indice)) self.lista_infectados_tipo_1 = nova_lista_t1 #print(self.lista_infectados_tipo_1) nova_lista_t2 = [] for indice in self.lista_infectados_tipo_2: nova_lista_t2.append(self.mover_infectante(indice)) self.lista_infectados_tipo_2 = nova_lista_t2 #print(self.lista_infectados_tipo_2) # matriz_infectantes = matriz_infectantes[matriz_infectantes < 3] indices_infectados = list( zip(*np.where((self.matriz_status == 1) + (self.matriz_status == 2)))) # indices_infectados = list(zip(*self.matriz_status.nonzero())) #indices_infectados = [indice for indice in indices_infectados if indice not in self.lista_infectados_tipo_1 + self.lista_infectados_tipo_2] # self.num_curados = 0 #self.num_mortos = 0 self.lista_infectados_tipo_1 = [] self.lista_infectados_tipo_2 = [] #novos_t1 = [] #novos_t2 = [] for indice in indices_infectados: #if indice not in self.lista_infectados_tipo_1 and indice not in self.lista_infectados_tipo_2: # print(indice) # print(self.matriz_status.shape) status = self.matriz_status[indice[0], indice[1]] if status == self.INFECTADO_TIPO_1: self.lista_infectados_tipo_1.append(indice) #novos_t1.append(indice) if status == self.INFECTADO_TIPO_2: self.lista_infectados_tipo_2.append(indice) #novos_t2.append(indice) #self.lista_infectados_tipo_1 = self.lista_infectados_tipo_1 + novos_t1 #self.lista_infectados_tipo_2 = self.lista_infectados_tipo_2 + novos_t2 dict = { 'num_sadios': self.populacao_inicial - len(self.lista_infectados_tipo_1) - len(self.lista_infectados_tipo_2) - self.num_curados - self.num_mortos, 'num_infect_t1': len(self.lista_infectados_tipo_1), 'num_infect_t2': len(self.lista_infectados_tipo_2), 'num_curados': self.num_curados, 'num_mortos': self.num_mortos } self.dataframe = self.dataframe.append(dict, ignore_index=True) self.salvar_posicionamento() #adiciona 1 ao número de atualizações realizadas na matriz self.num_atualizacoes += 1 def infectar(self, chance_infeccao, chance_infeccao_tipo2): saida = Individuo.SADIO #número aleatório para chance de infectar o vizinho rng_infeccao = random.random() if rng_infeccao <= chance_infeccao: #número aleatório para chance de infecção tipo 1 ou 2 rng_infeccao_tipo2 = random.random() if rng_infeccao_tipo2 <= chance_infeccao_tipo2: saida = Individuo.INFECTADO_TIPO_2 else: saida = Individuo.INFECTADO_TIPO_1 return saida def popular(self, tamanho_matriz): #lista de possíveis combinações de índices da matriz de dados indice_x = list(range(0, tamanho_matriz)) indice_y = list(range(0, tamanho_matriz)) random.shuffle(indice_x) random.shuffle(indice_y) lista_indices = [] for x in indice_x: for y in indice_y: lista_indices.append((x, y)) if len(lista_indices ) > self.num_inicial_tipo1 + self.num_inicial_tipo1 + 1: break #permutacoes = permutations(list(range(tamanho_matriz)),2) #conversão para lista de tuplas(x,y) #lista_indices = list(zip(indice_x,indice_y)) #embaralhamento dos índices #random.shuffle(lista_indices) indice_matriz = 0 #cria o primeiro tipo1: indice = lista_indices[indice_matriz] indice_matriz += 1 self.criar_individuo(Individuo.INFECTADO_TIPO_1, indice) self.lista_infectados_tipo_1.append(indice) print("criado um tipo 1") #cria o restante dos tipos 1 for i in range(self.num_inicial_tipo1): indice = lista_indices[indice_matriz] indice_matriz += 1 self.criar_individuo(Individuo.INFECTADO_TIPO_1, indice) self.lista_infectados_tipo_1.append(indice) #cria o restante dos tipo 2: for indice in range(self.num_inicial_tipo2): indice = lista_indices[indice_matriz] indice_matriz += 1 self.criar_individuo(Individuo.INFECTADO_TIPO_2, indice) self.lista_infectados_tipo_2.append(indice) def trocar(self, matriz, ponto_ini, ponto_final): x_ini = ponto_ini[0] y_ini = ponto_ini[1] x_fin = ponto_final[0] y_fin = ponto_final[1] aux = matriz[x_fin, y_fin] matriz[x_fin, y_fin] = matriz[x_ini, y_ini] matriz[x_ini, y_ini] = aux def verifica_status(self, indice): return self.matriz_status[indice[0], indice[1]] def mover_infectante(self, posicao_inicial): pos_x, pos_y = posicao_inicial[0], posicao_inicial[1] rng_posicao = random.random() if rng_posicao <= 0.25: #move pra cima pos_x -= 1 elif rng_posicao <= 0.5: #move pra baixo pos_x += 1 elif rng_posicao <= 0.75: #move para esquerda pos_y -= 1 else: #move para direita pos_y += 1 posicao_final = self.matriz_esferica.valida_ponto_matriz(pos_x, pos_y) self.trocar(self.matriz_status, posicao_inicial, posicao_final) self.trocar(self.matriz_atualizacoes_cura, posicao_inicial, posicao_final) return posicao_final def executar_simulacao(self): while (self.dataframe.iloc[-1]['num_infect_t1'] + self.dataframe.iloc[-1]['num_infect_t2']) > 0: self.iterar() num_sadios_min = self.dataframe.iloc[-1]['num_sadios'] #descobre linha que ocorreu o máximo de infectados indice_infeccao_maxima = self.dataframe[self.dataframe.num_sadios == num_sadios_min].index[0] metade_infeccao_maxima = int(indice_infeccao_maxima / 2) print(metade_infeccao_maxima + 1) self.dict_resumo = { "pop_inicial": self.populacao_inicial, "tipo1_inicial": self.dataframe.iloc[0]['num_infect_t1'], "tipo2_inicial": self.dataframe.iloc[0]['num_infect_t2'], "n/2_100%_infectados": metade_infeccao_maxima, "tipo1_n/2": self.dataframe.iloc[metade_infeccao_maxima]['num_infect_t1'], "tipo2_n/2": self.dataframe.iloc[metade_infeccao_maxima]['num_infect_t2'], "curados_n/2": self.dataframe.iloc[metade_infeccao_maxima]['num_curados'], "mortos_n/2": self.dataframe.iloc[metade_infeccao_maxima]['num_mortos'], "n/2+1_100%_infectados": metade_infeccao_maxima, "tipo1_n/2+1": self.dataframe.iloc[int(metade_infeccao_maxima)]['num_infect_t1'], "tipo2_n/2+1": self.dataframe.iloc[metade_infeccao_maxima]['num_infect_t2'], "curados_n/2+1": self.dataframe.iloc[metade_infeccao_maxima]['num_curados'], "mortos_n/2+1": self.dataframe.iloc[metade_infeccao_maxima]['num_mortos'], "n_atualizacoes_100%_infectados": indice_infeccao_maxima, "tipo1_n": self.dataframe.iloc[indice_infeccao_maxima]['num_infect_t1'], "tipo2_n": self.dataframe.iloc[indice_infeccao_maxima]['num_infect_t2'], "curados_n": self.dataframe.iloc[indice_infeccao_maxima]['num_curados'], "mortos_n": self.dataframe.iloc[indice_infeccao_maxima]['num_mortos'], "numero_total_atualizacoes": self.dataframe.shape[0], "sadios_final": self.dataframe.iloc[-1]['num_sadios'], "curados_final": self.dataframe.iloc[-1]['num_curados'], "mortos_final": self.dataframe.iloc[-1]['num_mortos'] }
class Simulador(): def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica percentual_inicial_tipo1, #percentual inicial da população que será infectada tipo 1 percentual_inicial_tipo2, #percentual inicial da população que será infectada tipo 2 chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura): #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 self.num_atualizacoes = 0 self.individuos_infectados_tipo_2 = [] self.individuos_infectados_tipo_1 = [] self.individuos_infectados_curados = [] self.individuos_infectados_mortos = [] self.lista_matrizes_posicionamento = [] self.matriz_status = np.zeros([tamanho_matriz,tamanho_matriz]) self.fabrica_individuo = Fabrica_individuo( chance_infeccao, chance_infeccao_tipo2, chance_morte, atualizacoes_cura) self.matriz_individuos = pd.DataFrame(columns=range(tamanho_matriz), index=range(tamanho_matriz)) self.matriz_individuos.loc[:] = self.fabrica_individuo.criar_individuo(Individuo.SADIO,(0,0)) self.matriz_status[:] = Individuo.SADIO #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) self.populacao_inicial = int(tamanho_matriz**2) self.num_inicial_tipo2 = int(self.populacao_inicial * percentual_inicial_tipo2) self.num_inicial_tipo1 = int(self.populacao_inicial * percentual_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - (self.num_inicial_tipo2 + self.num_inicial_tipo1) self.popular(tamanho_matriz) dict = { 'num_sadios':self.num_inicial_sadios, 'num_infect_t1':self.num_inicial_tipo1, 'num_infect_t2':self.num_inicial_tipo2, 'num_curados':0, 'num_mortos':0} #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(dict, index = [0]) self.salvar_posicionamento() def salvar_posicionamento(self): self.lista_matrizes_posicionamento.append(self.matriz_status) def iterar(self): #itera sobre sobre a lista de individuos que infectam e cada um realiza a tividade de infectar pass def popular(self, tamanho_matriz): #lista de possíveis combinações de índices da matriz de dados permutacoes = permutations(list(range(tamanho_matriz)),2) #conversão para lista de tuplas(x,y) lista_indices = list(permutacoes) #embaralhamento dos índices random.shuffle(lista_indices) #cria o primeiro tipo1: indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.matriz_individuos.loc[ind_x,ind_y] = self.fabrica_individuo.criar_individuo(Individuo.INFECTADO_TIPO_1,(ind_x,ind_y)) #self.matriz_individuos[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 self.individuos_infectados_tipo_1.append((ind_x,ind_y)) self.matriz_status[ind_x,ind_y] = Individuo.INFECTADO_TIPO_1 #cria o restante dos tipos 1 for i in range(1,self.num_inicial_tipo1): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.matriz_individuos.loc[ind_x,ind_y] = self.fabrica_individuo.criar_individuo(Individuo.INFECTADO_TIPO_1,(ind_x,ind_y)) #self.matriz_individuos[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 self.individuos_infectados_tipo_1.append((ind_x,ind_y)) self.matriz_status[ind_x,ind_y] = Individuo.INFECTADO_TIPO_1 #cria o restante dos tipo 2: for indice in range(self.num_inicial_tipo2): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.matriz_individuos.loc[ind_x,ind_y] = self.fabrica_individuo.criar_individuo(Individuo.INFECTADO_TIPO_2,(ind_x,ind_y)) #self.matriz_individuos[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 self.individuos_infectados_tipo_2.append((ind_x,ind_y)) self.matriz_status[ind_x,ind_y] = Individuo.INFECTADO_TIPO_2 def mover_infectado(self, individuo: Individuo): pos_x, pos_y = individuo.posicao[0], individuo.posicao[1] rng_posicao = random.random() if rng_posicao <=0.25: #move pra cima pos_x -= 1 elif rng_posicao <=0.5: #move pra baixo pos_x += 1 elif rng_posicao <=0.75: #move para esquerda pos_y -= 1 else: #move para direita pos_y += 1 novo_x, novo_y = self.matriz_esferica.validar(pos_x, pos_y) #troca os valores no dataframe aux = self.matriz_individuos.loc[novo_x, novo_y] self.matriz_individuos.loc[novo_x, novo_y] = self.matriz_individuos.loc[pos_x, pos_y] self.matriz_individuos.loc[pos_x, pos_y] = aux #troca os valores na matriz de status aux = self.matriz_status[novo_x, novo_y] self.self.matriz_status[novo_x, novo_y] = self.matriz_status[pos_x, pos_y] self.self.matriz_status[pos_x, pos_y] = aux return (novo_x, novo_y)
def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica percentual_inicial_tipo1, #percentual inicial da população que será infectada tipo 1 percentual_inicial_tipo2, #percentual inicial da população que será infectada tipo 2 chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura ): #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 self.num_atualizacoes = 0 self.lista_infectados_tipo_2 = [] self.lista_infectados_tipo_1 = [] self.num_curados = 0 self.num_mortos = 0 self.chance_infeccao = chance_infeccao self.chance_infeccao_tipo2 = chance_infeccao_tipo2 self.chance_morte = chance_morte self.atualizacoes_cura = atualizacoes_cura self.populacao_inicial = int(tamanho_matriz**2) self.num_inicial_tipo2 = int(self.populacao_inicial * percentual_inicial_tipo2) self.num_inicial_tipo1 = 1 + int( self.populacao_inicial * percentual_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - ( self.num_inicial_tipo2 + self.num_inicial_tipo1) self.matriz_status = lil_matrix((tamanho_matriz, tamanho_matriz), dtype=np.uint8) self.matriz_atualizacoes_cura = lil_matrix( (tamanho_matriz, tamanho_matriz), dtype=np.uint8) #self.matriz_status = self.df_individuos.to_numpy() self.popular(tamanho_matriz) self.lista_matrizes_status = [] #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) # dict = { # 'num_sadios':self.num_inicial_sadios, # 'num_infect_t1':self.num_inicial_tipo1, # 'num_infect_t2':self.num_inicial_tipo2, # 'num_curados':0, # 'num_mortos':0} dict = { 'num_sadios': self.dataframe[-1:]['num_sadios'] - np.sum(self.matriz_status[self.matriz_status != 0].toarray()), 'num_infect_t1': np.sum(self.matriz_status[self.matriz_status == 1].toarray()), 'num_infect_t2': np.sum(self.matriz_status[self.matriz_status == 2].toarray()), 'num_curados': np.sum(self.matriz_status[self.matriz_status == 3].toarray()), 'num_mortos': np.sum(self.matriz_status[self.matriz_status == 4].toarray()) } #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(dict, index=[0]) self.salvar_posicionamento()
class Simulador(): def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica percentual_inicial_tipo1, #percentual inicial da população que será infectada tipo 1 percentual_inicial_tipo2, #percentual inicial da população que será infectada tipo 2 chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura): #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 self.num_atualizacoes = 0 self.individuos_infectados_tipo_2 = [] self.individuos_infectados_tipo_1 = [] self.individuos_curados = [] self.individuos_mortos = [] self.lista_matrizes_posicionamento = [] self.matriz_status = np.zeros([tamanho_matriz,tamanho_matriz], dtype= int) self.fabrica_individuo = Fabrica_individuo( chance_infeccao, chance_infeccao_tipo2, chance_morte, atualizacoes_cura) self.matriz_individuos = pd.DataFrame(columns=range(tamanho_matriz), index=range(tamanho_matriz)) self.matriz_individuos.loc[:] = self.fabrica_individuo.criar_individuo(Individuo.SADIO,(0,0)) self.matriz_status[:] = Individuo.SADIO #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) self.populacao_inicial = int(tamanho_matriz**2) self.num_inicial_tipo2 = int(self.populacao_inicial * percentual_inicial_tipo2) self.num_inicial_tipo1 = int(self.populacao_inicial * percentual_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - (self.num_inicial_tipo2 + self.num_inicial_tipo1) self.popular(tamanho_matriz) dict = { 'num_sadios':self.num_inicial_sadios, 'num_infect_t1':self.num_inicial_tipo1, 'num_infect_t2':self.num_inicial_tipo2, 'num_curados':0, 'num_mortos':0} #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(index = [0]) self.salvar_posicionamento() def salvar_posicionamento(self): self.lista_matrizes_posicionamento.append(self.matriz_status) def verificar_infeccao(self, lista_infectantes): lista_novos_infectados_tipo1 = [] lista_novos_infectados_tipo2 = [] #itera sobre sobre a lista de individuos que infectam e cada um realiza a tividade de infectar for indice in lista_infectantes: #busca os vizinhos do infectante atual lista_vizinhos = self.matriz_esferica.get_vizinhos(indice[0], indice[1]) #Para cada vizinho, se ele for sadio, é gerado um número aleatório para verificar se foi infectado for vizinho in lista_vizinhos: x = vizinho[0] y = vizinho[1] #verificação de SADIO if self.matriz_status[x,y] == Individuo.SADIO: #verificação do novo status novo_status = self.matriz_individuos.loc[indice[0], indice[1]].infectar() #se for um infectado tipo 1 if novo_status == Individuo.INFECTADO_TIPO_1: #adiciona na lista de novos tipo 1 lista_novos_infectados_tipo1.append((x,y)) #modifica o status do objeto recém infectado self.matriz_individuos.loc[x,y].status = Individuo.INFECTADO_TIPO_1 #modifica o status na matriz de status self.matriz_status[x,y] = Individuo.INFECTADO_TIPO_1 if novo_status == Individuo.INFECTADO_TIPO_2: #adiciona na lista de novos tipo 2 lista_novos_infectados_tipo2.append((x,y)) #modifica o status do objeto recém infectado self.matriz_individuos.loc[x,y].status = Individuo.INFECTADO_TIPO_2 #modifica o status na matriz de status self.matriz_status[x,y] = Individuo.INFECTADO_TIPO_2 return lista_novos_infectados_tipo1, lista_novos_infectados_tipo2 def verificar_morte(self, lista_infectantes_tipo2): lista_mortos = [] for indice in lista_infectantes_tipo2: novo_status = self.matriz_individuos.loc[indice[0], indice[1]].checagem_morte() if novo_status == Individuo.MORTO: lista_mortos.append(indice) self.matriz_status[indice[0], indice[1]] = Individuo.MORTO return lista_mortos def verificar_cura(self, lista_infectantes): lista_curados = [] for indice in lista_infectantes: novo_status = self.matriz_individuos.loc[indice[0], indice[1]].checagem_cura() if novo_status == Individuo.CURADO: lista_curados.append(indice) self.matriz_status[indice[0], indice[1]] = Individuo.CURADO return lista_curados def iterar(self): #Verifica os novos infectados a partir dos atuais infectantes na matriz lista_novos_infectados_tipo1_1, lista_novos_infectados_tipo2_1 = self.verificar_infeccao(self.individuos_infectados_tipo_1) lista_novos_infectados_tipo1_2, lista_novos_infectados_tipo2_2 = self.verificar_infeccao(self.individuos_infectados_tipo_2) #Verifica morte dos tipo 2 lista_mortos = self.verificar_morte(self.individuos_infectados_tipo_2) self.individuos_infectados_mortos #retirar os mortos da lista de infectados tipo 2 ### """ """ #adiciona os novos mortos na lista geral de mortos # self.individuos_infectados_mortos #Verificar cura lista_curados_tipo1 = verificar_cura(self.individuos_infectados_tipo_1) lista_curados_tipo2 = verificar_cura(self.individuos_infectados_tipo_2) #retirar os curados das lista de infectados tipo 1 e 2 """ """ #adiciona os novos curados na lista geral de curados # self. #movimentar infectantes: for i in range(len(self.individuos_infectados_tipo_1)): self.individuos_infectados_tipo_1[i] = self.mover_infectante(self.individuos_infectados_tipo_1[i]) for i in range(len(self.individuos_infectados_tipo_2)): self.individuos_infectados_tipo_2[i] = self.mover_infectante(self.individuos_infectados_tipo_2[i]) #adicionar os novos infectados tipo 1 e 2 para as respectivas listas # self.individuos_infectados_tipo_2 = [] # self.individuos_infectados_tipo_1 = [] #salva os resultados da atualização no dataframe: num_mortos = len(self.individuos_mortos) num_curados = len(self.individuos_curados) num_tipo_1 = len(self.individuos_infectados_tipo_1) num_tipo_2 = len(self.individuos_infectados_tipo_2) #salva a nova matriz de status self.salvar_posicionamento() #adiciona 1 ao número de atualizações realizadas na matriz self.num_atualizacoes +=1 def popular(self, tamanho_matriz): #lista de possíveis combinações de índices da matriz de dados permutacoes = permutations(list(range(tamanho_matriz)),2) #conversão para lista de tuplas(x,y) lista_indices = list(permutacoes) #embaralhamento dos índices random.shuffle(lista_indices) #cria o primeiro tipo1: indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.matriz_individuos.loc[ind_x,ind_y] = self.fabrica_individuo.criar_individuo(Individuo.INFECTADO_TIPO_1,(ind_x,ind_y)) #self.matriz_individuos[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 self.individuos_infectados_tipo_1.append((ind_x,ind_y)) self.matriz_status[ind_x,ind_y] = Individuo.INFECTADO_TIPO_1 #cria o restante dos tipos 1 for i in range(1,self.num_inicial_tipo1): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.matriz_individuos.loc[ind_x,ind_y] = self.fabrica_individuo.criar_individuo(Individuo.INFECTADO_TIPO_1,(ind_x,ind_y)) #self.matriz_individuos[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 self.individuos_infectados_tipo_1.append((ind_x,ind_y)) self.matriz_status[ind_x,ind_y] = Individuo.INFECTADO_TIPO_1 #cria o restante dos tipo 2: for indice in range(self.num_inicial_tipo2): indice = lista_indices.pop() ind_x = indice[0] ind_y = indice[1] self.matriz_individuos.loc[ind_x,ind_y] = self.fabrica_individuo.criar_individuo(Individuo.INFECTADO_TIPO_2,(ind_x,ind_y)) #self.matriz_individuos[ind_x, ind_y] = Individuo.INFECTADO_TIPO_1 self.individuos_infectados_tipo_2.append((ind_x,ind_y)) self.matriz_status[ind_x,ind_y] = Individuo.INFECTADO_TIPO_2 def mover_infectante(self, indice): pos_x, pos_y = indice[0], indice[1] rng_posicao = random.random() if rng_posicao <=0.25: #move pra cima pos_x -= 1 elif rng_posicao <=0.5: #move pra baixo pos_x += 1 elif rng_posicao <=0.75: #move para esquerda pos_y -= 1 else: #move para direita pos_y += 1 novo_x, novo_y = self.matriz_esferica.validar(pos_x, pos_y) #troca os valores no dataframe aux = self.matriz_individuos.loc[novo_x, novo_y] self.matriz_individuos.loc[novo_x, novo_y] = self.matriz_individuos.loc[pos_x, pos_y] self.matriz_individuos.loc[pos_x, pos_y] = aux #troca os valores na matriz de status aux = self.matriz_status[novo_x, novo_y] self.self.matriz_status[novo_x, novo_y] = self.matriz_status[pos_x, pos_y] self.self.matriz_status[pos_x, pos_y] = aux return (novo_x, novo_y)
def __init__( self, tamanho_matriz, #numero de linhas e colunas da matriz esférica percentual_inicial_tipo1, #percentual inicial da população que será infectada tipo 1 percentual_inicial_tipo2, #percentual inicial da população que será infectada tipo 2 chance_infeccao, #chance que um infectado tipo 2 tem de infectar um indivíduo saudável chance_infeccao_tipo2, #chance de um indivíduo infectado se tornar contagioso chance_morte, #chance de um indivíduo tipo 2 morrer ao fim de uma atualização atualizacoes_cura ): #número de atualizações necessárias para a cura de um indivíduo tipo 1 ou 2 self.num_atualizacoes = 0 self.lista_infectados_tipo_2 = [] self.lista_infectados_tipo_1 = [] self.num_curados = 0 self.num_mortos = 0 self.chance_infeccao = chance_infeccao self.chance_infeccao_tipo2 = chance_infeccao_tipo2 self.chance_morte = chance_morte self.fabrica_individuo = Fabrica_individuo(atualizacoes_cura) self.df_individuos = pd.DataFrame(index=range(tamanho_matriz), columns=range(tamanho_matriz)) self.df_individuos.fillna( self.fabrica_individuo.criar_individuo(10, (0, 0))) print(self.df_individuos) #self.df_individuos.iloc[0,0] = 0 #lista que guarda o posicionamento self.lista_matrizes_posicionamento = [] #guarda em matriz esparsa o status de saúde de cada elemento self.matriz_status = lil_matrix((tamanho_matriz, tamanho_matriz), dtype=np.uint8) #guarda em matriz esparsa a localização do objeto em sua respectiva lista self.matriz_localizacao = lil_matrix((tamanho_matriz, tamanho_matriz), dtype=np.uint32) self.fabrica_individuo = Fabrica_individuo(atualizacoes_cura) #objeto que é responsável por validar a movimentação no grid n x n self.matriz_esferica = Matriz_esferica(tamanho_matriz) self.populacao_inicial = int(tamanho_matriz**2) self.num_inicial_tipo2 = int(self.populacao_inicial * percentual_inicial_tipo2) self.num_inicial_tipo1 = int(self.populacao_inicial * percentual_inicial_tipo1) self.num_inicial_sadios = self.populacao_inicial - ( self.num_inicial_tipo2 + self.num_inicial_tipo1) self.popular(tamanho_matriz) dict = { 'num_sadios': self.num_inicial_sadios, 'num_infect_t1': self.num_inicial_tipo1, 'num_infect_t2': self.num_inicial_tipo2, 'num_curados': 0, 'num_mortos': 0 } #dataframe que guardará os resultados de cada atualização self.dataframe = pd.DataFrame(index=[0]) self.salvar_posicionamento()
def __init__(self, tamanho_matriz): self.num_iteracoes = 0 self.matriz_individuos = [] self.matriz_esferica = Matriz_esferica(tamanho_matriz) self.dataframe = pd.DataFrame(columns= [''])