En una publicación anterior, construí un modelo de simulación simple basado en agentes, que contiene grupos de agentes que se pueden ubicar en una cuadrícula de campo de batalla. El modelo fue codificado en Python, usando matplotlib para la visualización.
Los agentes se modelaron como una clase, como se muestra a continuación:
# clase, definiendo agentes como tipos de datos abstractos class agent: # init-method, el método constructor para agentes def __init__(self,x,y,group): self.life = 100 # agent's life score self.x = x self.y = y self.group = group
Se creó una matriz bidimensional para modelar la cuadrícula del campo de batalla con una lista de comprensión en Python:
# crear una lista vacía de 100 x 100 usando la comprensión de la lista en Python battlefield = [[None for i in range(0,100)] for i in range(0,100)]
Se implementó una función auxiliar para crear un grupo de agentes con un tamaño de grupo definido, como se muestra a continuación:
# - definir una función para crear agentes y asignarlos a la cuadrícula def agentCreator(size,group,groupList,field,n,m): # recorrer todo el grupo, es decir, en este caso 1000 unidades for j in range(0,size): # seleccionar ubicación aleatoria disponible while True: # coordenada x aleatoria x = random.choice(range(0,n)) # coordenada y aleatoria y = random.choice(range(0,m)) # compruebe si hay lugar disponible; si no, repita if field[x][y] == None: field[x][y] = agent(x=x,y=y,group=group) # agregar la referencia del objeto del agente a la lista de grupos groupList.append(field[x][y]) # salir mientras bucle; se toma el lugar en el campo break
Usando estos componentes del modelo, creé una población inicial del campo de batalla y tracé las ubicaciones de los agentes usando matplotlib. Esto se hace en el siguiente código:
# lista con ubicaciones xey disponibles locations = battlefield.copy() # using .copy prevents copying by reference # cree una lista vacía para contener referencias de agentes en el futuro, escriba A y B agents_A = [] agents_B = [] # asignar lugares aleatorios a los agentes del grupo A y 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) # .imshow () necesita una matriz con elementos flotantes; population = [[0.0 for i in range(0,100)] for i in range(0,100)] # si el agente es de tipo A, poner 1.0, si es de tipo B, pyt 2.0 for i in range(1,100): for j in range(1,100): if battlefield[i][j] == None: vacía pass # dejar 0.0 en la celda de población elif battlefield[i][j].group == "A": # group A agents population[i][j] = 1.0 # 1.0 signifa "A" else: # group B agents population[i][j] = 2.0 # 2.0 signifa "B" # importar pyplot y colores de matplotlib from matplotlib import pyplot, colors # usando colores de matplotlib, defina un mapa de color colormap = colors.ListedColormap(["lightgrey","green","blue"]) # definir el tamaño de la figura usando pyplot pyplot.figure(figsize = (12,12)) # usando pyplot agregue un título pyplot.title("battlefield before simulation run (green = A, blue = B)", fontsize = 24) # usando pyplot agregue etiquetas xey pyplot.xlabel("x coordinates", fontsize = 20) pyplot.ylabel("y coordinates", fontsize = 20) # ajustar las marcas de los ejes xey, usando pyplot pyplot.xticks(fontsize = 16) pyplot.yticks(fontsize = 16) # use el método .imshow () de pyplot para visualizar las ubicaciones de los agentes pyplot.imshow(X = population, cmap = colormap)
<matplotlib.image.AxesImage at 0x22495922ac8>
Ahora podemos realizar una ejecución de simulación simple que en publicaciones posteriores se convertirá en un experimento. Para ello implementamos dos estrategias de ataque: El grupo A tiene la estrategia de golpear siempre al mismo agente en cada ronda. El grupo B tiene una estrategia aleatoria e independiente para atacar enemigos. Esto significa que cada agente de tipo B atacará a un enemigo seleccionado al azar dentro del alcance de ese agente. La simulación ahora se realiza en las siguientes condiciones:
1) Cada ronda es una iteración.
2) En cada ronda, cada agente puede atacar a un agente a su alcance.
3) El alcance de un agente se define al comienzo de la simulación y el valor predeterminado es 10
4) Si un agente muere, ya no estará ubicado en el campo de batalla.
5) Un agente muere cuando su puntuación de vida es igual o inferior a cero.
6) Cada agente tiene un daño de ataque distribuido aleatoriamente, que va de 10 a 60.
7) En cada ronda, todos los agentes pueden lanzar un ataque.
Con estas reglas en su lugar, ahora repetiré 50 rondas de lucha. Al final, imprimiré un diagrama de los agentes restantes en el campo de batalla. La implementación sigue a continuación:
for counter in range(0,50): # en este caso estoy realizando 50 iteraciones # iterando a través de todas las celdas en el campo de batalla for i in range(0,len(battlefield)): for j in range(0,len(battlefield)): #print ("iteración de nivel superior, i:" + str (i) + ", j:" + str (j)) # comprobar si hay un agente en la celda respectiva if battlefield[i][j] != None: # dependiendo del tipo: ejecutar la estrategia de ataque respectiva if battlefield[i][j].group == "A": found_i = None found_j = None # buscar en las celdas vecinas en el mismo orden para cada iteración for k in range(i-10,i+11): for l in range(j-10,j+11): # comprobar si hay valores de índice negativos; si es así, ¡rompe! if k < 0 or l < 0: break # compruebe si hay valores de índice superiores a 99, si es así, rompa! if k > 99 or l > 99: break if battlefield[k][l]: if battlefield[k][l].group == "B": # entonces este es un enemigo if found_i == None: found_i = k found_j = l # infligir daño al enemigo identificado if found_i: battlefield[found_i][found_j].life = battlefield[found_i][found_j].life - random.randint(10,60) else: # primero verifique si hay un enemigo en una de las celdas circundantes. enemy_found = False for k in range(i-10,i+11): for l in range(j-10,j+11): # comprobar si hay un índice negativo, si es así, pasar a la siguiente iteración if k < 0 or l < 0: break # compruebe los valores del índice por encima de 99, si es así, rompa if k > 99 or l > 99: break if battlefield[k][l] != None: if battlefield[k][l].group == "A": enemy_found = True # seleccione una fila aleatoria y una columna aleatoria found_i = None found_j = None while enemy_found and found_i == None: k = random.randint(i-10,i+10) l = random.randint(j-10,j+10) # compruebe si hay un índice negativo, si es así, continúe con la siguiente iteración if k < 0 or l < 0: continue # compruebe el valor del índice> 99, si es así, continúe if k > 99 or l > 99: continue if k != i: if battlefield[k][l]: if battlefield[k][l].group == "A": found_i = k found_j = l else: if l != j: if battlefield[k][l]: if battlefield[k][l].group == "A": found_i = k found_j = l # infligir daño al enemigo identificado if found_i: battlefield[found_i][found_j].life = battlefield[found_i][found_j].life - random.randint(10,60) # identificar agentes con una puntuación de vida de puntuación o inferior, y eliminarlos de la cuadrícula for i in range(0,len(battlefield)): for j in range(0,len(battlefield)): if battlefield[i][j]: if battlefield[i][j].life <= 0: battlefield[i][j] = None # produciendo una trama de todas las ubicaciones del campo de batalla, 10 iteraciones después population = [[0.0 for i in range(0,100)] for i in range(0,100)] # si el agente es de tipo A, poner 1.0, si es de tipo B, pyt 2.0 for i in range(1,100): for j in range(1,100): if battlefield[i][j] == None: # vacía pass # leave 0.0 in population cell elif battlefield[i][j].group == "A": # agentes del grupo A population[i][j] = 1.0 # 1.0 signifa "A" else: # group B agents population[i][j] = 2.0 # 2.0 signifa "B" # importar pyplot y colores de matplotlib from matplotlib import pyplot, colors # usando colores de matplotlib, defina un mapa de color colormap = colors.ListedColormap(["lightgrey","green","blue"]) # definir el tamaño de la figura usando pyplot pyplot.figure(figsize = (12,12)) # using pyplot add a title pyplot.title("battlefield after 50 iterations (green = A, blue = B)", fontsize = 24) # usando pyplot agregue etiquetas xey pyplot.xlabel("x coordinates", fontsize = 20) pyplot.ylabel("y coordinates", fontsize = 20) # ajustar las marcas de los ejes xey, usando pyplot pyplot.xticks(fontsize = 16) pyplot.yticks(fontsize = 16) # use el método .imshow () de pyplot para visualizar las ubicaciones de los agentes pyplot.imshow(X = population, cmap = colormap)
<matplotlib.image.AxesImage at 0x22495be1848>
En algunas publicaciones siguientes limpiaré el código y empaquetaré su funcionalidad en funciones reutilizables. Luego llevaré a cabo un estudio de simulación más completo en el que se varían varios parámetros para investigar su impacto en el resultado de la batalla.
En este ejemplo utilicé listas de Python como contenedores de agentes de mi elección. Sin embargo, se pueden construir modelos similares usando, por ejemplo, Matrices NumPy.
Ingeniero industrial especializado en optimización y simulación (R, Python, SQL, VBA)
Leave a Reply