Wie kann die Pfadfindung in einem sehr großen dynamischen 2D-Raster optimiert werden?


7

Ich habe eine große 2D-Tilemap mit einer Größe von Hunderten bis Tausenden. Die Karte besteht aus 8x8 Blöcken. Ich verwende derzeit A *, aber es ist nicht sehr effizient, da ich möglicherweise bis zu hundert Objekte gleichzeitig finden kann. Der Weg muss nicht unbedingt der kürzeste sein, es wird jedoch ein gewisses Maß an Kürze erwartet.

Ich habe hier nachgesehen und festgestellt, dass HPA * für mich möglicherweise funktioniert, da meine Karte in kleinere Teile unterteilt ist. Da die Karte jedoch sehr dynamisch ist (nehmen wir das zumindest an zwei Blöcke pro Sekunde geändert werden), scheint es bessere Alternativen zu geben.

Auch D * / Lite (im Link erwähnt) könnte funktionieren, aber wie kann es für ein Chunk-basiertes Raster optimiert werden?

Bei meiner Frage geht es nicht speziell um HPA * oder D *, sondern darum, einen optimalen Algorithmus für eine große und dynamische, auf Chunks basierende Tilemap zu finden.

BEARBEITEN: Die Chunks enthalten prozedural generierten Inhalt. Meistens bedeutet dies, dass der Block bis auf etwa 10 bis 20% seiner Kacheln leer ist. Manchmal kann diese Zahl jedoch bis zu 90% betragen (dh bei generierten "Blobs"). Die Chunks enthalten nahezu beliebige Daten, und zwei Chunks sind selten gleich.

Darüber hinaus verfügt jeder Agent über einen unabhängigen Pfad. Da die Karte jedoch dynamisch ist, kann sie künstliche Korridore und lange Durchgänge enthalten, die dazu führen können, dass sie häufig von vielen Agenten gemeinsam genutzt werden.

Die meisten Ziele werden willkürlich lokalisiert, es gibt jedoch auch einige vordefinierte Ziele (Standorte). Für diese vordefinierten Orte erwäge ich, ein Vektorfeld (ähnlich einer Wärmekarte) zu verwenden, mit dem man sich ihm nähern kann. Dies für jedes Ziel zu tun, wäre jedoch furchtbar ineffizient, zumal ich das generierte Feld nur einmal (oder in besseren Fällen vielleicht ein paar Mal) verwenden würde.


1
Können Sie uns einige Details darüber geben, wie diese Brocken aussehen? Werden sie aus einem festen Pool ausgewählt oder können sie willkürliche Inhalte haben? Beispielbilder sind immer hilfreich bei Fragen mit einer geometrischen Komponente. :) Und welche Art von Wegfindung brauchst du? Verwendet jeder Agent ein unabhängiges Ziel / einen unabhängigen Pfad oder gibt es ein gewisses Maß an Schwärmen oder gemeinsamen Zielen?
DMGregory

@ DMGregory Ich habe die spezifischen Details erklärt. :)
Dave

Ich werde vorschlagen, sich mit der Sprungpunktsuche zu befassen, die eine fantastische Optimierung für A * darstellt, da sie die Anzahl der für die Suche erforderlichen Knoten reduziert, indem Erweiterungsrichtungen eliminiert werden, die möglicherweise nicht optimal sind.
Draco18s vertraut SE

@ Draco18s Interessant, das könnte für die Korridore sehr hilfreich sein! Danke für den Tipp.
Dave

1
@ BlueRaja-DannyPflughoeft Unique
Dave

Antworten:


2

Hundert Objekte, die Wegfindung betreiben, bilden eine "Menge", denke ich. Dazu sollten Sie sich Continuum Crowds ansehen von der University of Washington .

Was Sie tun, ist die Wegfindung von überall auf der Karte zu einem Ziel zu lösen. Dann kann jeder Agent, der dieses Ziel teilt, es verwenden.

Dies funktioniert gut, wenn Sie viele Agenten haben, aber nur wenige unterschiedliche Ziele.

Ich habe dies in meiner Pyramidenbausimulation verwendet, die Tausende von Agenten ausführen kann der Pfadfindung mit 60 Hz ausführen kann.

Es kommt darauf an, die gesamte Karte zu lösen: Wie weit ist es von hier bis zum Ziel? Berechnen Sie aus dieser Karte einen Farbverlauf und folgen Sie diesem Farbverlauf.

Es verfügt über einige raffinierte Funktionen wie "automatische Spurbildung", wenn zwei Streams (mit unterschiedlichen Zielen) miteinander kollidieren. Die Mittel bilden dann Spuren, da das Bewegen gegen den vorherrschenden Fluss teurer ist als das Gehen mit ihm.

Das Bild unten zeigt dieses "Potentialfeld" (Abstand zu einem bestimmten Ziel), das als Farbe dargestellt und dann als Gradientenvektorfeld überlagert wird.

Geben Sie hier die Bildbeschreibung ein


0

Sie möchten wahrscheinlich keinen vollständigen Pfadfindungsalgorithmus pro Einheit ausführen: Hier finden Sie wahrscheinlich die Ineffizienz. Stattdessen würden Sie pro Zielort eine Karte mit dem kürzesten Weg zum Ziel erstellen. Wenn also mehrere Einheiten auf ein Ziel zusteuern, suchen sie einfach in dieser Karte nach der Kachel, zu der sie sich am nächsten bewegen.

Eine solche Karte wäre ein separates Raster, das basierend auf dem Hauptraster berechnet wird, mit dem Sie arbeiten. Aber mehr als nur Wände würden alle "offenen" Kacheln Zahlen enthalten, die als kürzeste Entfernung zum Ziel von dieser Stelle vorberechnet werden.

Eine beispielhafte berechnete Karte würde folgendermaßen aussehen (X bezeichnet eine Wand, 0 bezeichnet das Ziel)

6 5 4 3 2 3
7 X 3 2 1 2
8 X 2 1 0 1
X X X X X 2

Jede Einheit, die auf das Ziel zusteuert (die 0), folgt einfach den Zahlen in diesem Raster nach unten. Jede Änderung am Raster würde Sie zwingen, diese Karte neu zu berechnen (und wie Sie dies effizient gestalten, hängt von Ihrem speziellen Algorithmus ab). Ein einfacher Ansatz zum Erstellen einer solchen Karte wäre die Verwendung einer ersten Durchquerung der Breite vom Zielort.

Die Hauptidee ist, dass Sie Hunderte von Einheiten verwenden können, die dieselbe Pfadkarte verwenden, um den Weg zu einem Ziel zu finden, ohne für jeden von ihnen einen eigenen Pfad zu berechnen.


Dies funktioniert, wenn nur wenige Endpunkte vorhanden sind. Es klingt so, als wäre das nicht der Fall, obwohl seine Frage nicht ganz klar ist.
BlueRaja - Danny Pflughoeft

Ich habe mehrere Endpunkte, aber diese Endpunkte ändern sich häufig, sodass die Erstellung einer Heatmap möglicherweise nicht die beste Wahl ist.
Dave

Sie möchten wahrscheinlich immer noch eine Heatmap pro Endpunkt, anstatt die Pfadfindung pro Einheit durchzuführen (jedes Mal, wenn sich die Ziele ändern). Wenn Sie 1000 Einheiten und nur 4/5 Endpunkte haben, die sich ändern, möchten Sie diese weiterhin generieren Heatmap-Ansatz. Wenn Sie bei jeder Änderung die Pfadfindung pro Einheit ausführen, führen Sie 1000 * 4/5 Pfadfindungsläufe anstelle von 4/5 Heatmap-Updates durch. Ihre Frage würde dann lauten, wie Sie eine solche Heatmap schnell ändern würden. So wird es mit jedem Spiel gemacht, bei dem Sie Hunderte von Einheiten haben (entweder mit Kacheln oder Wegpunkten)
Danny Yaroslavski

@DannyYaroslavski Ja, ich stimme zu, aber ich habe bereits gesagt, dass ich dies für die vordefinierten / weniger häufig wechselnden Punkte im Hauptteil der Frage tun werde.
Dave

Ich verstehe nur nicht, warum Sie die Vektorkarte nur einmal verwenden würden - wie gesagt, Sie hätten eine Vektorkarte pro Endpunkt. Wenn mehrere Einheiten dieselben Endpunkte verwenden, ist dies der ideale Weg, um dies zu erreichen. Andernfalls können Sie nichts optimieren, wenn Sie mehrere Einheiten haben, die dieselbe dynamische Karte und keine Endpunkte gemeinsam nutzen.
Danny Yaroslavski

0

Da jede Einheit einen eindeutigen Endpunkt hat, ist HPA * wahrscheinlich die beste Wahl.

Wenn sich ein Block ändert, müssen Sie seinen Knoten auf jeder Ebene in der Hierarchie aktualisieren und dann die Pfadfindung für jede Einheit erneut ausführen (wenn eine Wand hinzugefügt wurde, können Sie Einheiten überspringen, deren bester Pfad diesen Knoten nicht durchlaufen hat) . Da sich das Diagramm so oft ändert, würde ich empfehlen, die Pfadfindung nur auf der höchsten Ebene auszuführen und dann nur bei Bedarf einen Drilldown durchzuführen. Die oberste Schicht hat nur wenige Knoten, daher ist dies sehr schnell.

An diesem Punkt Profil. Wenn Sie feststellen, dass Sie die Pfadfindung beschleunigen müssen, können Sie sich mit JPS (für die untersten Ebenen) und DynamicSWSF-FP befassen (für die höheren Ebenen) usw. . Sie können auch die häufigsten Abfragen auf jeder Ebene zwischenspeichern . Eine weitere gute Optimierung wäre, nur den Pfad für einige Einheiten pro Frame neu zu berechnen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.