Ein einfacher agentenbasierter Simulationslauf, mit Matplotlib in Python visualisiert

In einem früheren Beitrag habe ich ein einfaches agentenbasiertes Simulationsmodell erstellt. Das Modell enthält Gruppen von Agenten die sich auf einem Schlachtfeldgitter befinden. Das Modell wurde in Python entwickelt und mithilfe von Matplotlib visualisiert.

Die Agenten wurden als Klasse modelliert, wie unten dargestellt:

# Klasse, die Agenten als abstrakten Datentypen darstellt
class agent:
    # init-Methode, die Konstruktormethode für Agenten
    def __init__(self,x,y,group):
        self.life = 100 # agent's life score
        self.x = x
        self.y = y
        self.group = group

Eine zweidimensionelle Liste zur Modellierung des Schlachtfeldgitters wurde mit einer List-Comprehension in Python erstellt:

# Erstellen einer leeren 100 x 100-Liste mithilfe des List-Comprehension in Python
battlefield = [[None for i in range(0,100)] for i in range(0,100)]

Eine Hilfsfunktion zur Erstellung einer Gruppe von Agenten mit definierter Gruppengröße wurde wie folgt implementiert:

# - Definiere eine Funktion zum Erstellen und Zuweisen von Agenten zum Raster
def agentCreator(size,group,groupList,field,n,m):
    # Schleife durch die gesamte Gruppe, d. h. in diesem Fall 1000 Einheiten
    for j in range(0,size):
        # Wähle einen zufällig verfügbaren Ort
        while True:
            # zufällige x-Koordinate
            x = random.choice(range(0,n))
            # zufällige y-Koordinate
            y = random.choice(range(0,m))
            # Überprüfen ob ein Platz verfügbar ist. Wenn nicht, wiederhole Vorgang
            if field[x][y] == None:
                field[x][y] = agent(x=x,y=y,group=group)
                # Agentenobjektreferenz an Gruppenliste anhängen
                groupList.append(field[x][y])
                # beende while-Schleife; 
                break

Mit diesen Modellkomponenten erstellte ich eine erste Schlachtfeldpopulation und zeigte mithilfe von Matplotlib Agentenpositionen auf. Dies geschah in folgendem Code:

# Liste mit verfügbaren x- und y-Positionen
locations = battlefield.copy() # using .copy prevents copying by reference
# Erstellen Sie eine leere Liste für zukünftige Agentenreferenzen. Geben Sie A & B ein
agents_A = []
agents_B = []
# Zuweisen von zufälligen Stellen zu Agenten der Gruppen A und 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 () benötigt eine Matrix mit float-Elementen;
population = [[0.0 for i in range(0,100)] for i in range(0,100)]
# Wenn der Agent vom Typ A ist, geben Sie eine 1,0 ein. 
# Wenn der Typ B ist, geben Sie eine 2,0 ein.
for i in range(1,100):
    for j in range(1,100):
        if battlefield[i][j] == None: # leer
            pass # 0,0 in der Populationszelle belassen
        elif battlefield[i][j].group == "A": # Agenten der Gruppe A
            population[i][j] = 1.0 # 1.0 bedeutet "A"
        else: # Agenten aus Gruppe B
            population[i][j] = 2.0 # 2.0 bedeutet "B"
# Pyplot und Farben aus Matplotlib importieren
from matplotlib import pyplot, colors
# Definieren Sie mithilfe von Farben aus matplotlib eine Farbkarte
colormap = colors.ListedColormap(["lightgrey","green","blue"])
# Definieren Sie die Figurengröße mit Pyplot
pyplot.figure(figsize = (12,12))
# Mit Pyplot einen Titel hinzufügen
pyplot.title("battlefield before simulation run (green = A, blue = B)",
            fontsize = 24)
# Mit Pyplot x- und y-Beschriftungen hinzufügen
pyplot.xlabel("x coordinates", fontsize = 20)
pyplot.ylabel("y coordinates", fontsize = 20)
# Passen Sie die Ticks der x- und y-Achse mithilfe des Pyplots an
pyplot.xticks(fontsize = 16)
pyplot.yticks(fontsize = 16)
# Verwenden Sie die .imshow () -Methode von pyplot, um die Agentenpositionen zu visualisieren
pyplot.imshow(X = population,
             cmap = colormap)
<matplotlib.image.AxesImage at 0x22495922ac8>

Wir können jetzt einen einfachen Simulationslauf durchführen der in späteren Beiträgen zu einem Experiment wird. Dazu implementieren wir zwei Angriffsstrategien:

Gruppe A hat die Strategie, in jeder Runde immer den gleichen Agenten zu treffen

Gruppe B hat eine zufällige und unabhängige Strategie, um Feinde anzugreifen. Dies bedeutet, dass jeder Agent vom Typ B einen zufällig ausgewählten Feind in Reichweite dieses Agenten angreift.

Die Simulation wird nun unter folgenden Bedingungen durchgeführt:

1) Jede Runde entspricht einer Iteration
2) In jeder Runde kann jeder Agent einen Agenten in seiner Reichweite angreifen
3) Die Reichweite eines Agenten wird zu Beginn der Simulation definiert und ist standardmäßig 10

4) Wenn ein Agent stirbt, befindet er sich nicht mehr auf dem Schlachtfeld

5) Ein Agent stirbt, wenn sein Lebenswert gleich oder unter Null ist

6) Jeder Agent hat einen zufällig verteilten Angriffsschaden zwischen 10 und 60

7) In jeder Runde können alle Agenten einen Angriff starten

Mit diesen Regeln werde ich 50 Kampfrunden durchlaufen. Die Implementierung folgt unten:

for counter in range(0,50): # In diesem Fall führe ich 50 Iterationen durch
    # Durchlaufen aller Zellen auf dem Schlachtfeld
    for i in range(0,len(battlefield)):
        for j in range(0,len(battlefield)):
            #print ("Iteration der obersten Ebene, i:" + str (i) + ", j:" + str (j))
            # Überprüfen Sie, ob sich in der jeweiligen Zelle ein Agent befindet
            if battlefield[i][j] != None:
                # je nach Typ: jeweilige Angriffsstrategie ausführen
                if battlefield[i][j].group == "A":
                    found_i = None
                    found_j = None
                    # Suchen Sie in benachbarten Zellen für jede Iteration in derselben Reihenfolge
                    for k in range(i-10,i+11):
                        for l in range(j-10,j+11):
                            # auf negative Indexwerte prüfen; wenn ja - Pause!
                            if k < 0 or l < 0:
                                break
                            # auf Indexwerte über 99 prüfen, wenn ja, brechen!
                            if k > 99 or l > 99:
                                break
                            if battlefield[k][l]:
                                if battlefield[k][l].group == "B": # then this is an enemy
                                    if found_i == None:
                                        found_i = k
                                        found_j = l
                    # Füge dem identifizierten Feind Schaden zu
                    if found_i:
                        battlefield[found_i][found_j].life = battlefield[found_i][found_j].life - random.randint(10,60)
                else: 
                    # Überprüfen Sie zunächst, ob sich in einer der umliegenden Zellen überhaupt ein Feind befindet
                    enemy_found = False
                    for k in range(i-10,i+11):
                        for l in range(j-10,j+11):
                            # auf negativen Index prüfen, wenn ja, mit der nächsten Iteration abbrechen
                            if k < 0 or l < 0:
                                break
                            # Überprüfen Sie, ob Indexwerte über 99 vorliegen
                            if k > 99 or l > 99:
                                break
                            if battlefield[k][l] != None:
                                if battlefield[k][l].group == "A":
                                    enemy_found = True
                    # Wählen Sie eine zufällige Zeile und eine zufällige Spalte
                    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)
                        # Überprüfen Sie, ob ein negativer Index vorliegt. Fahren Sie in diesem Fall mit der nächsten Iteration fort
                        if k < 0 or l < 0:
                            continue
                        # Überprüfen Sie, ob der Indexwert> 99 ist
                        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
                    # Füge dem identifizierten Feind Schaden zu
                    if found_i:
                        battlefield[found_i][found_j].life = battlefield[found_i][found_j].life - random.randint(10,60)
    # Identifizieren von Agenten mit einer Lebensbewertung von oder weniger - und Entfernen dieser aus dem Raster
    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
# Erstellen einer Handlung aller Schlachtfeldstandorte, 10 Iterationen später
population = [[0.0 for i in range(0,100)] for i in range(0,100)]
# Wenn der Agent vom Typ A ist, geben Sie eine 1,0 ein, wenn er vom Typ B ist, geben Sie eine 2,0 ein
for i in range(1,100):
    for j in range(1,100):
        if battlefield[i][j] == None: # leer
            pass # 0,0 in der Populationszelle belassen
        elif battlefield[i][j].group == "A": # Agenten der Gruppe A.
            population[i][j] = 1.0 # 1.0 bedeutet "A"
        else: # group B agents
            population[i][j] = 2.0 # 2.0 bedeutet "B"
# Pyplot und Farben aus Matplotlib importieren
from matplotlib import pyplot, colors
# Definieren Sie mithilfe von Farben aus matplotlib eine Farbkarte
colormap = colors.ListedColormap(["lightgrey","green","blue"])
# Figurgröße mit Pyplot definieren
pyplot.figure(figsize = (12,12))
# Mit Pyplot einen Titel hinzufügen
pyplot.title("battlefield after 50 iterations (green = A, blue = B)",
            fontsize = 24)
# Mit Pyplot x- und y-Beschriftungen hinzufügen
pyplot.xlabel("x coordinates", fontsize = 20)
pyplot.ylabel("y coordinates", fontsize = 20)
# Passen Sie die Ticks der x- und y-Achse mithilfe des Pyplots an
pyplot.xticks(fontsize = 16)
pyplot.yticks(fontsize = 16)
# Verwenden Sie die .imshow () -Methode von pyplot, um die Agentenpositionen zu visualisieren
pyplot.imshow(X = population,
             cmap = colormap)
<matplotlib.image.AxesImage at 0x22495be1848>

Nach 50 Kampfrunden sieht das Schlachtfeld noch lebender Agenten so aus:

In einigen folgenden Beiträgen werde ich den Code bereinigen und seine Funktionalität in wiederverwendbare Funktionen packen. Ich werde dann eine umfassendere Simulationsstudie durchführen, in der verschiedene Parameter variiert werden um die Auswirkungen auf das übergeordnete Kampfergebnis zu untersuchen.

In diesem Beispiel habe ich Python-Listen als Agentencontainer meiner Wahl verwendet. Ähnliche Modelle können jedoch unter Verwendung von z.B. NumPy-Arrays entwickelt werden.

You May Also Like

Leave a Reply

Leave a Reply

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.