2012-06-30 6 views
5

Ich bin ein echter Geschwindigkeitsfreak, wenn es um Algorithmen geht, und in den Plugins, die ich für ein Spiel gemacht habe.Schnellere Alternativen zu Dijkstra-Algorithmus für GPS-System

Die Geschwindigkeit ist .. ein bisschen .. nicht befriedigend. Vor allem während man mit dem Auto herumfährt und man nicht seinem Weg folgt, muss der Weg neu berechnet werden. Und es braucht etwas Zeit. So stapelt das In-Game-GPS viele "falsche" Signale (und stapelt die Signale auf bedeutet mehr Berechnungen danach, für jeden falschen Weg) weil ich ein schnelles, Live-GPS-System haben möchte, das ständig aktualisiert.

änderte ich den alten Algorithmus (einige einfache dijkstra Implementierung) boost :: Dijkstra einen Weg vom Knoten A zum Knoten B um

(Gesamtknotenliste zu berechnen ist ~ 15k Knoten mit ~ 40k-Verbindungen, für neugierige Leute hier ist die Karte: http://gz.pxf24.pl/downloads/prv2.jpg (12 MB), Kanten in den roten Linien sind die Knoten),

, aber es hat nicht wirklich an Geschwindigkeit zu erhöhen. (Zumindest nicht merklich, vielleicht 50 ms).

Die Informationen, die in dem Knoten-Array gespeichert sind:

The ID of the Node, 
The position of the node, 
All the connections to the node (and which way it is connected to the other nodes, TO, FROM, or BOTH) 
Distance to the connected nodes. 

Ich bin neugierig, ob jemand ein paar schnelleren Alternativen in C/C++ kennt? Irgendwelche Vorschläge (+ Codebeispiele?) Werden geschätzt!


Wenn jemand an dem Projekt interessiert ist, hier ist es (Quelle + Binärdateien):

https://gpb.googlecode.com/files/RouteConnector_177.zip

In diesem Video können Sie sehen, was das GPS-System ist wie:

http://www.youtu.be/xsIhArstyU8

wie Sie sehen können, die rote Route wird langsam aktualisiert (gut, für uns - Gamer - es ist langsam).

(Bytheway: die Lücken zwischen den roten Linien haben vor langer Zeit fest: p)

+4

Haben Sie A * probiert? Es ist der gebräuchlichste (sicherlich der einfachste) heuristikbasierte Pfadfindungsalgorithmus. Und in einer GPS-artigen Situation funktioniert die Heuristik "Luftlinie in der Luftlinie" meist recht gut. – biziclop

+0

@biziclop hat Boost eine A * Implementierung? Ich kann nichts finden google = ein * boost oder ein * algorythm boost –

+1

Die zweite Optimierungsmöglichkeit kommt von der Tatsache, dass in einer GPS-Neuberechnung Situation Ihr Ziel immer gleich ist und Ihre Quelle nicht weit von der vorherigen Iteration entfernt ist, also wenn Sie die kürzeste speichern Von der vorherigen Berechnung ausgehend müssen Sie nur suchen, bis Sie einen Knoten erreichen, der bereits in dieser Liste enthalten ist. – biziclop

Antwort

5

Da dies ein GPS ist, muss es ein festes Ziel hat. Anstatt den Pfad von Ihrem aktuellen Knoten zum Ziel jedes Mal zu berechnen, wenn Sie den aktuellen Knoten ändern, können Sie stattdessen die kürzesten Pfade von Ihrem Ziel zu allen Knoten finden: Führen Sie Dijkstra einmal vom Ziel aus aus. Dies dauert ungefähr so ​​lange, wie ein Update jetzt dauert.

Dann behalten Sie in jedem Knoten prev = the node previous to this on the shortest path to this node (von Ihrem Ziel). Sie aktualisieren dies, während Sie die kürzesten Pfade berechnen. Oder Sie können ein prev[] Array außerhalb der Knoten verwenden - grundsätzlich sollte die Methode, die Sie zur Rekonstruktion des Pfads verwenden, jetzt noch funktionieren.

Wenn Sie Ihr Auto bewegen, wird Ihr Pfad durch currentNode.prev -> currentNode.prev.prev -> ... angegeben.

Dies wird die Aktualisierungsverzögerung lösen und Ihren Pfad optimal halten, aber Sie werden immer noch eine leichte Verzögerung haben, wenn Sie Ihr Ziel eingeben.

Sie sollten diesen Ansatz prüfen, auch wenn Sie sich mit A * oder andere Heuristik planen, die zumindest nicht immer die optimale Antwort geben, wenn Sie noch Verzögerung mit diesen Ansätzen bekommen.

Zum Beispiel, wenn Sie diese Grafik:

1 - 2 cost 3 
1 - 3 cost 4 
2 - 4 cost 1 
3 - 4 cost 2 
3 - 5 cost 5 

Die prev Array würde wie folgt aussehen (berechnet, wenn Sie die Abstände d[] berechnen):

 1 2 3 4 5 
prev = 1 1 1 2 3 

Bedeutung:

shortest path FROM TO 
       1 2 = prev[2], 2 = 1, 3 
       1 3 = prev[3], 3 = 1, 3 
       1 4 = prev[ prev[4] ], prev[4], 4 = 1, 2, 4 (fill in right to left) 
       1 5 = prev[ prev[5] ], prev[5], 5 = 1, 3, 5 
       etc. 
+0

Habe ich es richtig verstanden ?; Ich muss vom Ziel, zu allen Knoten, einen Pfad berechnen, die Pfade speichern und dann verwenden? Wouldn't erfordert diese riesige Menge an Speicher ... Offtopic: Ich habe einmal versucht, einen Vektor, der 64 GB RAM benötigt, zu initialisieren, ich scheiterte XD –

+0

@anyonewhoclosedthistopic, ich habe ein Szenario hier, diese Frage nicht! Dies ist kein Duplikat: ((zumindest kein exaktes Duplikat), bitte nicht schließen. –

+0

@GamErix - Nein: Sie brauchen nur ein 'prev' Array der Größe' Anzahl der Knoten'. Führen Sie dijkstra einmal vom Ziel aus und füllen Sie das prev-Array so, dass "prev [i] = Knoten vor i auf dem kürzesten Weg vom Startknoten zum Knoten i." Sie speichern die tatsächlichen Pfade nicht, da sie viele gleiche Knoten enthalten Du konstruierst irgendeinen Pfad, wenn du es brauchst – IVlad

2

Um den Start sofort zu machen, können Sie im folgenden w betrügen ja.

Haben Sie eine ziemlich kleine Reihe von "Hauptdurchgangsknoten". Definieren Sie für jeden Knoten seine "Nachbarschaft" (alle Knoten innerhalb einer bestimmten Entfernung). Speichern Sie die kürzesten Routen von jedem Hauptverkehrsknotenpunkt zu jedem anderen. Speichern Sie die kürzesten Routen zu/von jedem Knoten zu seinen Hauptverkehrsstraßen.

Wenn sich die zwei Knoten in derselben Nachbarschaft befinden, können Sie die beste Antwort im laufenden Betrieb berechnen. Sonst bedenken Sie nur die Wege der Form, "hier zum Hauptdurchgangsknoten neben mir zur Hauptverkehrsstraße in der Nähe davon". Da Sie diese bereits vorausberechnet haben und eine begrenzte Anzahl von Kombinationen haben, sollten Sie sehr schnell in der Lage sein, eine Route im laufenden Betrieb zu berechnen.

Dann wird die Herausforderung eine Reihe von Hauptdurchgangsknoten auswählen. Es sollte eine ziemlich kleine Menge von Knoten sein, die die meisten guten Routen durchlaufen sollten - wählen Sie daher regelmäßig Knotenpunkte entlang der Hauptstraßen. Eine Liste von ein paar hundert sollte mehr als gut genug für Ihre Karte sein.

+0

jede 'Durchgangsstraße' (Straße?) Kann viele Knoten haben, sogar gerade Linien bestehen aus mehreren Knoten :) So, wie man das anpackt? –

+0

@GamErix Wählen Sie einfach einen Knoten auf Ihren Straßen. Sie wollen nicht jeden vielversprechenden Knoten. Es geht Ihnen gut, solange Sie genug haben, dass die beste Route, die eine lange Strecke zurücklegt, mit ziemlicher Sicherheit mehrere davon durchläuft. – btilly

+0

Vielen Dank für Ihre Eingabe, diese ist gelöst, jetzt werde ich eine weitere Frage über arthimetrics stellen. Etwas funktioniert nicht richtig xD –