Wie man mit einfachen Regeln Evolution mit dem Computer simulieren kann.
Simulation von künstlichem Leben in der toroidalen Welt von Wa-Tor
Wator (im Original: Wa-Tor) ist der Name der Computersimulation eines einfachen Räuber-Beute-Modells in einer toroidalen Welt. Die Simulation wurde von Alexander K. Dewdney in einem Artikel der Buchreihe Computer Kurzweil (1994) beschrieben [1]. Simuliert wird der hypothetische toroidale Planet Wator (von engl.: Water Torus), dessen Oberfläche vollständig mit Wasser bedeckt ist. In diesem Ozean leben nur zwei Spezies: Haie und deren Beutefische. Die Haie überleben nur durch das Jagen von Fischen, während die Fische von einer niemals versiegenden Planktonquelle ernährt werden.
Haie und Beutefische verhalten sich nach einem fest vorgegebenen Regelsatz. Im Verlauf der Simulation entwickelt sich eine interessante Dynamik, während die Populationen zwischen Aussterben und Überpopulation schwanken.
Pixel Size Prey Breed Time Energy per Prey Min shark spawn energy Chart SkipDie Simulation kann durch Ändern der folgenden Parameter beeinflusst werden:
| Parameter | Bedeutung |
|---|---|
| Pixel Size | Kantenlänge einer Simulationszelle in Bildschirm-Pixeln. Kleinere Werte ergeben ein feineres Raster mit mehr Tieren, aber höherer Rechenlast. Bei Änderung wird die Simulation zurückgesetzt. |
| Prey Breed Time | Brutdauer der Beutefische in Ticks. Jeder Fisch erhält bei Geburt ein zufälliges Maximalalter im Bereich [1, breedTime + 300]; beim Erreichen teilt er sich (Kind auf alter Position, Alter zurück auf 0). Kleinere Werte → schnelle Fischvermehrung. |
| Energy per Prey | Energiegewinn eines Hais pro gefressenem Fisch. Haie verlieren pro Tick 1 Energie und sterben bei 0. Höhere Werte machen Haie langlebiger und dominanter. |
| Min shark spawn energy | Energieschwelle, ab der ein Hai sich teilt. Beim Überschreiten halbiert sich die Energie auf Elternteil und Kind. Kleinere Werte → häufige Reproduktion, höhere Oszillationsfrequenz. |
In diesem Abschnitt werden wir kurz auf die Simulationsregeln eingehen. Die Simulationszeit wird in diskreten Zeitschritten fortgeführt. Die toroidale Welt wird auf einem zweidimensionalen Gitter simuliert, dessen gegenüberliegende Enden miteinander verbunden sind. Wenn ein Individuum auf der einen Seite den Simulationsbereich verlässt, so tritt es auf der gegenüberliegenden Seite wieder ein. Beutefische und Haie bewegen sich in jedem Zeitschritt (wenn möglich) und interagieren gemäß der im Folgenden beschriebenen Regeln.
In jedem Zeitschritt bewegt sich ein Beutefisch zufällig in eines seiner vier Nachbarfelder, vorausgesetzt dieses ist leer. Fische altern mit jedem Zeitschritt. Erreicht der Fisch ein bestimmtes Alter (die "breed time"), so endet sein Leben mit der Erzeugung von zwei Nachkommen. Die Alterszähler beider Nachkommen werden auf Null zurückgesetzt. Einer der Nachkommen entsteht in der Gitterzelle des alten Fischs, der zweite wird zufällig in einer freien Nachbarzelle erzeugt. Ist gerade keine Nachbarzelle frei, so kann kein weiterer Nachwuchs erzeugt werden. Die Nachkommen vollziehen erneut den gleichen Lebenszyklus.
Im Bild links sind die Bewegungsoptionen der Fische mit Pfeilen markiert. Fische dürfen sich nicht in Zellen bewegen, die bereits von Haien besetzt sind. Ist keine der Nachbarzellen frei, so bewegt sich der Fisch nicht.
Zusammenfassung der Regeln für die Bewegung der Beutefische:
Haie bewegen sich zufällig in benachbarte Felder. Durch jede Bewegung verliert ein Hai einen Energiepunkt. Fällt das Energielevel des Hais auf Null, so stirbt er. Wenn das Nachbarfeld, in das der Hai sich bewegt, einen Fisch enthält, so wird dieser gefressen und der Hai bekommt einen bestimmten Betrag an Energie gutgeschrieben. Zum Überleben braucht ein Hai regelmäßigen "Jagderfolg". Sobald ein Hai genügend Energie gesammelt hat, kann er in einem Nachbarfeld einen Nachkommen erzeugen. Der Nachkomme bekommt die Hälfte der Energie des Elterntieres. Der Alterszähler des Elterntieres wird im Fortpflanzungsfall zurückgesetzt.
Zusammenfassung der Regeln für die Bewegung der Räuber (Haie):Um die Berechnungsleistung zu erhöhen, wurden einige Änderungen am Algorithmus vorgenommen. Im Originalalgorithmus bewegen sich die Haie nicht zufällig. Sie steuern gezielt Nachbarzellen an, in denen sich Fische befinden. Dieses Bewegungsmuster wurde hier vereinfacht, um die Simulationsgeschwindigkeit zu erhöhen. Darüber hinaus wurde der Algorithmus dahingehend modifiziert, dass ein komplettes Aussterben einer der Spezies nicht möglich ist, jeweils ein Fisch und ein Hai sind unsterblich.
Diese Modifikation ist minimal, so dass sich kein sichtbarer Unterschied im Vergleich zur Originalsimulation ergibt. Alexander K. Dewdneys Implementierung ähnelt einem zellulären Automaten. Bei einer solchen Implementierung muss jede Zelle einzeln getestet werden, auch wenn sie leer ist. Das reduziert die Simulationsgeschwindigkeit. Die hier verwendete Implementierung verwendet daher eine verkettete Liste für die Speicherung der Haidaten. Dadurch muss der Algorithmus sich nur noch um die tatsächlich existierenden Individuen kümmern.
Populationsgröße im Verlauf der Zeit.
Zeichnet man die Anzahl der Individuen beider Spezies in einem Diagramm, so erhält man einen für Lotka-Volterra-Gleichungen typischen Verlauf. Dieses Verhalten wird durch zwei Differentialgleichungen beschrieben.
wobei:
Obwohl die Lösung der Differentialgleichungen ein periodisches Verhalten aufweist, kann diese Lösung nicht mittels normaler trigonometrischer Funktionen dargestellt werden. Eine vereinfachte linearisierte Lösung zeigt jedoch, dass die Kurve der Räuberpopulation der der Beute um 90 Grad vorauseilt. Eine ausführlichere Beschreibung der hier aufgeführten Informationen gibt es im Wikipedia-Artikel zu den Lotka-Volterra-Differentialgleichungen [3].
Einstellungsfenster des Wator-Bildschirmschoners
Dieser Artikel ist inzwischen über 20 Jahre alt. Im Original war die Simulation als Bildschirmschoner für Windows implementiert. Früher waren diese Programme viel verbreiteter als heute. Sie sollten ursprünglich verhindern dass sich ein statisches Computerbild auf den damals verwendeten Röhrenmonitoren einbrennt. Inzwischen sind sie weitgehend obsolet und ein Nischenprodukt geworden. Moderne Monitore sind nicht mehr von diesem Problem betroffen und werden in aller Regel ohnehin aus Energiespargründen automatisch vom Betriebssystem abgeschaltet.
Wie dem auch sei, der Originalbildschirmschoner kann noch immer heruntergeladen werden. Er ist in C++ geschrieben, die Grafikausgabe erfolgt in 2D mit der OpenGL-Bibliothek. Die Grundlagen der Programmierung von Bildschirmschonern mit MFC und OpenGL werden in [2] von Rachel Grey sehr gut beschrieben und zusammengefasst. Der Quellcode des Wa-Tor-Bildschirmschoners kann auf GitHub heruntergeladen und mit Visual Studio kompiliert werden.
Bei einem Windows-Bildschirmschoner handelt es sich um eine ausführbare Datei, welche die Dateiendung "*.scr" hat. Zusätzlich muss ein Bildschirmschoner noch einen fest vorgegebenen Satz an Kommandozeilenparametern implementieren. Diese Parameter erlauben es, den Bildschirmschoner zu konfigurieren bzw. auszuführen.
| Kommandozeilenparameter | Bildschirmschoner-Aktionen |
|---|---|
| /P:### |
Startet den Bildschirmschoner im Vorschaumodus. ### ist der Platzhalter für ein Fensterhandle (HWND), das
als Elternfenster verwendet werden soll. Der Bildschirmschoner wird innerhalb dieses Fensters ausgeführt. Mit dieser Option
kann man den Bildschirmschoner in jedem beliebigen Fenster von Windows anzeigen.
|
| /C:### | Öffnet den Konfigurationsdialog. Wenn der Platzhalter ### nicht vorhanden ist, wird
der Rückgabewert von GetForegroundWindow() als Dialog-Elternfenster verwendet.
Andernfalls wird der Inhalt des Platzhalters "###" als Dezimalwert interpretiert, der ein Fensterhandle repräsentiert,
welches als Elternfenster des Dialoges verwendet werden soll.
|
| /S | Startet den Bildschirmschoner im Vollbildmodus. Sobald Tastatur- bzw. Mausaktivität detektiert wird, wird der Bildschirmschoner beendet. |
Nach der Installation können die Einstellungen durch Rechtsklick auf den Windows-Desktop verändert werden. Die Installation erfolgt durch Verschieben der EXE-Datei in den Ordner windows/system32. Einen separaten Installer gibt es nicht. Der Konfigurationsdialog befindet sich in den Anzeigeoptionen (Rechtsklick auf den Desktop). Er erlaubt die Einstellung der unten beschriebenen Parameter.
Alle Änderungen der Parameter werden sofort im Vorschaufenster übernommen. Die folgende Liste gibt einen Überblick über die verfügbaren Parameter:
| Parameter | Beschreibung |
|---|---|
| Prey breed time | Anzahl der notwendigen Zeitschritte bevor sich ein Räuber fortpflanzen kann. |
| Energy per hunted prey | Diese Menge an Energie gewinnt der Räuber beim Fressen der Beute. Pro Zeitschritt verliert der Räuber einen Energiepunkt. Ist die Energie erschöpft, stirbt der Räuber. |
| Energy to create offspring | Minimalenergie, die erforderlich ist, damit ein Räuber sich fortpflanzen kann. Bei der Fortpflanzung wird die Energie zwischen Mutter und Kind geteilt. Ja genau, Fortpflanzung erfolgt durch Teilung, denn durch eine Laune der Natur gibt es auf Wator keine Väter. |
| Pixelsize | Die Größe eines Individuums in Pixeln. Je größer dieser Wert, desto besser die Performance der Simulation. |
C++ Quellcode für Visual Studio
Um die Software zu installieren, muss lediglich das hier zur Verfügung gestellte Installationsprogramm ausgeführt werden. Der Bildschirmschoner läuft auf den gängigen Windows-Versionen. Die Software wird kostenfrei zur Verfügung gestellt, Benutzung erfolgt auf eigene Gefahr.