- Lässt sich die einmalige Ausführung eines Methoden-Kommandos nur über ein Klassenattribut realisieren (wie in meinem Code). Oder gibt es dafür "schlankere" Möglichkeiten, die die Klasse nicht unnötig "belasten"?
- Auch die coords-Liste (Liste der Koordinaten, die durchlaufen werden sollen) habe ich als Klassenattribut definiert, um sicherzustellen, dass pop den jeweils nächsten Wert aufruft. Lässt sich das auch schlanker machen, oder muss ich damit auch die Klasse "belasten"?
- Zur step-Iteration in der main-Funktion: Bislang habe ich die Anzahl der Durchläufe so gesetzt, dass ich "hinkomme". Wie bewerkstellige ich es, dass gestept wird, bis die Kommandos "abgearbeitet" sind (und nicht weiter)?
Vielen Dank im Voraus.
Hier der Code:
Code: Alles auswählen
import mesa
class Model(mesa.Model):
"""Modell mit 2 Agenten, die sich in einem Grid bewegen sollen"""
def __init__(self, number_of_agents, width, height):
super().__init__(number_of_agents, width, height)
self.num_agents = number_of_agents
self.grid = mesa.space.MultiGrid(width, height, True)
self.schedule = mesa.time.BaseScheduler(self)
"""Nachfolgend werden 2 Agenten produziert, als Modell-Attribute definiert
(damit z.B. ihre Position aus dem Modell aufgerufen werden kann) und auf dem Grid platziert"""
self.alter = Agent("alter", self)
self.schedule.add(self.alter)
coord = (self.random.randrange(self.grid.width), self.random.randrange(self.grid.height))
print(f"Anfangsposition von alter: {coord}")
self.grid.place_agent(self.alter, coord)
self.ego = Agent("ego", self)
self.schedule.add(self.ego)
coord = (self.random.randrange(self.grid.width), self.random.randrange(self.grid.height))
print(f"Anfangsposition von ego: {coord}")
self.grid.place_agent(self.ego, coord)
def step(self):
"""Ruft die step-Methode des Agenten auf"""
self.schedule.step()
class Agent(mesa.Agent):
def __init__(self, name, model):
super().__init__(name, model)
self.name = name
self._state = self.move_to_corner
self.coords = []
self.traverse_grid_first_run = True # Erster Durchlauf traverse_grid-Methode
def move_to_corner(self):
"""Bewegt die beiden Agenten von ihrer Ausgangsposition in die
linke untere Ecke"""
x, y = self.pos
if x > 0 or y > 0:
new_position = (max(x - 1, 0), max(y - 1, 0))
print(self.name, " position: ", new_position)
self.model.grid.move_agent(self, new_position)
else:
self._state = self.traverse_grid
def traverse_grid(self):
"""Agenten sollen das gesamte Grid in Schleifen durchlaufen, von links unten
(0,0) bis in die rechte obere Ecke, zunächst Prüfung der Ausgangsposition
für diesen Durchlauf"""
if self.traverse_grid_first_run:
print(self.name, ": Position zu Beginn traverse_grid: ", self.pos)
self.traverse_grid_first_run = False # Erster Durchlauf abgeschlossen
"Ermittlung der Koordinaten für den Durchlauf"
if not self.coords:
self.coords = [(i, j) if i % 2 == 0 else (i, self.model.grid.height - 1 - j)
for i in range(self.model.grid.width) for j in range(self.model.grid.height)][1:]
if self.pos != (self.model.grid.width - 1, self.model.grid.height - 1):
new_pos = self.coords.pop(0)
print(self.name, " position: ", new_pos)
self.model.grid.move_agent(self, new_pos)
else:
self._state = self.next_method
def next_method(self):
print(self.name, ": Position zu Beginn next_method: ", self.pos)
def step(self):
"""Wird von self.schedule.step aus dem Modell aufgerufen"""
self._state()
def main():
"""Produziert ein Grid"""
model = Model(2, 5, 5)
for _ in range(100):
model.step()
print("Endposition von alter:", model.alter.pos)
print("Endposition von ego:", model.ego.pos)
if __name__ == "__main__":
main()