Labyrinth Algorithmus (mutierend) Tipps?
Guten Tag,
ich habe mich mal an mutierende Algorithmen als Amateur Programmierer herangewagt. Mein erstes Projekt ist ein Algorithmus, welcher den effizientesten Weg durch ein Labyrinth finden soll (Ich weiß, dass A* besser ist).
Ich bin wie folgt vorgegangen:
- Labyrinth als zwei dimensionales Array (0 = Frei, 1 = Mauer)
- Start- und Endpunkt festgelegt
- STart Population erstellt aus zufälligen Pfaden (Ein Pfad ist ein Array, welches als Elemente 0,1,2 oder 3 enthalten, welche wiederum die Bewegungsrichtung vorgeben, die anschließend abgelaufen wird. Bspw. Hoch, hoch, links, rechts, runter.
- Dann score für jeden Agent aus Entfernung zum Ziel (Satz des Pythagoras) und Länge des Pfades gebastelt. Kürzere Entfernung gibt mehr Punkte, unnötiger Weg Abzug
- Danach werden für die 500 neuen agents jeweils zwei Eltern mit der Wahrscheinlichkeit basierend auf dem Score ausgewählt.
- Das „Kind“ wird aus den zwei Hälften der Pfade der Eltern erstellt, wobei jedes Element des neuen Pfades eine Chance hat zu mutieren (Hier sehe ich bedarf zur Verbesserung)
- Dies wiederholt sich solange ich will
Mein Problem ist, dass es bei kleinen Labyrinths den weg auch findet, aber die Wege noch teilweise sehr unnötig sind, obwohl ab dem Punkt, wo die meisten agents das Ziel erreichen, ja der längere weg rausselektiert werden sollte. Hatte überlegt auch minus punkte zugeben, wenn eine wand oder der Rand berührt wird, aber das hat nicht so funktioniert.
Mich würden eure Gedanken dazu interessieren und einfach ein paar Tipps zu der Thematik.
2 Antworten
Du brauchst auf jeden Fall einen Score, der den tatsächlichen Fortschritt bewertet. Satz vom Pythagoras hilft nicht, wenn du z.B. folgendes hast:
0 0 0
0 1 0
0 1 0
0 1 0
S 1 E
Bzw. es wird so viel Mutation nötig, dass es nichts weiter als Bruteforce wird.
Die "Fusion" von zwei Pfaden halte ich auch für sehr schwierig. Bist du dir sicher, dass das ein guter Anwendungsfall ist?
Ich habe noch einmal nachgedacht und würde als Score die Anzahl an Feldern nehmen, die exakt ein einziges Mal besucht werden. Sackgassen werden damit vernünftig bestraft, sobald sie schnell genug auftauchen und es wird keine explizite Kenntnis des Standortes des Ziels vorausgesetzt.
Wenn dann das Ziel erreicht wird, braucht es eine neue Metrik, um die Performance zu bewerten. Dann geht es nämlich darum, den kürzesten Weg zu erhalten.
wenn nur die Distanz zum Ziel berücksichtigst, dann kann auch ein scheinbar sehr guter Weg am Ende in eine Sackgasse enden.
Natürlich kann man das Labyrinth bruteforcen, aber das macht keinen Sinn für ein Algorithmus. Du solltest unwahrscheinliche Wege meiden.
Vielleicht ist doch der A* Algorithmus besser.
Mir geht es gar nicht darum einen optimalen Algorithmus zu entwickeln, sondern ein Projekt zum lernen und verstehen von mutierenden Algorithmen zu haben.
dann mach wie du es willst, es muss im Endeffekt einfach funktionieren
Genau hier sehe ich auch verbesserungsbedarf. Hier fehlt mir aber die Expertise. Evtl. könnte man einen Score basierend auf Ziel erreicht ja/nein und ob ein Hindernis getroffen wurde oder nicht einrichten. So würde das Ziel zwar langsamer gefunden, aber der Weg wird effizienter.
bzgl. Der Vererbung könnte man ja eigentlich auf eine Paarung verzichten, da die Pfade in sich selbst ja sxhlüssig sein müssen. Also nur eine Mutation.