En simpel agentbaseret simulation, visualiseret med Matplotlib i Python

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.

Leave a Reply

Skriv et svar

Din e-mailadresse vil ikke blive publiceret.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Close

Meta