6 Stimmen

Leistung einer in Clojure implementierten A*-Suche

Ich habe eine A*-Suchalgorithmus für die Suche nach einem kürzeste Weg zwischen zwei Zuständen. Der Algorithmus verwendet eine Hash-Map zur Speicherung der besten bekannten Entfernungen für besuchte Zustände. Und eine Hash-Map für die Speicherung von Kind-Eltern-Beziehungen, die für die Rekonstruktion des kürzesten Pfades benötigt werden.

Hier ist der Code. Die Implementierung des Algorithmus ist generisch (die Zustände müssen nur "hashable" und "comparable" sein), aber in diesem speziellen Fall sind die Zustände Paare (Vektoren) von ints [x y] und sie stellen eine Zelle in einer bestimmten Höhenkarte dar ( Kosten für den Sprung zu Nachbarzelle hängt von der Höhendifferenz ab).

Die Frage ist, ob es möglich ist, die Leistung zu verbessern und wie? Vielleicht durch die Verwendung einiger Funktionen aus 1.2 oder zukünftigen Versionen, durch eine Änderung der Logik der Algorithmus-Implementierung (z.B. durch eine andere Art der Pfadspeicherung) oder eine Änderung der Zustandsdarstellung in diesem speziellen Fall?

Java-Implementierung läuft im Handumdrehen für diese Karte und die Clojure-Implementierung dauert etwa 40 Sekunden. Natürlich gibt es dafür einige natürliche und offensichtliche Gründe: dynamische Typisierung, persistente Datenstrukturen, unnötiges (Un-)Boxing von primitiven Typen...

Die Verwendung von Transienten hat keinen großen Unterschied gemacht.

4voto

JoeCamel Punkte 642

使用方法 priority-map anstelle von sorted-set

Ich habe zuerst sorted-set für die Speicherung offener Knoten (Suchgrenze), Wechsel zu priority-map verbesserte Leistung: jetzt dauert es 15-20 Sekunden für diese Karte (bevor es 40 Jahre dauerte).

Ce site Blog-Beitrag war sehr hilfreich. Und "meine" neue Implementierung ist so ziemlich die gleiche.

Neue a*-Suche kann gefunden werden aquí .

3voto

Shaggy Frog Punkte 27326

Ich kenne Clojure nicht, aber ich kann Ihnen einige allgemeine Ratschläge zur Verbesserung der Leistung von Vanilla A* geben.

  • Erwägen Sie die Umsetzung IDA* die eine Variante von A* ist, die weniger Speicherplatz benötigt, wenn sie für Ihren Bereich geeignet ist.

  • Versuchen Sie eine andere Heuristik. Eine gute Heuristik kann einen erheblichen Einfluss auf die Anzahl der erforderlichen Knotenerweiterungen haben.

  • Verwenden Sie einen Cache, oft als " Umsetzungsliste " in Suchalgorithmen. Da die Suchgraphen in der Regel Gerichtet azyklische Graphen und keine echten Bäume, kann es passieren, dass die Suche nach einem Zustand mehr als einmal wiederholt wird; ein Zwischenspeicher zur Erinnerung an zuvor gesuchte Knoten verringert die Anzahl der Knotenerweiterungen.

Dr. Jonathan Schaeffer hat einige Folien zu diesem Thema:

http://webdocs.cs.ualberta.ca/~jonathan/Kurse/657/Notes/10.Single-agentSearch.pdf

http://webdocs.cs.ualberta.ca/~jonathan/Kurse/657/Notizen/11.Evaluierungen.pdf

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X