I et tidligere indlæg demonstrerede jeg hvordan man visualiserer et 2D-gitter ved hjælp af matplotlib og pyplot i Python. Dette indlæg er ment som en introduktion til hvordan man visualiserer en agentbaseret simulationsmodel i Python. I dette indlæg modellerer jeg desuden fundamentet for en simpel agentbaseret simulationsmodel ved hjælp af et 2D-array (2D gitter): Et gitter (eller man kunne sige, et “miljø”) kan befolkes af to typer agenter: Agenter af type A eller agenter af type B.
Dette 2D gitter fungerer som en slagmark hvorpå to grupper af agenter vil kæmpe en kamp. Jeg kalder det derfor også for et slagmarksgitter.
Agenter har det samme sæt attributter, hvoraf den ene er deres gruppemedlemskab. Udover dette har de alle en livscore, som er lige store når simulationen starter. Endeligt har de et sæt koordinater (x- og y-koordinater) som repræsenterer deres rumlige placering i en 2-dimensionel verden.
Jeg vil ikke udføre en helt simulationsstudie i dette indlæg. Dette gøres i et kommende indlæg. Jeg vil derimod bruge modellen fra dette indlæg i fremtidige indlæg for at simulere kampe mellem to grupper af agenter.
I kodestykket nedenfor definerer jeg en klasse for agenter, som indeholder alle relevante attributter og metoder. Dokumentation føjes til koden i form af kommentarer.
# klasse, der definerer agenter som abstrakte datatyper class agent: # init-metode, konstruktormetoden for agenter def __init__(self,x,y,group): self.life = 100.0 # agentens livscore self.x = x # placering langs x-aksen self.y = y # placering langs y-aksen self.group = group # gruppemedlemskab
Næste trin er at definere et 2D-gitterarray i form af en 2D-liste. Rækker repræsenterer x-koordinater, kolonner repræsenterer y-koordinater. Denne 2D-liste repræsenterer slagmarken og er altså det såkaldte slagmarksgitter. Jeg definerer det til at have en størrelse på 100 x 100 celler, dvs. 10.000 placeringer. Jeg vil bruge standardlistetypen i Python for at definere slagmarksgitteret. Det nemmeste er at bruge en list-comprehension in Python for at bygge gitteret op.
# 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)]
Dernæst opretter jeg to grupper af agenter og finder dem tilfældigt på slagmarken. I separate lister gemmer jeg desuden henvisninger til agentobjekterne. Jeg opretter 1000 agenter i gruppe A og 1000 agenter i gruppe B.
# liste med tilgængelige x- og y-placeringer locations = battlefield.copy() # using .copy prevents copying by reference # opret en tom liste til at indeholde agentreferencer i fremtiden, skriv A & B agents_A = [] agents_B = [] # tildel tilfældige placeringer til agenter i gruppe A og B; # - til dette har jeg brug for det tilfældige modul, så importer det import random # - 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 # - Jeg befolker slagmarken ved hjælp af funktionen agentCreator 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)
2D-listen “slagmark” indeholder nu enten “ingenting” (None) eller agentreferencer, af enten type A eller B. Alle agenter har en livscore på 100 idet kampen endnu ikke har startet.
For at fuldføre dette første indlæg på agentbaseret simulering vil jeg visualisere placeringen af type A-agenter og placeringen af type B-agenter i to separate gitterdiagrammer. Nøglen til at gøre dette er at bruge matplotlib.pyplot med metoden .imshow():
# .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 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 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 0x1c756b04c88>

I et kommende indlæg vil jeg bruge denne grundlæggende model, der er udviklet i dette indlæg, til at simulere en kamp mellem de to grupper af agenter. Vi vil se på forskellige parametre og vil forstå hvordan de påvirker resultatet af kampen.



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