Gibt es einen besseren Ansatz für die Suche nach kürzesten Wegen innerhalb eines (Fahrzeug-) Verkehrsnetzes?

8

Liebe Programmierkollegen,

Wir entwickeln eine Software, die den Fahrzeugverkehr simuliert. Ein Teil des als "Zuweisung" bezeichneten Prozesses befasst sich mit der Zuweisung von Fahrzeugen zu ihren Routen und muss eine Art Algorithmus zum Auffinden kürzester Wege verwenden.

Traditionell tun dies Menschen mit Dijkstra, und bestimmte wissenschaftliche Literatur scheint darauf hinzudeuten, dass A * und andere Alternativen keine signifikante Verbesserung ergeben, möglicherweise aufgrund der Art des Diagramms.

Daher verwenden wir auch Dijkstra. Ein kleines Problem bestand darin, dass Sie, wenn Sie Verkehrsverbindungen (Straßenspannen zwischen Kreuzungen) als Kanten und Kreuzungen als Knoten behandeln, kein klassisches unidirektionales Diagramm erhalten können: Wenn Sie sich einer Kreuzung nähern, von der Sie häufig abbiegen können, hängt dies davon ab woher Sie kommen, während Sie in einem herkömmlichen Diagramm eine beliebige Kante von einem Knoten nehmen können.

Wir haben dieses Problem ganz einfach gelöst, indem wir ein Verbindungs-Schnittpunkt-Paar (nennen wir es "Latte") als Knoten dargestellt haben. Da Sie einen Link durchlaufen müssen, um zu einer nachfolgenden "Leiste" oder einem Punkt Ihrer Wahl zu gelangen, wird eine Kante als diese Durchquerung definiert, und Sie erhalten ein typisches Diagramm.

Die Ergebnisse werden dann in einer einfachen Tabelle N x N gespeichert, wobei N die Anzahl der "Latten" ist.

Hier ist der (unvermeidliche?) Nachteil. Wenn ein typisches Netzwerk für unsere Simulation beispielsweise 2000 Kreuzungen haben kann, hat es ungefähr 6000 Verbindungen, dh N = 3V. Wenn wir in Bezug auf die Schnittpunkte (V) gezählt werden, sind wir jetzt bis zu O (log (3V) * (3V + E)).

Sie könnten argumentieren, dass 3 (oder 9) ein konstanter Faktor ist, aber vom praktischen Standpunkt aus verlangsamt er die Dinge erheblich und erhöht den Speicherplatz auf 3 V x 3 V.

Hat jemand eine Idee, wie wir dies umstrukturieren können, um die Leistung zu verbessern? Nicht unbedingt ein alternativer Algorithmus, vielleicht die Datenstrukturen neu formen, um sie auf andere Weise an einen Graphen anzupassen?

Greg Kramida
quelle
Mir ist nicht klar, was N und V sind. Ist V die Anzahl der Eckpunkte (Schnittpunkte) und N die Anzahl der Bögen zwischen Eckpunkten? Was ist E?
Mike Dunlavey
Welche Ressourcen haben Sie gelesen? IIRC, A * findet bei einer pessimistischen Heuristik nachweislich in kürzester Zeit den optimalen Weg. Tatsächlich regressiert A * mit einer leeren / 0-Heuristik in die Dijkstra.
Steven Evers
Welche Diagrammdarstellung verwenden Sie? Unidirektionale Graphen mit Adjazenzlisten würden Straßen leicht als Kanten / Kreuzungen als Knoten zulassen (tatsächlich würde sogar eine Adjazenzmatrix dies tun, aber es müsste offensichtlich eine vollständige Matrix anstelle eines oberen / unteren Dreiecks sein). TBH: Ich würde eine Menge Literatur zur Spielprogrammierung vorschlagen, es ist ein hoch gearbeitetes Problem auf diesem Gebiet und hat die gleichen oder strengeren Leistungsbeschränkungen, als Sie erwähnen.
Steven Evers
1
@SnOrfus: Ja, aber Sie können eine einzelne Kreuzung nicht immer als einen einzelnen Knoten darstellen. Wenn Sie beispielsweise eine Kreuzung verwenden, können Sie nach links oder geradeaus abbiegen, aber nicht nach rechts. Die einfache Adjazenzmatrix kann dies nicht darstellen. schlimmer, wenn Sie einen Kreisverkehr haben).
Lie Ryan
@LieRyan: Vielleicht verstehe ich dich falsch, aber das unterscheidet sich nicht von einer Kreuzung, an der es keine Rechtskurve gibt und die auf die gleiche Weise dargestellt werden sollte.
Steven Evers

Antworten:

6

Dijkstra findet den kürzesten Weg zwischen einem bestimmten Knoten und allen anderen Knoten, daher erwarte ich, dass er teurer als A * wäre. Es sieht jedoch so aus, als würden Sie versuchen, die Kosten und den Pfad von einem Knoten zu einem anderen vorab zu berechnen. Dann ist Dijkstra der richtige Weg.

Für eine einfachere Darstellung fallen einige Dinge ein:

An vielen Kreuzungen können Sie kommen und gehen, wie Sie wollen. Es ist nur eine Teilmenge, für die Sie Einschränkungen wie "keine Linkskurve" haben. Sie können die "Latten" also nur für Kreuzungen verwenden, an denen Sie sie tatsächlich benötigen. Das sollte die Größe genau dort stark reduzieren.

Sie können dies automatisch tun, indem Sie nach "äquivalenten Latten" suchen und diese kombinieren. Zwei Latten sind gleichwertig, wenn alle herauskommenden Links gleich sind. Wenn beispielsweise "Schnittpunkt X aus dem Westen" und "Schnittpunkt X aus dem Süden" beide zu demselben Satz anderer Knoten mit denselben Kosten führen, führen Sie diese einfach zu einem einzigen Knoten zusammen.

Sind Sie sicher, dass Sie den besten Pfad vorberechnen müssen / möchten, anstatt ihn online zu berechnen? Videospiele berechnen diese Dinge normalerweise online.

Wie repräsentieren Sie die Pfade? In Ihrer Matrix müssen Sie nur den ersten Link im Pfad darstellen. Um beispielsweise von Bobs Haus zu Bobs Arbeit zu gelangen, müssen Sie nur den ersten Link kennen. Wenn sie dort ankommen, können Sie jetzt in Ihrer Matrix nachsehen, wie Sie vom ersten Link zu Bobs Arbeit gelangen, die Sie erhalten der zweite Link usw.

Martin C. Martin
quelle
Das Kombinieren von "Latten" ist in der Tat eine interessante Idee. Sie haben Recht, wir finden den kürzesten Pfad zwischen jedem Knotenpaar und generieren dann Pfade. In einer typischen Verkehrssimulation werden kaum Straßen benutzt (warum sollte es dort überhaupt eine Straße geben, oder?). Wenn Sie "online" sagen, meinen Sie das in Echtzeit? Alles, was wir wirklich tun können, ist, "erwartete" kürzeste Wege zu berechnen, da wir nicht genau wissen, wie die Bedingungen auf einer Verbindung sein werden, wenn das Fahrzeug tatsächlich dort ankommt. Wir aktualisieren die kürzeste Pfadmatrix basierend auf den aktuellen Bedingungen.
Greg Kramida
Ja, mit "online" meine ich in Echtzeit, dh wenn Bob sein Haus verlässt und zur Arbeit gehen möchte, dann mache das A *.
Martin C. Martin
Abhängig davon, wie oft die Matrix mit dem kürzesten Pfad aktualisiert werden muss, müssen Sie möglicherweise viel Arbeit für das Update aufwenden und verwenden nicht die meisten Zellen, bevor Sie das Update erneut durchführen. Ich kenne die Details Ihres Anwendungsfalls nicht, aber von außen scheint es, dass A * zumindest einen Versuch wert ist. Auch wenn alle N Knoten irgendwann verwendet werden, bedeutet dies nicht, dass alle N ^ 2 Paare irgendwann verwendet werden. Die Leute auf Bobs Block, wie viele einzigartige Ziele haben sie?
Martin C. Martin
Ja, ich stimme zu, A * ist wahrscheinlich einen Versuch wert. Für einige Simulationen leiten wir einen Teil der Fahrzeuge an jedem Ursprung zu fast allen Zielen, aber bei weitem nicht in jedem Fall. Ich habe ein paar Artikel über Leute gefunden, die verschiedene Heuristiken mit A * speziell für Verkehrsnetze verwenden. Ich werde diese ausprobieren. Danke für deine Hilfe, Martin.
Greg Kramida
1

Sie haben eine große Grafik und haben sie noch größer gemacht. Martinc C. Martin hat empfohlen, Drehmaschinen nur bei Bedarf zu verwenden, daher werde ich nicht darauf eingehen.

Eines der Dinge, die Ihnen helfen könnten, ist die Umwandlung Ihres Diagramms in kleinere Diagramme.

Die erste Vereinfachung, die mir sehr geholfen hat (ich habe mit Straßennetzen europäischer Staaten gearbeitet), war das rekursive "Entfernen" von Knoten mit Digree 1 und 2. Auf diese Weise haben Sie keine Sackgassen und T-Kreuzungen (ursprünglich Grad 3) werden zu Grad 2, und das ist nicht interessant, wenn Sie nicht zu diesem Knoten oder Knoten in dieser entfernten Sackgasse gehen.

Danach können Sie versuchen, Ihr Diagramm in Teile zu unterteilen, die eine große Anzahl interner Knoten und Kanten aufweisen, aber nur eine minimale Verbindung zu anderen Teilen haben. Um sie zu finden, habe ich einen minimalen Schnitt verwendet, bei dem Spüle und Quelle so weit voneinander entfernt waren (in Kanten) und Kanten in ihrer Nähe eine große Kapazität hatten und Kanten dazwischen klein waren.

user470365
quelle