Einige Ideen zum Vermeiden von Suchvorgängen, die zu fehlgeschlagenen Pfaden führen:
Insel ID
Eine der billigsten Möglichkeiten, A * -Suchen effektiv zu beenden, besteht darin, überhaupt keine Suchvorgänge durchzuführen. Wenn die Bereiche für alle Agenten wirklich unpassierbar sind, füllen Sie jeden Bereich unter Last (oder in der Pipeline) mit einer eindeutigen Insel-ID . Überprüfen Sie beim Ermitteln des Pfads , ob die Insel-ID des Ursprungs des Pfads mit der Insel-ID des Ziels übereinstimmt . Wenn sie nicht übereinstimmen, macht die Suche keinen Sinn - die beiden Punkte befinden sich auf unterschiedlichen, nicht verbundenen Inseln. Dies hilft nur, wenn es wirklich unpassierbare Knoten für alle Agenten gibt.
Obergrenze einschränken
Ich beschränke die Obergrenze der maximalen Anzahl von Knoten, die durchsucht werden können. Dies verhindert, dass unpassierbare Suchvorgänge für immer ausgeführt werden. Es bedeutet jedoch, dass einige sehr lange passierbare Suchvorgänge verloren gehen können. Diese Nummer muss angepasst werden und löst das Problem nicht wirklich , verringert jedoch die mit langen Suchvorgängen verbundenen Kosten.
Wenn Sie feststellen, dass es zu lange dauert , sind die folgenden Techniken hilfreich:
Machen Sie es asynchron und begrenzen Sie Iterationen
Lassen Sie die Suche in einem separaten Thread oder in einem Teil jedes Frames ablaufen, damit das Spiel nicht auf die Suche wartet. Zeigen Sie eine Animation des Charakters an, der den Kopf kratzt oder die Füße stampft, oder was auch immer angebracht ist, während Sie darauf warten, dass die Suche endet. Um dies effektiv zu tun, würde ich den Status der Suche als separates Objekt beibehalten und zulassen, dass mehrere Status existieren. Wenn ein Pfad angefordert wird, greifen Sie auf ein Objekt mit freiem Status zu und fügen Sie es der Warteschlange der aktiven Statusobjekte hinzu. Ziehen Sie in Ihrem Pfadfindungs-Update das aktive Element von der Vorderseite der Warteschlange und führen Sie A * aus, bis A. abgeschlossen ist oder B. eine bestimmte Anzahl von Iterationen ausgeführt wird. Wenn Sie fertig sind, fügen Sie das Statusobjekt wieder in die Liste der freien Statusobjekte ein. Wenn es noch nicht abgeschlossen ist, setzen Sie es an das Ende der aktiven Suche und fahren Sie mit der nächsten fort.
Wählen Sie die richtigen Datenstrukturen
Stellen Sie sicher, dass Sie die richtigen Datenstrukturen verwenden. So funktioniert mein StateObject. Alle meine Knoten sind aus Leistungsgründen einer endlichen Zahl (z. B. 1024 oder 2048) zugeordnet. Ich verwende einen Knotenpool, der die Zuweisung von Knoten beschleunigt und es mir auch ermöglicht, Indizes anstelle von Zeigern in meinen Datenstrukturen zu speichern, die u16s sind (oder u8, wenn ich 255 maximale Knoten habe, was ich bei einigen Spielen mache). Für die Pfadfindung verwende ich eine Prioritätswarteschlange für die offene Liste, in der Zeiger auf Knotenobjekte gespeichert sind. Es ist als binärer Heap implementiert und ich sortiere die Gleitkommawerte als Ganzzahlen, da sie immer positiv sind und meine Plattform langsame Gleitkommavergleiche hat. Ich verwende eine Hashtabelle für meine geschlossene Karte, um die Knoten zu verfolgen, die ich besucht habe. Es speichert NodeIDs, nicht Nodes, um Cache-Größen zu sparen.
Cache was du kannst
Wenn Sie einen Knoten zum ersten Mal besuchen und die Entfernung zum Ziel berechnen, speichern Sie die im Statusobjekt gespeicherten Werte im Cache. Wenn Sie den Knoten erneut besuchen, verwenden Sie das zwischengespeicherte Ergebnis, anstatt es erneut zu berechnen. In meinem Fall hilft es, keine Quadratwurzel auf neu besuchten Knoten zu machen. Möglicherweise gibt es andere Werte, die Sie vorberechnen und zwischenspeichern können.
Weitere Bereiche, die Sie untersuchen könnten: Verwenden Sie die bidirektionale Pfadfindung, um von beiden Seiten aus zu suchen. Ich habe dies nicht getan, aber wie andere bemerkt haben, könnte dies helfen, ist aber nicht ohne Einschränkungen. Die andere Sache auf meiner Liste, die ich versuchen möchte, ist die hierarchische Pfadfindung oder die Cluster-Pfadfindung. Es gibt eine interessante Beschreibung in der HavokAI Dokumentation Hier ihr Clustering - Konzept beschreibt, die als die HPA unterscheiden * Implementierungen beschrieben hier .
Viel Glück und lassen Sie uns wissen, was Sie finden.