Ein kurzes Beispiel für die genetische Evolution in JavaScript: Machen wir ein Baby.

"Der Prozess der Mutation ist die einzige bekannte Quelle für die neuen Materialien der genetischen Variabilität und damit der Evolution." - Dobzhansky, 1957.

Genetische Evolutionsalgorithmen faszinieren mich wirklich. Die Fähigkeit, virtuelle DNA zu programmieren, ist nur eine phänomenale Leistung der Informatik. Die Fähigkeit, Darwins Evolutionstheorie in Code zu schreiben und tatsächlich ein Survival of the Fittest-Modell in Aktion zu sehen, ist einfach erstaunlich.

Ich habe genetische Algorithmen noch nie wirklich angesprochen und beschlossen, dass es Zeit war, mit dem ich anfing. Und welchen besseren Ort gibt es als den eigentlichen, richtig? In diesem Tutorial werde ich einen "Stick" erstellen, und dieser Stick möchte einen "Kreis" erreichen. Schliessen Sie daraus, was Sie wollen, aber ich schreibe familienfreundliche Tutorials und es wird so bleiben.

Ich nehme unglaublich starken Einfluss von The Coding Train: Coding Challenge # 29 als Inspiration dafür. Link dazu hier. Er wurde von Smart Rockets inspiriert. Obwohl ich nichts Neues oder Originelles mache, hoffe ich, dass es als Beispiel für einen genetischen Evolutionsalgorithmus dient. Ich verwende die P5.JS-Bibliothek, die ich als visuelle JavaScript-Bibliothek zusammenfassen würde.

Bevor ich einen genetischen Algorithmus erstellen kann, muss ich zuerst die tatsächliche Einstellung vornehmen. Zuerst erstelle ich eine sehr einfache HTML-Seite.

Ich habe zwei Bibliotheken für P5. Main kümmert sich um das Zeichnen auf dem Bildschirm, die Instanziierung von Variablen usw. Ein Stick ist die Linie, die sich entwickeln wird, eine Population ist eine Sammlung von Sticks, und DNA ist das, was ich als Kern des genetischen Algorithmus betrachten würde. Werfen wir einen Blick auf den Code für Stick:

Ein Stick hat also einige grundlegende Funktionen. Es muss sich bewegen können, damit es einen Bewegungsmotor (aus Mangel an einem besseren Begriff) in den Geschwindigkeits-, Beschleunigungs- und Positionsvariablen hat. Im Moment wird jede Bewegung durch die mysteriöse DNA-Funktion gesteuert. Bevor wir zur DNA kommen, werfen wir einen Blick auf die Bevölkerung:

Die Bevölkerung ist wirklich nicht so interessant. Es werden 25 Sticks erstellt, von denen ich glaube, dass sie für eine Population ausreichen, und sie werden dann auf dem Bildschirm verschoben. Mit dieser Funktion keine Barrieren überwinden! DNA:

Zu diesem Zeitpunkt macht DNA im Grunde nichts. Ein Stick erhält eine DNA, und eine DNA enthält 200 Gene. Dies entspricht der Lebensdauer meines kleinen Sticks. Keine Sorge, zu gegebener Zeit werden weitere hinzugefügt. Die Hauptdatei:

Main macht hier also ein paar Dinge. Zuerst müssen wir eine neue Generation von Stöcken erstellen, die eine Instanziierung der Bevölkerung darstellt, und dann erstellen wir unseren Kreis, auf den die Stöcke später abzielen werden. Dann zeichnen wir alles auf den Bildschirm, mit der zusätzlichen Fähigkeit, jedes Mal, wenn ihr Lebenszyklus endet, eine neue Generation zu töten und zu erschaffen.

Wenn wir dies also so ausführen, wie es derzeit ist, erhalten wir Folgendes:

Die verwirrten kleinen Stöcke

Derzeit ist es überhaupt kein genetischer Algorithmus. Stattdessen handelt es sich um eine Reihe von Sticks, die sich mit zufällig ausgewählten Vektoren bewegen, wobei ein Punkt auf dem Bildschirm gezeichnet wird. Fügen wir also den genetischen Teil hinzu.

Wir wollen also, dass der Stock, der ihn am weitesten und am nächsten zum Kreis macht, der Stock ist, der seine Gene an seine Kinder weitergibt. Dies ist im Grunde das Überleben der Stärksten: Wer am längsten überlebt, ist derjenige, der seine Gene weitergibt.

Wir können also damit beginnen, dies umzusetzen, indem wir jedem Stick eine neue Variable geben: Fitness.

var fitness = 0

Die Fitness wird anhand der aktuellen Position des Schlägers relativ zur Position des Kreises (Ziels) berechnet. Wir können dies als Funktion implementieren, um Zeugen auf jedem Stick zu berechnen.

this.calculateFitness = function () {
var distance = dist (this.pos.x, this.pos.y, target.x, target.y)
this.fitness = 1 / Entfernung
}}

Jetzt haben wir Stöcke mit einer Fitnessbewertung - dh sie haben bessere Gene, weil sie länger überlebt haben. Jetzt brauchen wir also einen Weg, um diese Sticks mit erstklassigen Genen reproduzieren zu können. Betreten Sie den Pool:

Dieser Pool ist also relativ einfach im Konzept. Wir haben bereits oben herausgefunden, dass die erfolgreichsten Gene diejenigen sind, die dem Kreis am nächsten sind. Je näher der Stab ist, desto öfter wird sein Genom in den Pool gelangen und desto wahrscheinlicher ist es, dass es sich vermehrt. Ein Stick, der es zu 5% geschafft hat, hat eine Chance von 5%, sich zu reproduzieren, während ein Stick, der es zu 70% geschafft hat, eine Chance von 70% hat, sich zu reproduzieren. Ich hoffe, ich habe das gut genug erklärt. Erfolgreicherer Stock = bessere Chance, als Teil eines neuen Stocks wiedergeboren zu werden.

Das Obige sind zwei neue Funktionen. Die Auswahl ist, wie der Name andeutet, die Auswahl der Elterngene aus dem Genpool. Diese Gene werden dann kombiniert, um im Crossover eine neue DNA zu bilden, die wiederum dem neuen Stick zugewiesen wird! Das ist so ziemlich alles, da wir dies relativ einfach und rudimentär halten wollen.

Ziemlich cool, unsere Stöcke können jetzt die besten Fähigkeiten der Vorgänger nutzen und sie verwenden, um den Kreis zu finden! Wenn wir es jetzt in Aktion betrachten:

Die immer noch verwirrten, aber etwas schlaueren Stöcke.

Nach mehreren Dutzend Iterationen sieht es so aus, als wären sie abgestorben, da nur wenige Linien sichtbar sind. Dies ist jedoch nicht der Fall: Je leichter der Stick, desto mehr Sticks folgen genau demselben Pfad. Dies ist zu erwarten, da wir einen relativ begrenzten Pool an Genen haben.

Die sehr intelligenten Alpha-Sticks.

Je länger es läuft, desto mehr erscheint nur ein Stick auf dem Bildschirm. Dieser Stick repräsentiert den optimalen Stick! Der gewählte Stock. Hier sind sie, der Höhepunkt unseres genetischen Algorithmus:

Genius Stick (s)!

Das ist also ein genetischer Evolutionsalgorithmus, der vollständig im Browser geschrieben wurde! Es ist zwar kein perfektes Beispiel für die genetische Evolution, aber es ist ein gutes Beispiel dafür bei der Arbeit. Unser kleiner Stock kann jetzt den Kreis bilden und was als nächstes folgt, ist für heute kein Thema.

Wie eingangs erwähnt, wird dies stark von The Coding Train beeinflusst. Link zu ihrem Repo.

Mein vollständiger Code.