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