Ich bin mit Dijkstra sehr vertraut und habe eine spezielle Frage zum Algorithmus. Wenn ich einen riesigen Graphen habe, zum Beispiel 3,5 Milliarden Knoten (alle OpenStreetMap-Daten), kann ich den Graphen nicht im Speicher haben, also wird der Graphen auf einer Festplatte in einer Datenbank gespeichert.
Es stehen Bibliotheken zur Verfügung, mit denen kürzeste Pfade für solche Diagramme berechnet werden können. Wie machen sie das? Wie laden sie den erforderlichen Teil des Diagramms, um den Dijkstra-Algorithmus auszuführen?
Das Abrufen der Adjazenzliste jedes besuchten Scheitelpunkts würde nach meinen statistischen Daten ungefähr 1.500 Datenbankabfragen pro 10.000 Knoten erfordern, so dass es eindeutig nicht so ist, wie sie es tun. Das wäre viel zu langsam.
Wie machen Sie das? Ich versuche es selbst umzusetzen.
quelle
Antworten:
Sie können eine Datenbank, ein benutzerdefiniertes Dateiformat zum Lesen von Datenträgern und eine speicherinterne Einstellung verwenden.
Nach meiner Erfahrung ist die Verwendung einer Datenbank jedoch ungefähr 5- bis 10-mal langsamer und speicherintensiver als das Schreiben eines eigenen Dateiformats auf der Grundlage eines "einfachen" Formats für verknüpfte Listen.
Das Gute ist, dass es mehrere Open-Source-Software-Frameworks mit OSM gibt, so dass Sie direkt in den Code hineinschauen können (siehe hier) . In der Open-Source-Routing-Engine von GraphHopper ist es sehr einfach, von einer Einstellung für die Speicherzuordnung (auf Disc-Basis) auf die Einstellung für den internen Speicher umzuschalten - beide verwenden dasselbe Format. Die "mmap" -Einstellung ermöglicht sogar die Verwendung auf speicherbeschränkten Mobilgeräten. Letztere ist wesentlich schneller, wenn Sie über den erforderlichen Arbeitsspeicher verfügen, z. B. auf einem Server. ZB für einen weltweiten Graphen (> 100 Millionen Knoten) benötigen Sie dann ungefähr 8-10 GB RAM, plus viel mehr RAM, wenn Sie alles weiter beschleunigen möchten, z. B. mit Kontraktionshierarchien - ungefähr 5-8 GB mehr für jedes Fahrzeug, das Sie möchten.
Das Format ist sehr simpel und speichert im Grunde nur die Daten, die Sie mit ein paar Tricks benötigen, um es kompakt zu machen. Lesen Sie hier mehr darüber . Haftungsausschluss: Ich bin der Autor von GraphHopper.
Zu den anderen Antworten:
Der "normale" Dijkstra kann eine sehr vernünftige Leistung erbringen (<1s für landesweite Abfragen wie Ihr 3-Millionen-Knoten-Beispiel) und ist im "theoretischen Sinne" optimal , benötigt jedoch eine gewisse Anpassung , um in Produktionsszenarien schnell zu werden. Und Techniken wie Kontraktionshierarchien verwenden eine bidirektionale Modifikation davon und arbeiten sehr gut.
Straßennetze sind nur für Autos hierarchisch und nicht eben (Brücken, Tunnel, ...)
quelle
NodeID
den nächstgelegenen Knoten von derlatitude/longitude
? Dies ist erforderlich, um den kürzesten Pfad A-> B zu berechnen. Und wir müssen auch berücksichtigen, dass A und B möglicherweise nicht als Knoten existieren, da nicht jeder Quadratmeter einen Knoten enthält. Also müssen wir die 2 nächsten NodeIDs von A und B findenSie müssen nicht alle Kanten, die benachbart sind, in die Prioritätswarteschlange stellen. "Lüge" zu Dijkstras Algorithmus und gib ihm nur den kürzesten Scheitelpunkt, v, der auf den Scheitelpunkt fällt, sagen wir w, der vom Stapel gezogen wurde. Wenn dann v aus der Warteschlange gezogen wird, sagst du "oops", ich habe einen Fehler gemacht und hätte dir auch diesen Scheitelpunkt geben sollen, der dem Scheitelpunkt w am nächsten ist. Es ist leicht zu erkennen, dass Sie auf diese Weise eine korrekte Lösung erhalten und die Warteschlangengröße sich dramatisch auf nur einen der vielen Scheitelpunkte eines Vorfalls reduziert. Sie müssen jedoch die Vorfälle im Auge behalten, um bei Bedarf immer den nächstgelegenen Scheitelpunkt zu ermitteln. Einer der Kommentare behauptete, Straßennetze seien eben, was falsch ist. Tatsächlich hat eine Studie gezeigt, dass sie in hohem Maße nicht planar sind. Denken Sie an alle Autobahnen, die über Brücken durch eine Stadt führen und viele Unebenheiten verursachen.
quelle
Der anwendbare Dijkstras-Algorithmus wird für dieses Problem als nicht optimal angesehen, obwohl effizientere Varianten als "ähnlich" angesehen werden könnten. es gibt verschiedene Vereinfachungen. Straßennetze sind hierarchisch und planar . Hier sind die grundlegenden Ansätze. Das Gebiet wird allgemein als "Routenplanung in Straßennetzen" bezeichnet.
Aus den Daten der Adjazenzliste kann eine Graphenstruktur "kompiliert" werden. Dies ist der Ansatz in der Bibliothek, die Sie zitieren , SpatiaLite. Diese Diagrammstrukturen werden in einem komprimierten Binärformat gespeichert, in dem die Diagrammpositionen durch binär codierte Ganzzahlen usw. dargestellt werden. Die Darstellung und Bearbeitung des Diagramms nimmt also viel weniger Platz in Anspruch als das Speichern aller Straßennamen usw .; Es scheint, dass der SpatiaLite-Algorithmus nicht "online" ist und vollständig im Speicher ausgeführt wird.
Es gibt parallele / verteilte Algorithmen. siehe zB Scalable GPU Graph Traversal / Merrill, Garland, Grimshaw.
Die Frage verwendet Client-Server-Terminologie, dh "Abfragen". Die Algorithmen werden nicht ausgeführt, indem die Datenbank im Client-Server-Sinne "abgefragt" wird. Abfragesprachen höherer Ebenen wie SQL sind eine Schnittstelle zur Datenbank und können verwendet werden, um die Anforderung zur Berechnung der minimalen Routen zu übertragen, werden jedoch vom Algorithmus nicht intern verwendet. Im Allgemeinen läuft der Algorithmus "innerhalb der Datenbank", dh vollständig "serverseitig". Daher ist das Schreiben eines Algorithmus mit kürzestem Pfad in Datenbankabfragen für kleine Netzwerke, aber nicht für mittlere oder große Netzwerke möglich.
Es gibt einen anderen Ansatz, bei dem Schätzungen innerhalb kleiner Prozentsätze akzeptabel sein können. Die Grundidee besteht darin, einen Index der Abstände zwischen Knoten zu führen. siehe z. B. Schnelle und genaue Abschätzung der kürzesten Wege in großen Graphen / Gubichev, Bedathur, Seufert, Weikum
Diese (235p!) Doktorarbeit ist besonders anwendbar. Routenplanung in Straßennetzen / Schultes
Einige Algorithmen verwenden viele dieser Ideen, andere sind hochentwickelt und proprietär und stoßen auf wettbewerbsfähige Geschäftsgeheimnisse. zB Googles. Möglicherweise gibt es irreführende Medien zu diesem Thema. ZB Der einfache, elegante Algorithmus, der Google Maps ermöglicht, was besagt / impliziert, dass Google den Dijkstras-Algorithmus ohne Angabe von Gründen verwendet.
quelle
Für extrem große Datenmengen wie diese ist es am besten, eine Union-Find-Datenstruktur mit Pfadkomprimierung zu verwenden, um so schnelle Ergebnisse zu erzielen. Wenn Sie jedoch nur den Djikstra-Algorithmus verwenden und diesen optimieren möchten, kommt es darauf an, welche Informationen jeder Knoten im Diagramm hat. Höchstwahrscheinlich müssen Sie nicht alle 1.500 Abfragen durchführen.
Betrachten Sie beispielsweise das folgende Beispiel. Nehmen wir an, ich versuche, den Grad der Trennung zwischen zwei beliebigen Akteuren (die Bacon-Nummer) zu finden, und ich möchte den Pfad mit der geringsten Gewichtung finden (Pfad unter Verwendung der neuesten Filme, die möglich sind). Angenommen, ich habe eine Funktion namens
shortestPath(actor A, actor B);
. Stellen Sie sich das folgende Szenario vor.Wenn Schauspieler A seit 1970 und Schauspieler B seit 2000 tätig ist, wäre es angesichts dieser Informationen viel logischer, einen Pfad zu finden, der vom ersten Film von Schauspieler B aus beginnt und sich dann auf den Weg zu Schauspieler A macht im Gegensatz zu jedem Film, in dem Schauspieler A mitgespielt hat.
Der wichtigste Punkt ist also, dass die Optimierung des Djikstra-Algorithmus wirklich von Ihrem Datensatz abhängt. Sie müssen weitere Informationen darüber bereitstellen, was Ihr Datensatz für uns bedeutet, damit Sie Ihren Algorithmus optimieren können.
BEARBEITEN: Nehmen wir an, Sie versuchen, den kürzesten Weg zwischen zwei Städten im selben Land zu finden. Wenn dieses Land länger als breit ist, z. B. Argentinien, können Sie Ihre Abfragen anhand des Längen- und Breitengrads der Länder durchführen Grenzen. Dann können Sie beginnen, vertikal (unter Verwendung des Längengrads) und nicht horizontal zu verfahren. Natürlich müsste es eine Ausnahmebehandlung geben, aber Sie haben eine allgemeine Vorstellung davon.
quelle