I et tidligere indlæg implementerede jeg en simpel agentbaseret simulationsmodel. Modellen omfatter bla. grupper af agenter, som kan placeres på et slagmarkensgitter. Modellen blev kodet i Python og anvender Matplotlib til visualiseringer.
Agenterne blev modelleret som en klasse, som vist forneden:
# klasse; definerer agenter som abstrakt datatype
class agent:
# init-metode, konstruktormetode til agenter
def __init__(self,x,y,group):
self.life = 100 # agentens livscore
self.x = x
self.y = y
self.group = group
Et 2-dimensionelt array til modellering af slagmarksgitteret blev oprettet med en listeforståelse i Python:
# opretter tom 100 x 100 liste ved hjælp af listeforståelse i python battlefield = [[None for i in range(0,100)] for i in range(0,100)]
En hjælperfunktion til oprettelse af en agentgruppe med defineret gruppestørrelse blev implementeret som vist nedenfor:
# definer en funktion til oprettelse af agenter og tildeling af dem til gitter
def agentCreator(size,group,groupList,field,n,m):
# loop gennem hele gruppen, dvs. i dette tilfælde 1000 enheder
for j in range(0,size):
# vælg tilfældig tilgængelig placering
while True:
# tilfældig x koordinat
x = random.choice(range(0,n))
# tilfældig y koordinat
y = random.choice(range(0,m))
# kontroller om stedet er tilgængeligt; hvis ikke så gentages det
if field[x][y] == None:
field[x][y] = agent(x=x,y=y,group=group)
# tilføj reference til agentobjekt til gruppelisten
groupList.append(field[x][y])
# exit under loop; stedet på marken tages
break
Ved hjælp af disse modelkomponenter oprettede jeg en indledende population på slagmarken og plottede agentplaceringer ved hjælp af matplotlib. Det sker i nedenstående kode:
# liste med tilgængelige x- og y-placeringer
locations = battlefield.copy() # using .copy prevents copying by reference
# opret en tom liste til fremover at indeholde agentreferencer, skriv A & B
agents_A = []
agents_B = []
# tildele tilfældige pletter til agenter i gruppe A og 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 () har brug for en matrix med flydelementer;
population = [[0.0 for i in range(0,100)] for i in range(0,100)]
# hvis agenten er af type A, skal du sætte en 1.0, hvis af type B, pyt a 2.0
for i in range(1,100):
for j in range(1,100):
if battlefield[i][j] == None: # tom
pass # efterlad 0,0 i befolkningscelle
elif battlefield[i][j].group == "A": # gruppe med A agenter
population[i][j] = 1.0 # 1.0 betyder "A"
else: # group B agents
population[i][j] = 2.0 # 2.0 betyder "B"
# importer pyplot og farver fra matplotlib
from matplotlib import pyplot, colors
# brug farver fra matplotlib til at definere et farvekort
colormap = colors.ListedColormap(["lightgrey","green","blue"])
# definer figurstørrelse ved hjælp af pyplot
pyplot.figure(figsize = (12,12))
# ved hjælp af pyplot tilføj en titel
pyplot.title("battlefield before simulation run (green = A, blue = B)",
fontsize = 24)
# ved hjælp af pyplot tilføj x- og y-etiketter
pyplot.xlabel("x coordinates", fontsize = 20)
pyplot.ylabel("y coordinates", fontsize = 20)
# juster x- og y-aksemærker ved hjælp af pyplot
pyplot.xticks(fontsize = 16)
pyplot.yticks(fontsize = 16)
# brug metoden .imshow () fra pyplot til at visualisere agentplaceringer
pyplot.imshow(X = population,
cmap = colormap)
<matplotlib.image.AxesImage at 0x22495922ac8>

Vi kan nu gennemføre en simpel simulation. Hertil implementerer vi to angrebsstrategier:
Gruppe A har strategien om altid at ramme den samme agent i hver runde
Gruppe B har en tilfældig og uafhængig strategi for angreb på fjender. Dette betyder, at hver agent af type B vil angribe en tilfældigt valgt fjende inden for sin rækkevidde
Simulationen udføres nu under følgende betingelser:
1) Hver runde svarer til én iteration
2) I hver runde kan hver agent angribe en agent inden for sin rækkevidde
3) En agents rækkevidde defineres i starten af simulationen og er som standard 10
4) Døde agenter fjernes fra slagmarken
5) En agent dør når hans livscore er lig med eller går under nul
6) Hver agent har en tilfældigt fordelt angrebsskade, der spænder fra 10 til 60
7) I hver runde kan alle agenter starte ét angreb
Med disse regler på plads vil jeg nu simulere 50 kamprunder. I slutningen vil jeg udgive et plot af de resterende agenter på slagmarken. Implementeringen følger her:
for counter in range(0,50): # i dette tilfælde gennemfører jeg 50 gentagelser
# iterer gennem alle celler på slagmarken
for i in range(0,len(battlefield)):
for j in range(0,len(battlefield)):
#print ("top tier iteration, i:" + str (i) + ", j:" + str (j))
# kontroller, om der er en agent i den respektive celle
if battlefield[i][j] != None:
# afhængigt af typen: udfør den respektive angrebsstrategi
if battlefield[i][j].group == "A":
found_i = None
found_j = None
# se i naboceller i samme rækkefølge for hver iteration
for k in range(i-10,i+11):
for l in range(j-10,j+11):
# tjek for negative indeksværdier; hvis ja - break!
if k < 0 or l < 0:
break
# tjek for indeksværdier over 99, hvis ja - break!
if k > 99 or l > 99:
break
if battlefield[k][l]:
if battlefield[k][l].group == "B": # så er dette en fjende
if found_i == None:
found_i = k
found_j = l
# behandle skader på identificeret fjende
if found_i:
battlefield[found_i][found_j].life = battlefield[found_i][found_j].life - random.randint(10,60)
else:
# kontroller først, om der overhovedet er en fjende i en af de omkringliggende celler
enemy_found = False
for k in range(i-10,i+11):
for l in range(j-10,j+11):
# tjek for negativt indeks, hvis det er tilfældet, gå til næste iteration
if k < 0 or l < 0:
break
# tjek for indeksværdier over 99, hvis ja bryde
if k > 99 or l > 99:
break
if battlefield[k][l] != None:
if battlefield[k][l].group == "A":
enemy_found = True
# vælg en tilfældig række og en tilfældig kolonne
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)
# tjek for negativt indeks, hvis så fortsæt til næste iteration
if k < 0 or l < 0:
continue
# tjek for indeksværdi> 99, hvis det fortsætter
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
# behandle skader på identificeret fjende
if found_i:
battlefield[found_i][found_j].life = battlefield[found_i][found_j].life - random.randint(10,60)
# identificere agenter med livscore på score eller derunder - og fjerne dem fra nettet
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
# producerer et plot af alle slagmarkplaceringer, 10 iterationer efter
population = [[0.0 for i in range(0,100)] for i in range(0,100)]
# hvis agenten er af type A, skal du sætte en 1.0, hvis af type B, pyt a 2.0
for i in range(1,100):
for j in range(1,100):
if battlefield[i][j] == None: # tom
pass # efterlad 0,0 i befolkningscelle
elif battlefield[i][j].group == "A": # gruppe A-agenter
population[i][j] = 1.0 # 1.0 betyder "A"
else: # gruppe B-agenter
population[i][j] = 2.0 # 2.0 betyder "B"
# importer pyplot og farver fra matplotlib
from matplotlib import pyplot, colors
# brug farver fra matplotlib til at definere et farvekort
colormap = colors.ListedColormap(["lightgrey","green","blue"])
# definer figurstørrelse ved hjælp af pyplot
pyplot.figure(figsize = (12,12))
# ved hjælp af pyplot tilføj en titel
pyplot.title("battlefield after 50 iterations (green = A, blue = B)",
fontsize = 24)
# ved hjælp af pyplot tilføj x- og y-etiketter
pyplot.xlabel("x coordinates", fontsize = 20)
pyplot.ylabel("y coordinates", fontsize = 20)
# juster x- og y-aksemærker ved hjælp af pyplot
pyplot.xticks(fontsize = 16)
pyplot.yticks(fontsize = 16)
# brug metoden .imshow () fra pyplot til at visualisere agentplaceringer
pyplot.imshow(X = population,
cmap = colormap)
<matplotlib.image.AxesImage at 0x22495be1848>

I dette eksempel brugte jeg Python-lister som containere (beholdere) vor agenter. Men lignende modeller kan også konstrueres ved hjælp af f.eks. NumPy-arrays.

Industriingeniør som gerne beskæftiger sig med optimering, simulation og matematisk modellering i R, SQL, VBA og Python

Leave a Reply