Neste artigo, demonstro simulação baseada em agente em Python. Na verdade, já apresentei a modelagem baseada em agente em Python em postagens anteriores. Por exemplo, introduzi um modelo de campo de batalha que contém grupos de agentes localizados em uma grade 2D. Codifiquei esse modelo em Python e usei o Matplotlib para visualização. Neste artigo, não apenas construirei um modelo, mas também executarei toda uma simulação baseada em agente em Python.
Módulo simples para simulação baseada em agente em Python
Para começar, preciso construir um módulo simples para simulações baseadas em agentes em Python. Em primeiro lugar, assim como em minha introdução anterior à modelagem baseada em agente em Python, defino um tipo de dados de agente personalizado. Isso é feito na forma de uma classe personalizada em Python.
# class, defining agents as abstract data types
class agent:
# init-method, the constructor method for agents
def __init__(self,x,y,group):
self.life = 100 # agent's life score
self.x = x
self.y = y
self.group = group
Como pode ser visto no construtor da classe de agente, um agente tem uma pontuação de vida. Além disso, os agentes pertencem a um grupo e têm coordenadas x e y. Esses atributos de coordenadas são usados para descrever a localização dos agentes em uma grade 2D.
Basicamente, um array bidimensional é usado para conter todos os agentes. Assim, as populações de agentes são alocadas em uma grade 2D. Neste caso, esta grade representa um campo de batalha. Como pode ser visto abaixo, criei o campo de batalha com uma compreensão de lista em Python.
# creating empty 100 x 100 list using list comprehension in python
battlefield = [[None for i in range(0,100)] for i in range(0,100)]
Agora continuo definindo uma função auxiliar em Python para criar e alocar agentes no campo de batalha. Vou usar esta função para configurar minha simulação baseada em agente em Python.
# define a function for creating agents and assigning them to grid
def agentCreator(size,group,groupList,field,n,m):
# loop through entire group, i.e. in this case 1000 units
for j in range(0,size):
# select random available location
while True:
# random x coordinate
x = random.choice(range(0,n))
# random y coordinate
y = random.choice(range(0,m))
# check if spot is available; if not then re-iterate
if field[x][y] == None:
field[x][y] = agent(x=x,y=y,group=group)
# append agent object reference to group list
groupList.append(field[x][y])
# exit while loop; spot on field is taken
break
Resumindo, a função agentCreator cria uma quantidade especificada de agentes e os aloca em um campo. Cada agente criado por uma chamada de função tem o mesmo tipo. Como pode ser visto na definição da função, o tipo é um parâmetro de entrada da função. Outro ponto importante a ser observado é que o campo em que os agentes estão alocados é passado como referência. Ou seja, neste caso o campo é a grade do campo de batalha. Ele facilita a tela na qual essa simulação baseada em agente em Python ocorre.
Inicializando minha simulação baseada em agente em Python
Usando esses componentes de modelo, agora inicio meu modelo. Para iniciar minha simulação baseada em agente em Python, crio um campo de batalha inicial. Além disso, adiciono agentes a ele. Tudo isso é feito chamando a função agentCreator como mostrei acima. Eu chamo a função duas vezes para adicionar dois grupos de agentes. O primeiro grupo é do tipo “A” enquanto o segundo grupo é do tipo “B”.
# list with available x and y locations
locations = battlefield.copy() # using .copy prevents copying by reference
# create empty list for containing agent references in future, type A & B
agents_A = []
agents_B = []
# assigning random spots to agents of group A and B;
import random
agentCreator(size = 1000,
group = "A",
groupList = agents_A,
field = battlefield,
n = 100,
m = 100)
agentCreator(size = 1000,
group = "B",
groupList = agents_B,
field = battlefield,
n = 100,
m = 100)
Embora os dados agora reflitam uma grade 2D com duas populações de agentes concorrentes, não consigo vê-los visualmente. Usarei o Matplotlib para visualizar essa simulação baseada em agente em Python. Nos parágrafos seguintes, demonstro como fazer isso.
Matplotlib visualiza simulação baseada em agente em Python
Conforme mostrado por mim em uma das minhas postagens anteriores no blog, o Matplotlib pode ser usado para visualizar grades 2D em Python. Eu coloquei uma referência na forma de um link no final deste artigo. Certifique-se de ler caso queira implementar esse tipo de visualização do zero por conta própria.
No código exibido abaixo, uso o Matplotlib para visualizar cada célula na grade do campo de batalha. Eu faço isso criando uma matriz flutuante 2D usando uma compreensão de lista em Python. Em seguida, itero através de cada par de índices da grade 2D. Devido a cada par de índices na matriz flutuante corresponder a um par de índices na grade do campo de batalha, posso identificar células com agentes nelas. Eu sobrescrevo as células que contêm um agente. Resumindo, toda célula com agente do tipo A recebe float 1.0 enquanto toda célula com agente do tipo B recebe float 2.0.
#.imshow() needs a matrix with float elements;
population = [[0.0 for i in range(0,100)] for i in range(0,100)]
# if agent is of type A, put a 1.0, if of type B, pyt a 2.0
for i in range(1,100):
for j in range(1,100):
if battlefield[i][j] == None: # empty
pass # leave 0.0 in population cell
elif battlefield[i][j].group == "A": # group A agents
population[i][j] = 1.0 # 1.0 means "A"
else: # group B agents
population[i][j] = 2.0 # 2.0 means "B"
Não consigo visualizar o battlefiend. Para fazer isso, importo pyplot e cores do Matplotlib em Python. Isso me permite criar um objeto ListedColormap. Os objetos ListedColormap podem ser baseados como referências ao método pyplot.imshow(). Eu mostro isso no código abaixo.
# import pyplot and colors from matplotlib
from matplotlib import pyplot, colors
# using colors from matplotlib, define a color map
colormap = colors.ListedColormap(["lightgrey","green","blue"])
# define figure size using pyplot
pyplot.figure(figsize = (12,12))
# using pyplot add a title
pyplot.title("battlefield before simulation run (green = A, blue = B)",
fontsize = 24)
# using pyplot add x and y labels
pyplot.xlabel("x coordinates", fontsize = 20)
pyplot.ylabel("y coordinates", fontsize = 20)
# adjust x and y axis ticks, using pyplot
pyplot.xticks(fontsize = 16)
pyplot.yticks(fontsize = 16)
# use .imshow() method from pyplot to visualize agent locations
pyplot.imshow(X = population,
cmap = colormap)
<matplotlib.image.AxesImage em 0x22495922ac8>

Agora podemos executar e visualizar uma simulação baseada em agente em Python. Embora mostre apenas uma iteração da simulação neste artigo, coloquei uma referência vinculada a outro artigo no qual utilizo a execução de um experimento de simulação inteiro.
Implementando estratégias para interação agente
Para isso implementamos duas estratégias de ataque:
O Grupo A tem a estratégia de acertar sempre o mesmo agente em cada rodada
O Grupo B tem uma estratégia aleatória e independente para atacar os inimigos. Isso significa que cada agente do tipo B atacará um inimigo selecionado aleatoriamente ao alcance desse agente.
A simulação agora é conduzida sob as seguintes condições:
1) Cada rodada é uma iteração
2) A cada rodada, cada agente pode atacar um agente ao seu alcance
3) O alcance de um agente é definido no início da simulação e o padrão é 10
4) Se um agente morrer ele não estará mais localizado no campo de batalha
5) Um agente morre quando sua pontuação de vida iguala ou fica abaixo de zero
6) Cada agente tem um dano de ataque distribuído aleatoriamente, variando de 10 a 60
7) Em cada rodada todos os agentes podem lançar um ataque
Com essas regras em vigor, agora irei iterar por 50 rodadas de luta. No final, imprimirei um gráfico dos agentes restantes no campo de batalha. A implementação segue abaixo:
for counter in range(0,50): # neste caso estou conduzindo 50 iterações # iterando por todas as células no campo de batalha para i no intervalo(0,len(campo de batalha)): para j no intervalo(0,len(campo de batalha)): #print("iteração de nível superior, i: "+str(i)+", j: "+str(j)) # verifica se existe um agente na respectiva célula if battlefield[i][j] != Nenhum: # dependendo do tipo: executa a respectiva estratégia de ataque se campo de batalha[i][j].grupo == "A": encontrado_i = Nenhum found_j = Nenhum # procura nas células vizinhas na mesma ordem para cada iteração para k no intervalo(i-10,i+11): para l no intervalo(j-10,j+11): # verifica se há valores de índice negativos; se assim for - quebre! se k < 0 ou l < 0: pausa # verifique se há valores de índice acima de 99, se for o caso, interrompa! se k > 99 ou l > 99: pausa se campo de batalha[k][l]: if battlefield[k][l].group == "B": # então este é um inimigo if found_i == Nenhum: encontrado_i = k encontrado_j = l # causa dano ao inimigo identificado se encontrado_i: battlefield[found_i][found_j].life = battlefield[found_i][found_j].life - random.randint(10,60) outro: # primeiro verifique se há um inimigo em uma das células ao redor inimigo_encontrado = Falso para k no intervalo(i-10,i+11): para l no intervalo(j-10,j+11): # verifica se há índice negativo, se sim, vá para a próxima iteração se k < 0 ou l < 0: pausa # verifique se há valores de índice acima de 99, se for o caso, interrompa se k > 99 ou l > 99: pausa if battlefield[k][l] != Nenhum: se campo de batalha[k][l].grupo == "A": inimigo_encontrado = Verdadeiro # seleciona uma linha aleatória e uma coluna aleatória encontrado_i = Nenhum found_j = Nenhum enquanto inimigo_encontrado e encontrado_i == Nenhum: k = random.randint(i-10,i+10) l = random.randint(j-10,j+10) # verifique se há índice negativo, se for, continue para a próxima iteração se k < 0 ou l < 0: Prosseguir # verifique se há valor de índice > 99, se sim, continue se k > 99 ou l > 99: Prosseguir se k != i: se campo de batalha[k][l]: se campo de batalha[k][l].grupo == "A": encontrado_i = k encontrado_j = l outro: se l != j: se campo de batalha[k][l]: se campo de batalha[k][l].grupo == "A": encontrado_i = k encontrado_j = l # causa dano ao inimigo identificado se encontrado_i: battlefield[found_i][found_j].life = battlefield[found_i][found_j].life - random.randint(10,60) # identificando agentes com pontuação de vida de pontuação ou abaixo - e removendo-os da grade para i no intervalo(0,len(campo de batalha)): para j no intervalo(0,len(campo de batalha)): se campo de batalha[i][j]: se campo de batalha[i][j].vida <= 0: campo de batalha[i][j] = Nenhum # produzindo um gráfico de todos os locais do campo de batalha, 10 iterações após população = [[0,0 para i no intervalo(0,100)] para i no intervalo(0,100)] # se agente for do tipo A, coloque 1.0, se for do tipo B, pyt 2.0 para i no intervalo (1.100): para j no intervalo (1.100): if battlefield[i][j] == Nenhum: # vazio pass # deixa 0.0 na célula de população elif battlefield[i][j].grupo == "A": # agentes do grupo A população[i][j] = 1,0 # 1,0 significa "A" else: # agentes do grupo B população[i][j] = 2,0 # 2,0 significa "B" # import pyplot e cores do matplotlib from matplotlib import pyplot, colors # usando cores do matplotlib , defina um mapa de cores colormap = colors.ListedColormap(["lightgrey","green","blue"]) # define o tamanho da figura usando pyplot pyplot.figure(figsize = (12,12)) # usando pyplot adicione um título pyplot.title("campo de batalha após 50 iterações (verde = A, azul = B)", tamanho da fonte = 24) # usando pyplot adicione rótulos x e y pyplot.xlabel("coordenadas x", tamanho da fonte = 20) pyplot.ylabel("coordenadas y", tamanho da fonte = 20) # ajusta os tiques dos eixos x e y, usando pyplot pyplot.xticks(tamanho da fonte = 16) pyplot.yticks(tamanho da fonte = 16) # use o método .imshow() do pyplot para visualizar a localização dos agentes pyplot.imshow(X = população, cmap = mapa de cores)
<matplotlib.image.AxesImage em 0x22495be1848>

Considerações finais e referências a conteúdo relacionado
Em algumas postagens a seguir, limparei o código e empacotarei sua funcionalidade em funções reutilizáveis. Em seguida, conduzirei um estudo de simulação mais abrangente no qual vários parâmetros são variados para investigar seu impacto no resultado da batalha.
Neste exemplo, usei listas do Python como meus contêineres de agentes preferidos. No entanto, modelos semelhantes podem ser construídos usando, por exemplo, arrays NumPy .
Se você estiver interessado em simulação baseada em agentes, poderá se interessar pelo seguinte conteúdo:
- Link: Desenvolvendo um modelo simples de simulação baseado em agente em Python
- Link: Métodos de simulação para analistas de SCM
- Link: Modelagem baseada em agente em Python
- Link: Visualizando grade 2D com Matplotlib em Python
- Link: Simulação baseada em agente de mercados de eletricidade

Cientista de dados com foco em simulação, otimização e modelagem em R, SQL, VBA e Python
Leave a Reply