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.
Wirtschaftsingenieur mit Interesse an Optimierung, Simulation und mathematischer Modellierung in R, SQL, VBA und Python
Leave a Reply