Sonntag, 23. August 2009
Wieselauswahl - was kann die Selektion?
Eine wichtige Botschaft des Buches "der blinde Uhrmacher" von R. Dawkins besagt, dass natürliche Selektion in der Lage ist, neues herzustellen. Um dies zu demonstrieren, enthält das Buch u.a. zwei Programme, das Wieselprogramm und das Biomorphprogramm (die Links enthalten nicht das Originalprogramm, sondern Programme, die nach der Beschreibung im Buch geschrieben wurden).

Das Wieselprogramm "entwickelt" aus einer zufälligen Zeichenkette mithilfe von Mutationen und Selektion den Satz "Methinks it is like a weasel" aus einem Werk von Shakespeare. Die genaue Menge von Generationen hängt dabei von den einprogrammierten Parametern ab, wie z.B. Mutationsrate, Anzahl der Nachkommen etc.

Das Biomorph-Programm zeichnet mit Hilfe von "Genen" (einem Satz von Variablen) eine Strichzeichnung, die Dawkins als "Biomorph" bezeichnet. Aus einem Biomorph kann das Programm dann "Nachkommen" erzeugen, die mutiert sind, indem je ein Parameter etwas verändert wurde. Der Benutzer kann einen Nachkommen "selektieren", der dann weiter mutiert wird.

Dawkins zeigt, dass auf diese Weise innerhalb von 20 bis 30 Generationen aus einem sehr einfachen Vorfahren hochkomplexe Gebilde entstehen können (siehe S. 76f des Buches).

Natürlich können diese Programme nicht die Evolution in ihrer ganzen Komplexität nachformen. Dawkins will mit diesen Programmen stattdessen zeigen, dass Evolution kein Zufall ist, sondern von natürlicher Selektion "gesteuert" werden kann. Dawkins selbst nennt einige Vereinfachungen, die dafür sorgen, dass das Programm nicht realistisch ist. Allerdings äußert er sich meist nur kurz über die Folgen, die diese Punkte für seine Modelle haben.

Vereinfachungen in den Programmen

Folgende Vereinfachungen erwähnt Dawkins in seinem Buch (ich kann nicht garantieren, dass ich keine übersehen habe):

Wer das Wieselprogramm laufen lässt, merkt sehr schnell, dass das Programm immer einen vorgegebenen Satz erzeugt. Dieses Verfahren ist natürlich sehr einfach zu programmieren, hat aber mit natürlicher Selektion nichts zu tun. Diese kann definitionsgemäß nie im Hinblick auf ein anzustrebendes Ziel arbeiten. Diese Form der Selektion entspricht mehr einer automatisierten Form von künstlicher Selektion, bei der ein Züchter ein bestimmtes Merkmal erzeugen oder verstärken will.

Beim Biomorph-programm ist die Selektion gar nicht im Programm enthalten, sondern wird vom Benutzer vorgenommen. Hierbei spielt einzig die Frage eine Rolle, was dem Benutzer gefällt.

Es gibt beim Wieselprogramm auch keine Unterscheidung in Gene und Phänotyp. Mutation und Selektion greifen direkt an der Zeichenkette an. Im Gegensatz dazu findet bei Lebewesen die Mutation in den Genen statt, während die Selektion am Organismus stattfindet.

Dawkins erwähnt auch noch die unrealistisch hohe Mutationsrate, die aber damit begründet ist, dass wir nicht Millionen von Jahren warten wollen, bevor sich auf dem Computerbildschirm etwas verändert.

Ist natürliche Selektion der Züchtung ähnlich?

Zum ersten haben mir diese Programme vor Augen geführt, dass natürliche Selektion und Züchtung zwei vollkommen verschiedene Paare Schuhe sein müssen. Zwar ist es möglich, Organismen durch Züchtung zu verändern, und desgleichen kann unter geeigneten Umständen natürliche Selektion auch Organismen verändern, aber die Mechanismen sind verschiedenartig.

Dies wird deutlich, wenn man versucht, beide Verfahren zu programmieren. Züchtung kann in wenigen Programmzeilen automatisiert werden, während natürliche Selektion um viele Größenordnung schwerer zu simulieren ist.

Wenn wir uns in der Natur umsehen, dann wird auch offensichtlich, dass die Ergebnisse von Züchtungen meist kaum ohne menschlichen Schutz überlebensfähig sind, während Wildformen,, die der natürlichen Selektion unterliegen, wesentlich besser in der Natur zurechtkommen.

Dies sagt mir, dass die Verfahren unterschiedlich sind und auch das Ergbenis anders aussieht, wenn man natürliche Selektion und Züchtung vergleicht.

der Genraum

Das biomorphprogramm kann mit neun Genen ca. eine halbe Billion(!) verschiedener Formen erzeugen. Allerdings werden alle Formen nach dem gleichen Bauplan erzeugt, der bereits vom Programm vorgegeben ist. Anders gesagt: die möglichen Variationen sind vom Programm begrenzt. Es kann außerhalb dieser vorgegebenen Variationsbreite keine Neuerungen geben. Wenn man andere Formen erzeugen will, muss man das Programm umschreiben.

Im Gegensatz dazu geht die Evolutionstheorie natürlich davon aus, dass das Leben mit einem äußerst einfachen Organismus angefangen hat, dessen Nachkommen allmählich an Komplexität zunahmen.

Man kann dies als Analogon des Unterschied zwischen Mikroevolution und Makroevolution sehen. Mikroevolution wäre hierbei analog zu den vom Programm zugelassenen Änderungen, während Makroevolution ein umschreiben des Programmes selbst erfordert. Es ist klar, dass diese beiden Vorgänge im Computer vollkommen verschieden sind. Die Veränderung von Programmparametern ist etwas anderes als das Schreiben neuer Programmfunktionen.

Niemand kommt auf die Idee, dass man durch das ändern von Parametern im Programm neue Funktionen erzeugen kann, die vorher nicht da waren. Wenn es allerdings um die Evolution von Organismen geht, dann gibt es erstaunlicherweise diesen Unterschied nicht mehr.

Wenn das wirklich so wäre, dann wäre natürlich ein Computerprogramm ohnehin nicht geeignet, als Modell für die Evolution zu dienen. Dies bringt mich zu dem nächsten Punkt:

Evolution und Syntax

Jedes Computerprogramm ist in einer Syntax geschrieben, die vorschreibt, was genau wo im Programm stehen darf. Dabei gibt es Stellen, die nie verändert werden dürfen, da ansonsten das Programm nicht funktioniert(z.B. in einem C-Programm die main-Funktion), während andere beinahe beliebig verändert werden können (z.B. Zeichenketten).

Nach meinem Wissen gibt es Anzeichen, dass auch Gene einem vergleichbaren Mechanismus unterliegen. Eine Gene können sich (fast) nicht verändern, ohne ihre Funktion zu verlieren, während andere eine sehr große Variationsmöglichkeit haben. Dies ist ein Hinweis darauf, dass auch Gene einer Art "Syntax" unterliegen, die festlegt, was geändert werden kann und was nicht. Dies wird dadurch erreicht, dass außerhalb der Syntax mutierte Organismen einfach nicht lebensfähig sind, d.h. eine befruchtete Eizelle mit einer entsprechenden Mutation entwickelt sich gar nicht oder nur wenige Schritte, bevor sie abstirbt.

Dies führt aber zu einem Problem: eine Syntax verhindert, dass Mutations- und Selektionsschritte beliebig klein werden können. Dieses Prinzip wird insbesondere im Wiesel-Programm verletzt. Erst der letzte Programmschritt erzeugt einen syntaktisch korrekten Satz. Alle vorhergehenden Schritte wären eigentlich als Sätze nicht "lebensfähig".

Dieses Problem wird in dem Buch meiner Meinung ausgeklammert. Es wird zwar daraf verwiesen, dass es wesentlich mehr Möglichkeiten gibt [genetisch] tot zu sein als lebendig, aber über die Ursachen wird nichts interessantes gesagt.

"Hallo Welt!" - Selektion

Man kann diesen Punkt heutzutage relativ einfach ma eigenen Computer simulieren, wenn man (wie ich) einen kleinen Bruder mit Programmierkenntnissen hat. Sein Programm mutierte den C++ -Quelltext des "Hallo Welt!"-Programms, versucht das mutierte Programm zu kompilieren und stuft es als "lebensfähig" ein, wenn es sich kompilieren lässt; am Ende zeigt es die Ergebnisse von vielen (zehntausenden bis hunderttausenden) Durchläufen an.

Es ist wenig erstaunlich, dass der grösste Teil der mutierten Programme die Kompilierung nicht überlebte, da die Syntax nicht mehr passte. Die restlichen Programme (nach mehrstündigem Durchlauf immer noch einige zehntausend) enthielten im wesentlichen Verstümmelungen des ausgegebenen Textes (z.B. "Ha2 re'$§%lt!" oder sinngemäß). Dies könnte man als analog zu einer schwach negativen Mutation ansehen.

Dann gab es auch noch neutrale Mutationen wie die Veränderung von Variablennamen, die nur einmal im Programmtext vorkommen; mehrfach vorkommende konnen so gut wie nicht geändert werden. Außerdem sammelten sich sinnlose Zeichenketten an Stellen, die nicht der Syntaxprüfung unterliegen (d.h. nach der "include"-Anweisung), die aber keinerlei Einfluss auf die Programmausführung haben.

Die Änderungen am eigentlichen Programmcode waren selten und dann auch meist Verlustmutationen, die bewirkten, dass das Programm nichts mehr ausgibt. So wurde z.B. in die Ausgabeanweisung an der entscheidenden Stelle ein "nicht"-Operator eingefügt, der dafür sorgte, dass die Zeichenkette nicht ausgegeben wurde. Mehrmals wurde die Ausgabeanweisung "std::cout" durch eine Sprungmarke ersetzt ("std:") oder ganz gelöscht. Das Ergebnis ist auch hier jeweils ein Programm ohne Ausgabe.

Es gab ein paar ganz wenige Mutationen, die zusätzliche syntaktische Elemente einfügte; normalerwese war dies einfach die leere Anweisung ";" die gar nichts macht. In einem einzigen Fall kam die Zeile "int z;" hinzu, die eine neue Variable definiert ohne irgend einen Einfluss auf den Programmablauf zu haben.

Die Zeile "int z;" kann theoretisch in zwei Schritten entstehen: zuerst muss eine leere Anweisung ";" an einer sinnvolle Stelle eingefügt werden, dann muss direkt davor der Text "int z" eingefügt werden. Ein C++ - Programm kann ca. 75 verschiedene Zeichen enthalten. Die leere Anweisung hat damit eine Wahrscheinlichkeit von 1,3 x 10-2. Diese muss natürlich an einer passenden Stelle eingefügt werden, was die
Wahrscheinlichkeit nochmal ca. um den Faktor 10 reduziert. Wenn aber die Anweisung erst einmal da ist, bleibt sie meist stabil im Programm bestehen, da der Compiler auch für Code, der nichts tut, syntaktische Korrektheit erzwingt. Bei Genen wäre das wahrscheinlich anders.

In der Zeichenfolge "int z" ist der Variablenname (fast) beliebig, so dass wir vereinfacht vier Zeichen in der richtigen Reihenfolge an der richtigen Stelle benötigen, die einmal in einem ca. 70 Zeichen langen Programm auftaucht. Das ergibt: 1 / (754 x 70) = 4,5-10, sprich schon ein sehr unwahrscheinliches Ereignis für eine vollkommen triviale Anweisung, eins zu 2,2 Milliarden. Dies ist der einzige Weg, um Anweisungen zu erzeugen, die noch gar nicht vorkommen.

Für andere triviale Anweisungen liegen die Verhältnisse meist noch extremer, da jeder erforderliche Buchstabe die Wahrscheinlichkeit um fast zwei Zehnerpotenzen verringert, dass eine derartige Anweisung neu entsteht. Die Dinge liegen natürlich etwas einfacher, wenn ein bereits vorhandener Programmteil durch eine Mutation verdoppelt wird. In diesem Fall hätte z.B. das erste Argument aus der "main"-Funktion verdoppelt werden können. Hier liegt der "Trick" dann nur darin, die richtigen Stellen zum Kopieren und einfügen zu finden. Die Wahrscheinlichkeit liegt hier natürlich höher, nach meiner Schätzung ca. bei 10-4, so dass man hin und wieder mit einem derartigen Ereignis rechnen kann. Voraussetzung dafür ist natürlich, dass die Anweisung bereits irgendwo im Programm vorhanden ist.

Auch mein Programm kann natürlich nicht den gesamten Ablauf der Evolution nachspielen, es zeigt aber, dass Syntax die Möglichkeiten, Veränderungen in kleinen Schritten zu betreiben, extrem einschränkt, so dass bereits triviale Veränderungen bereit extrem unwahrscheinlich werden.

An dieser Stelle will ich noch darauf hinweisen, dass bei der obigen Rechnung lediglich die Entstehung einer Anweisung behandelt. Die Anweisung hat aber keinen Sinn für das Programm, kann also auch nicht "selektiert" werden. Der einzige Mechanismus, der verhindert, dass die Zeile wieder aus dem Programm verschwindet, besteht darin, dass der Compiler eine syntaktisch korrekte Programmzeile fordert. Daher kann nur die gesamte Zeile gelöscht werden, was wiederum ein relativ unwahrscheinliches Ereignis ist. In einem Organismus würde natürlich so ein stabilisierender Einfluss entfallen.

Die Frage, die für mich daraus folgt, lautet: "Gibt es in den Genen etwas, was einer Syntax entspricht?" Wenn ja, dann ist die Theorie der kleinen Veränderungen sehr viel weniger glaubwürdig, da Veränderungen dann eine nicht triviale Mindestgröße haben müssen, damit sie überhaupt zulässig sind.

Design oder designähnlich?

Damit eine Veränderung in einem (trivialen) Programm einen positiven Effekt haben kann, muss sie in den Gesamtablauf des Programms integriert sein. Es reicht nicht einfach eine syntaktisch korrekte Zeile einzufügen. Wenn die Anweisung im Rahmen des Programms keinen "Sinn" hat, dann bewirkt sie keine Verbesserung.

Hier habe ich das Wort "Sinn" benutzt, dass in der Evolutionsdebatte nicht gern gehört wird. Aber im Rahmen eines Programms ist der Begriff ohne weiteres benutzbar und sinnvoll. Aber jede noch so triviale Anweisung eines Computerprogramms ist nur dann nützlich für den Programmablauf, wenn sie zu einem umfassenden Ziel des Programmes oder Programmabschnitts beiträgt.

In einem Organismus gibt es das Ziel des Überlebens und der Vermehrung. Jeder Teil des Organismus (und damit auch der Gene) trägt hierzu bei. Proteine (und daraus aufgebaute Merkmale), die keinen Beitrag zum Überleben leisten, werden nicht selektiert und "zerfallen" somit durch Mutationen; ein beliebtes Beispiel hierfür sind die verschwundenen Augen der Höhlenfische.

Eine grundlegende These der Evolutionstheorie lautet, dass diese Merkmale "designähnlich" sind, d.h. sie sehen zwar aus wie designt, sind aber in Wirklichkeit durch Mutation und Selektion entstanden.

Um die Frage zu klären, ob die Komplexitiät des Lebens durch Evolution oder Design entstanden ist, wäre es erforderlich, ein Kriterium zu benennen, mit dem man Design von designähnlicher Selektion unterscheiden kann. Diese Aufgabe ist sicher nicht einfach.

Nach meiner Erfahrung wird diese Frage von den meisten Evolutionisten nicht gestellt oder als nicht wesentlich angesehen. Sie meinen, die Frage nach Design oder Evolution wäre bereits auf einer anderen Ebene entschieden.


...957 x aufgerufen