.. -- coding: utf-8 -- .. Copyright (C) Coelho e Hitoshi Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with Invariant Sections being Forward, Prefaces, and Contributor List, no Front-Cover Texts, and no Back-Cover Texts. .. shortname:: EP10 .. description:: agent based modelling: modelo de segregação de Schelling Exercício Programa 10: Modelos baseados em agentes ================================================== Introdução ---------- .. An agent-based model (ABM) is one of a class of computational models for simulating the actions and interactions of autonomous agents (both individual or collective entities such as organizations or groups) with a view to assessing their effects on the system as a whole. It combines elements of game theory, complex systems, emergence, computational sociology, multi-agent systems, and evolutionary programming Um **modelo baseado em agentes** (`agent-based model `__) é uma classe de modelos computacionais para simulação de ações e iterações de agentes autônomos (indivíduos ou entidades coletivas como organizações e grupos) com a intenção de estimar o seu efeito no sistema como um todo. Ele combina elementos de teoria so jogos (`game theory `__), sistema complexos (`complex systems `__), emergência (`emergence `__), sociologia computacional (`computacional sociology `__), sistemas de agentes mútiplos (`multi-agent system `__) e programação evolucionária (`evolutionary programming `__). O modelamento baseado em agentes é uma ferramenta computacional bastante poderosa para investigar certos fenômenos dinâmicos. Um dos primeiros modelos foi proposto por `Thomas Schelling `__ em 1971 em seu trabalho `Dynamics Models of Segregation `__. O seu objetivo era demonstrar possíveis causas de segregação [#f1]_ racial em cidades americanas. Em seu modelo, uma cidade é representada por uma matriz retangular (nesse exercício consideraremos matrizes quadradas), onde cada elemento da matriz é uma casa. Uma casa pode ser ocupada por um **agente** vermelho ou azul, ou ficar vazia. O número de agentes vermelhos é aproximadamente o mesmo de azuis, com uma certa porcentagem de casas vazias. A cada instante da simulação, um agente pode estar feliz ou infeliz com relação aos seus vizinhos e, caso infeliz, ele se muda para uma casa vazia qualquer. Cada casa pode ter até 8 vizinhos. Vamos considerar que um agente está **feliz** se possui ao menos 2 vizinhos como ele. Caso ele esteja feliz nada acontece. Caso haja 1 ou zero vizinhos como ele, o agente fica **infeliz**. Um agente infeliz tenta mudar para uma outra casa. O que você deve fazer (entrega dia 13/11) ----------------------------------------- Antes de mais nada, instale o NumPy seguindo o link que está na página `arrays `__ do `Guia interativo de estudos `__. c Escreva um programa em Python que permita observar a evolução desse processo. Inicialmente o seu programa deve ler do teclado os seguintes valores **inteiros**: - o valor da semente a ser utilizada para o gerador de números pseudo-aleatórios; - a dimensão ``n`` da cidade que será representada por um ``array`` (= objeto da classe ``numpy.ndarray``) quadrado de dimensão ``n x n``; - a porcentagem de agentes azuis; - a porcentagem de agentes vermelhos; - o número mínimo de vizinhos que deixa um agente feliz. A soma das porcentagens de agentes azuis e vermelhos deve ser sempre menor que 100, para permitir a existência de casas vazias. Por exemplo, quando a porcentagem de azuis é 45 e a de vermelhos é 35, o restante 20% é de casas vazias. A partir dessas informações, o seu programa deve sortear uma certa distribuição de casas na cidade, que define a condição inicial, utilizando para isso a função ``sorteia_cidade()`` fornecida abaixo: .. sourcecode:: python import numpy as np def sorteia_cidade(s, a, v): ''' (int, int, int) -> array Recebe um inteiro s com o tamanho do mapa (s x s) e a porcentagem de agentes azuis (a) e vermelhos (v) e retorna um mapa respeitando a distribuição fornecida ''' # cria um array com números pseudo-aleatórios M = np.random.randint(100, size=(s,s)) vazio = M >= v+a verm = (M >= a) & (M < v+a) azul = M < a M[vazio] = VAZIO M[azul] = AZUL M[verm] = VERMELHO # cria borda com zeros M[:,0] = M[0,:] = M[-1,:] = M[:,-1] = BORDA return M A seguir, o seu programa deve executar iterações da simulação até que o usuário digite a palavra ``fim``. A cada iteração da simulação, o seu programa deve primeiro identificar todos os agentes infelizes. A seguir, cada um desses agentes se move, aleatoriamente para uma casa vazia. Ao se mudar, sua própria casa fica vazia e disponível para o sorteio do próximo agente insatisfeito. Veja o exemplo de execução abaixo. Implemente o seu programa de tal forma que tenha **exatamente** o mesmo comportamento do exemplo abaixo. .. sourcecode:: python Bem vindo ao simulador do modelo de segregação de Schelling Digite a semente para o gerador de números pseudo-aleatórios: 5 Digite a dimensão n da cidade: 5 Digite a porcentagem da população azul: 40 Digite a porcentagem da população vermelha: 40 Digite o número mínimo de vizinhos desejado: 2 Configuração Inicial [[-1 -1 -1 -1 -1 -1 -1] [-1 1 0 1 2 1 -1] [-1 1 2 2 2 2 -1] [-1 0 0 1 1 2 -1] [-1 0 1 2 1 2 -1] [-1 1 1 2 1 1 -1] [-1 -1 -1 -1 -1 -1 -1]] 8 querem mudar: [[-1 -1 -1 -1 -1 -1 -1] [-1 1 0 1 0 1 -1] [-1 1 1 0 0 0 -1] [-1 0 0 0 0 0 -1] [-1 0 0 1 0 1 -1] [-1 0 0 1 0 0 -1] [-1 -1 -1 -1 -1 -1 -1]] Mudaram de casa: 4 da cor azul Mudaram de casa: 4 da cor vermelha Estado após 1 iterações [[-1 -1 -1 -1 -1 -1 -1] [-1 2 0 2 2 1 -1] [-1 0 0 2 2 2 -1] [-1 1 1 1 1 2 -1] [-1 1 1 2 1 2 -1] [-1 1 1 0 1 1 -1] [-1 -1 -1 -1 -1 -1 -1]] Digite fim para terminar, ou enter para mais uma iteração: 4 querem mudar: [[-1 -1 -1 -1 -1 -1 -1] [-1 1 0 0 0 1 -1] [-1 0 0 0 0 0 -1] [-1 0 0 0 0 0 -1] [-1 0 0 1 0 1 -1] [-1 0 0 0 0 0 -1] [-1 -1 -1 -1 -1 -1 -1]] Mudaram de casa: 1 da cor azul Mudaram de casa: 3 da cor vermelha Estado após 2 iterações [[-1 -1 -1 -1 -1 -1 -1] [-1 0 2 2 2 0 -1] [-1 1 2 2 2 2 -1] [-1 1 1 1 1 2 -1] [-1 1 1 0 1 0 -1] [-1 1 1 2 1 1 -1] [-1 -1 -1 -1 -1 -1 -1]] Digite fim para terminar, ou enter para mais uma iteração: 1 querem mudar: [[-1 -1 -1 -1 -1 -1 -1] [-1 0 0 0 0 0 -1] [-1 0 0 0 0 0 -1] [-1 0 0 0 0 0 -1] [-1 0 0 0 0 0 -1] [-1 0 0 1 0 0 -1] [-1 -1 -1 -1 -1 -1 -1]] Mudaram de casa: 0 da cor azul Mudaram de casa: 1 da cor vermelha Estado após 3 iterações [[-1 -1 -1 -1 -1 -1 -1] [-1 0 2 2 2 2 -1] [-1 1 2 2 2 2 -1] [-1 1 1 1 1 2 -1] [-1 1 1 0 1 0 -1] [-1 1 1 0 1 1 -1] [-1 -1 -1 -1 -1 -1 -1]] Digite fim para terminar, ou enter para mais uma iteração: 0 querem mudar: [[-1 -1 -1 -1 -1 -1 -1] [-1 0 0 0 0 0 -1] [-1 0 0 0 0 0 -1] [-1 0 0 0 0 0 -1] [-1 0 0 0 0 0 -1] [-1 0 0 0 0 0 -1] [-1 -1 -1 -1 -1 -1 -1]] Mudaram de casa: 0 da cor azul Mudaram de casa: 0 da cor vermelha Estado após 4 iterações [[-1 -1 -1 -1 -1 -1 -1] [-1 0 2 2 2 2 -1] [-1 1 2 2 2 2 -1] [-1 1 1 1 1 2 -1] [-1 1 1 0 1 0 -1] [-1 1 1 0 1 1 -1] [-1 -1 -1 -1 -1 -1 -1]] Digite fim para terminar, ou enter para mais uma iteração: fim Dicas e Detalhes ================ . Não deixe o EP para a última hora . Siga as `Instruções para entrega de EPs `__ . Para saber mais sobre números pseudo-aleatórios usando NumPy, visite a documentação disponível em `http://docs.scipy.org/doc/numpy/reference/routines.random.html `__ . Coloque as suas dúvidas no fórum de discussão da disciplina. . Venha tirar as dúvidas nos plantões. .. rubric:: Footnotes .. [#f1] Forma de dissociação que se realiza quando unidades similares, obedecendo ao mesmo impulso, se concentram, distanciando-se, ao mesmo tempo, de outras unidades consideradas diferentes ou divergentes. Essa separação ou distância social e física é oriunda de fatores biológicos e sociais: raça, riqueza, educação, religião, profissão, nacionalidade.