Auf die gleiche Art und Weise kann nun jedes beliebige Individuum codiert werden. Es ist dabei übrigens nicht notwendig, dass die Eigenschaften eines Individuums zwingend aus einzelnen Zahlen bestehen, die dual codiert und dann aneinandergereiht werden. Die Codierung in eine Bitkette kann beliebig aussehen; es muss lediglich möglich sein, aus dieser Bitkette – dem Genotyp – das eigentliche Individuum – den Phänotyp – wiederherstellen zu können. Für diese Wiederherstellung wird eine Funktion g definiert, welche eine Bitkette auf das zugehörige Individuum abbildet. Für obiges Beispiel würde das etwa bedeuten, dass
g(11000111) = (12,7)
ist. Wie die Abbildung genau funktioniert, liegt dabei allein im Ermessen des Programmierers und kann praktisch beliebig umgesetzt werden. Zudem muss natürlich festgelegt werden, ob die Bitkette eine feste Länge haben soll (wie in unserem Beispiel mit 8 Bit) oder ob sie variabel sein kann; das hängt aber wie immer vom konkreten Problem ab. Übrigens muss man sich natürlich nicht auf Bitketten beschränken – jedes beliebige Wertesystem kann die Grundlage für die Informationskette bilden. Häufig verwendete Systeme sind eben das duale System, das Dezimalsystem mit nur natürlichen oder ganzen Zahlen oder auch das Dezimalsystem mit reellen Zahlen.
Wo liegt nun aber der eigentliche Vorteil darin, ein Individuum als Wertkette zu codieren und nicht den Phänotyp direkt für Mutation und Rekombination zu benutzen? Genau wie in der Natur alle Lebewesen auf der DNA basieren und Mutation sowie Rekombination den gleichen Prinzipien folgen – sei es ein Fisch, ein Insekt, eine Pflanze, ein Mensch oder ein anderes Tier -, können die gleichen Techniken bei der Mutation und Rekombination von Wertketten in einem evolutionären Algorithmus angewendet werden, unabhängig davon, wie das codierte Individuum aussieht. Man sagt, dass die Mutation und Rekombination auf dem Genotyp der Individuen stattfinden.
Die möglichen Mutationen hängen nun nicht mehr von den Eigenschaften des Individuums ab, sondern nur noch von den Operationen, die auf Wertketten – dem Genom – stattfinden können. Die einfachste Operation ist hier sicherlich auf Bitketten möglich: die Invertierung einer einzelnen, zufällig gewählten Position im Genom – aus einer 0 wird eine 1 oder umgekehrt – bewirkt die kleinstmögliche Änderung an einem derart codierten Individuum. Etwas umfangreichere Mutationen können mehrere Stellen im Genom oder ganze Abschnitte invertieren, bis hin zur gesamten Bitkette (wobei über die Sinnhaftigkeit einer solchen Makro-Mutation natürlich gestritten werden kann). Besteht das Genom nicht aus binären, sondern etwa aus natürlichen, ganzen oder reellen Zahlen, so können die einzelnen Positionen zwar nicht invertiert, so doch aber auf verschiedene andere Arten modifiziert werden. Denkbar ist hier alles, was man einer Zahl so antun kann; man kann Werte hinzuaddieren oder abziehen, man kann sie mit einem Faktor multiplizieren oder man kann dividieren, man kann sie auf einen Höchst- oder Mindestwert setzen und so weiter. Unabhängig von der dem Genom zugrundeliegenden Zahlenbasis kann man auch Abschnitte des Genoms austauschen oder – bei variabler Genomlänge – Abschnitte löschen oder zufällige neue Abschnitte hinzufügen. Ein kleines Beispiel hierzu; nehmen wir dazu unser obiges Beispielindividuum 11000111, welches die Position (12,7) codiert. Wenden wir verschiedene Mutationen darauf an, so können sich etwa die folgenden Individuen ergeben:
11000111 -> 11010111 = (13,7)
Invertierung von zwei Bitpositionen (4 und 7):
11000111 -> 11010101 = (13,5)
Vertauschung zweier Genomabschnitte ([2,3] mit [5,6]):
11000111 -> 10111011 = (11,11)
Auch bei der Rekombination kann die einheitliche Darstellung des Genoms ausgenutzt werden. Ein typischer Rekombinationsvorgang eines evolutionären Algorithmus sieht so aus, dass die Genome zweier (oder mehrerer) Elternindividuen hergenommen, geteilt und zu (meist zwei) neuen Individuen zusammengesetzt werden. Die Teilung kann nach verschiedenen Verfahren erfolgen. Häufige Verwendung findet hier der 1-Punkt-Crossover, bei welchem die beiden Genome der Eltern an der gleichen Stelle geteilt und die beiden Teile jeweils untereinander vertauscht werden. Analog kann natürlich auch ein 2-Punkt-Crossover mit 2 Teilungspunkten oder ein beliebiger n-Punkt-Crossover verwendet werden. Darf die Länge des Genoms variieren, können die Teilungspunkte für den Crossover auch an unterschiedlichen Stellen innerhalb der Genome der Eltern liegen, so dass die Genomlänge der Kinder von der der Eltern abweicht. Da die Teilungspunkte in den Genomen natürlich nicht zwingend an den Stellen liegen müssen, welche bestimmte Eigenschaften des Individuums codieren (sofern überhaupt eine direkte Abbildung von Genomabschnitten auf Eigenschaften vorhanden ist), können bereits bei der Rekombination neue Eigenschaften entstehen, wodurch die Variabilität der Individuen in der Nachfolgegeneration erhöht wird (ein oft begrüßenswerter Umstand bei der Anwendung evolutionärer Algorithmen; warum, sehen wir im nächsten Artikel). Zur Demonstration noch 3 kleine Bilder (übernommen aus der Wikipedia); die beiden Farben repräsentieren jeweils die Genom(abschnitt)e der beiden Elternteile:
Kommentare (11)