Wa-Tor: Ein Räuber-Beute Modell

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 Wa-Tor (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 Leben im Überfluss hin und her gerissen sind.

Wa-Tor Simulation in Aktion. In der unteren Bildhälfte sind die charakteristischen Kurven einer Räuber-Beute-Simulation zu erkennen.

Die Simulation kann in Form eines Bildschirmschoners heruntergeladen werden. Der Bildschirmschoner 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 2013 kompiliert werden.

Simulationsregeln

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 wird tritt es auf der gegenüberliegenden Seite wieder ein. Beutefische und Haie bewegen sich in jedem Zeitschritt (wenn möglich) und interagieren gemäß den im Folgenden beschriebenen Regeln.

Regeln für Beutefische

Rules for fish

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:
  • Fische bewegen sich orthogonal auf zufällig ausgewählte freie Nachbarfelder
  • Fische werden niemals freiwillig in eine von einem Hai besetzte Zelle schwimmen
  • Bei erreichen der "breed_time" werden Nachkommen in einem zufällig ausgewählten freiem Nachbarfeld erzeugt.

Regeln für Haie

Rules for sharks

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ück gesetzt.

Zusammenfassung der Regeln für die Bewegung der Räuber (Haie):
  • Haie bewegen sich orthogonal auf zufällig ausgewählte Nachbarfelder, die entweder leer oder von Beutefischen besetzt sind.
  • Ist in der Nachbarzelle, in die der Räuber sich bewegt ein Fisch, so wird dieser gefressen und die Energie des Räubers erhöht sich um einen fest vorgegebenen Betrag.
  • Ist genügend Energie vorhanden, so werden in einem freien Nachbarfeld Nachkommen erzeugt.
  • Mit jedem Zeitschritt verliert der Räuber einen fest vorgegebenen, kleinen Energiebetrag.
  • Fällt die Energie des Räubers auf Null, so stirbt der er.

Modifikationen am Originalalgorithmus

Um die Berechnungsleistung zu erhöhen wurden einige Modifikationen 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. 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 senkt 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.

Die Lottka-Volterra Gleichungen

Solution of the Lotka-Volterra equation 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.

\begin{equation} \frac{dx}{dt} = x(\alpha - \beta y), \\ \frac{dy}{dt} = -y(\gamma - \delta x), \end{equation}
wobei:
  • y die Anzahl der Räuber ist (Haie)
  • x die Anzahl der Beute ist (Beutefische)
  • t steht für die Zeit
  • \(\alpha, \beta, \gamma\) und \(\delta\) sind Parameter, welche die Interkation zwischen den beiden Spezies beschreiben.

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, das 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].

Wator als Bildschirmschoner

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 Kommandozeilenparameters 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 Platzhalter "###" 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 werden wird der Bildschirmschoner beendet.

Installation und Konfiguration

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 unter beschriebenen Parameter.

Wator config window

Simulationsparameter

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 bei 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. Um so größer dieser Wert je besser die Performance der Simulation.

Download

Download Wator-Screensaver

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 allen WIndows Versionen ab Windows 7. Die Software wird kostenfrei zur Verfügung gestellt, Benutzung erfolgt auf eigene Gefahr.

Quellenverzeichnis

  1. A.K. Dewdney: "Computer Recreations; Sharks and Fish wage an ecological war on the toroidal planet of Wa-Tor" Scientific American. pp. I4—22.
  2. Rachel Grey: "Writing an OpenGL screensaver for Windows" online, 2002
  3. Wikipedia: "Lotka-Volterra-Gleichungen" The Free Encyclopedia. Wikimedia Foundation, Inc., 2014, Online; Stand 7. Februar 2015