Dies ist ein Beispiel dafür, was ich per Code tun möchte. Ich weiß, dass Sie die Sprungpunktsuche verwenden können, um problemlos vom grünen Knoten zum roten Knoten oder sogar zu A * zu gelangen. Aber wie rechnet man das mit Warps?
Im Bild können Sie sehen, dass es nur 8 Züge dauert, um vom grünen zum roten Knoten zu gelangen, wenn Sie den blauen Pfad nehmen. Der blaue Pfad verschiebt Ihre Position sofort von einem lila Knoten zum nächsten. Das Feld in der Mitte, das 2 Züge kostet, ist ein Punkt zwischen zwei Warpzonen, zu dem Sie sich bewegen müssen, um zu gelangen.
Es ist deutlich schneller, den blauen Pfad einzuschlagen, da Sie nur die Hälfte (ungefähr) bis zum gelben Pfad zurücklegen müssen. Wie mache ich das programmgesteuert?
Um dieses Problem zu lösen, nehmen wir an, dass das Diagramm mehrere violette "Verzerrungen" enthält, die Sie verwenden können, UND wir wissen genau, wohin sich die einzelnen violetten Punkte verzerren und wo sie sich im Diagramm befinden.
Einige violette Verzerrungen sind bidirektional und andere nicht, was bedeutet, dass Sie eine Verzerrung manchmal nur von einer Seite eingeben können, nach dem Verzerren jedoch nicht zurück.
Ich habe über die Lösung nachgedacht und bin nur zu dem Schluss gekommen, dass ich das Problem berechnen kann, indem ich den Abstand zu jedem Warp-Punkt (abzüglich der unidirektionalen Punkte) und den Unterschied zwischen diesen Punkten und den nahegelegenen Punkten überprüfe .
Das Programm müsste irgendwie herausfinden, dass es vorteilhafter ist, den zweiten Warp auszuführen, anstatt vom ersten Sprung zu laufen. Anstatt also 6 Punkte zu bewegen, dann zu verziehen und dann die restlichen 8 Schritte zu Fuß zu bewegen (was auch schneller ist, als überhaupt keine Verzerrungen zu verwenden), würden die 6 Züge und dann die beiden Züge zur zweiten Verzerrung führen.
EDIT: Ich habe festgestellt, dass der blaue Pfad tatsächlich 12 statt 8 Züge benötigt, aber die Frage bleibt dieselbe.
quelle
Antworten:
Die meisten Pfadsuchalgorithmen werden in Form von Diagrammen und nicht in Form von Gittern definiert. In einem Graphen ist eine Verbindung zwischen zwei ansonsten entfernten Knoten nicht wirklich ein Problem.
Sie müssen jedoch auf Ihre Heuristiken achten. Bei Wurmlöchern entspricht der Mindestabstand zwischen zwei Knoten nicht mehr dem euklidischen Abstand und der Abstand entspricht nicht mehr der Dreiecksungleichung. Solche Heuristiken sind für A * unzulässig. Sie können daher A * nicht einfach verwenden.
Natürlich funktionieren auch Pfadfindungsalgorithmen wie Dijkstra, die keine Heuristik verwenden. Dies ist eher eine Breitensuche und wählt Ihre Wurmlöcher ohne zusätzlichen Aufwand aus. Dijkstra wird jedoch mehr Knoten als A * mit einer guten Heuristik besuchen. (Dijkstra entspricht A * mit
heuristic(x) = 0
.)Ich denke, A * wird funktionieren, wenn Sie eine Heuristik verwenden, die alle ausgehenden Wurmlöcher als Wurmloch direkt zum Ziel behandelt: Die Heuristik kann die Entfernung unterschätzen, darf sie jedoch niemals überschätzen. Dh die Heuristik wäre:
Für eine sehr genaue Heuristik können Sie (rekursiv) den Abstand vom Endpunkt des Wurmlochs zum Ziel oder zum nächsten Wurmloch hinzufügen. Dh als Vorberechnung können Sie die Wegfindung auf dem (vollständig verbundenen) Teilgraphen durchführen, der alle Wurmlöcher und das Ziel enthält, wobei der Abstand zwischen zwei Knoten der euklidische Abstand ist. Dies kann von Vorteil sein, wenn die Anzahl der Wurmlöcher weit unter der Anzahl der erreichbaren Zellen in Ihrem Raster liegt. Die neue Heuristik wäre:
Wie @Caleth in den Kommentaren ausführt, ist dies alles sehr gut einstellbar und wir können die Heuristik des ersten Wurmlochs verbessern, ohne einen vollständigen Weg durch das Wurmlochnetz zu finden, indem wir den Abstand zwischen dem letzten Wurmlochausgang und dem Ziel addieren. Da wir nicht wissen, welcher Wurmloch-Ausgang zuletzt verwendet wird und wir nicht überschätzen dürfen, müssen wir den Ausgang annehmen, der dem Ziel am nächsten liegt:
quelle
dijkstra_heuristic(x) = 0
wormhole_path_distance
als die Subgraphen-Suche und weniger unterschätzt als die "Alle Ausgänge sind auf dem Ziel".Sie haben ein Diagramm mit 6 Eckpunkten in einem Gitter mit Koordinaten:
Sie können ein vollständiges Diagramm für diese Eckpunkte erstellen und jeder Kante Kosten zuweisen, wobei die Kosten
MAX( ABS( x1 - x2 ), ABS( y1 - y2 ) )
für Standardkanten und die Kosten für Wurmlöcher 0 betragen.Dies gibt Ihnen die Kosten (als Adjazenzmatrix):
Wenn es einseitige Verzerrungen gibt, erstellen Sie nur Kanten in der Grafik (oder der Adjazenzmatrix), die in diese Richtung verlaufen, jedoch nicht in die entgegengesetzte Richtung.
Sie können dann den Dijkstra-Algorithmus mit einer Prioritätswarteschlange verwenden .
Beginnen Sie mit
A
und verschieben Sie jede benachbarte Kante in die Prioritätswarteschlange:Format: (Pfad: Kosten)
Wenn die Elemente in die Warteschlange verschoben werden, behalten Sie die Mindestkosten für jeden Scheitelpunkt im Auge und verschieben Sie Pfade nur dann in die Warteschlange, wenn die Kosten niedriger sind als die vorhandenen Mindestkosten.
Entfernen Sie das erste Element aus der Warteschlange, und verschieben Sie alle zusammengesetzten Pfade, die von diesem Pfad und den angrenzenden Kanten gebildet werden, in die Prioritätswarteschlange zurück, wenn die zusammengesetzten Pfade niedrigere Kosten als das vorhandene Minimum haben.
Löschen:
(A-B : 7)
(A-B-A : 14)
- als höhere Kosten abzulehnen(A-B-C : 7)
- als gleiche Kosten abzulehnen(A-B-D : 13)
- als höhere Kosten abzulehnen(A-B-E : 19)
- als höhere Kosten abzulehnen(A-B-F : 19)
- als höhere Kosten abzulehnenLöschen
(A-C : 7)
(A-C-A : 14)
- als höhere Kosten abzulehnen(A-C-B : 7)
- als gleiche Kosten abzulehnen(A-C-D : 10)
- als gleiche Kosten abzulehnen(A-C-E : 16)
- als gleiche Kosten abzulehnen(A-C-F : 16)
- als gleiche Kosten abzulehnenLöschen
(A-D : 10)
(A-D-A : 20)
- als höhere Kosten abzulehnen(A-D-B : 16)
- als höhere Kosten abzulehnen(A-D-C : 13)
- als höhere Kosten abzulehnen(A-D-E : 10)
- Einfügen in die Warteschlange(A-D-F : 16)
- als gleiche Kosten abzulehnenJetzt sieht die Warteschlange so aus:
Löschen
(A-D-E : 10)
(A-D-E-A : 26)
- als höhere Kosten abzulehnen(A-D-E-B : 22)
- als höhere Kosten abzulehnen(A-D-E-C : 19)
- als höhere Kosten abzulehnen(A-D-E-D : 10)
- als gleiche Kosten abzulehnen(A-D-E-F : 12)
- Einfügen in die WarteschlangeDann ist die Warteschlange:
Entfernen
(A-D-E-F : 12)
Sie, und stellen Sie fest, dass Sie zum Zielknoten gekommen sind (Kosten 12).Hinweis: die Pfade
(A-B-C-D-E-F)
,(A-C-D-E-F)
und(A-D-E-F)
alle haben den gleichen minimalen Kosten von 12.quelle
Stellen Sie eine Matrix mit allen Eckpunkten auf und verwenden Sie den Floyd-Wallenstein-Algorithmus oder den Bellman-Ford-Algorithmus. Beides ergibt eine Matrix mit möglichst kurzen Wegen zwischen allen Punkten. Sie können dann durch die Matrix iterieren, um den kürzesten Pfad zu finden, der zwei Punkte verbindet. (Ihr Problem ist dasselbe wie bei einem asymmetrischen TSP).
quelle