Algorithmus für Durchmesser von graph?
Wenn Sie ein Diagramm, und müssen feststellen, dass die Durchmesser der es (was ist die maximale Entfernung zwischen zwei Knoten), wie können Sie es tun in O(log v * (v + e))
Komplexität.
Wikipedia sagt, Sie können dies tun, indem Dijkstra-Algorithmus
mit einem binary heap
.
Aber ich verstehe nicht, wie das funktioniert. Kann sich das jemand erklären bitte?
Oder zeigt eine pseudocode?
- Der Dijkstra-Algorithmus nicht den Durchmesser des Graphen; es wird nur der Abstand von einigen Knoten zu jedem anderen Knoten im graph. Gibt es eine Ressource, die Sie haben, die sagt, dass Sie verwenden können, Dijkstra, dies zu tun?
- cs.stackexchange.com/questions/194/...
- Nichts in dem link sagt, dass Sie verwenden sollten, Dijkstra, dies zu tun.
- oh, ok, aber gibt es eine Möglichkeit, dies zu tun in
O(log n * (n + e)
Komplexität? - Ist sind die Kanten gewichtet?
- Sie sind nicht gewichtet.
- Was ist
e
? Auch soll das arbeiten auf Allgemeinen Graphen oder einer bestimmten Klasse von Graphen? - Einfache ungerichtete Graphen. e sollte sein |E|, wobei E die Menge von Kanten.
- Check diese Antwort auf CS die sich mit Ihrer Frage, Sie haben im Grunde eine all-pairs-shortest-paths und wählen Sie das minimum über diese, was bedeutet, dass es nach dem Stand der Kunst von der Suche nach kürzesten Entfernungen in Allgemeinen gewichteten Graphen, den Sie nicht unter O(n2 log n + nm) mit Johnson ' s Algorithmus.
- dass es mentiones Johnson ' s Algorithmus ( en.wikipedia.org/wiki/Johnson%27s_algorithm ), die für nicht-negative edge-GEWICHTE, läuft darauf hinaus, Dijkstra in einer Schleife.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Für einen Allgemeinen Graphen
G=(V,E)
es gibt keineO(log V * (V + E))
Zeitkomplexität Algorithmus bekannt, der für die Berechnung des Durchmessers.Die derzeit beste Lösung ist
O(V*V*V)
, z.B. durch die Berechnung aller kürzesten Pfade-Floyd-Warshall-Algorithmus.Für spärliche Graphen, d.h. wenn
E
ist ino(N*N)
Johnson ' s Algorithmus gibt Sie mitO(V*V*log(V)+V*E)
eine bessere Zeit-Komplexität.Wenn Ihr graph hat bestimmte Eigenschaften wie azyklische (Baum), die Sie sich besser.
Also die schlechte Nachricht ist, dass der Dijkstra nicht genug, im Allgemeinen Fall...
Ich weiß, ich bin ein Jahr zu spät auf den thread, aber ich glaube nicht, dass diese Angaben korrekt sind. OP erwähnt in den Kommentaren, dass die Kanten nicht gewichtet; in diesem Fall, den besten Algorithmus läuft in $O(n^{\omega}) \log n$ Zeit (wobei $\omega$ ist der exponent für die matrix-Multiplikation; derzeit oben begrenzt auf $2.373$ von Virginia Williams).
Der Algorithmus nutzt folgende Eigenschaft der ungewichtete Graphen. Sei $A$ die matrix des angrenzens der graph mit einer zusätzlichen selbst-Schleife für jeden Knoten. Dann ist $(A^k)_{ij}$ ist nicht null, iff $d(i, j) \le k$. Wir können diese Tatsache nutzen, um zu finden Sie die Grafik Durchmesser von EDV $\log n$ die Werte von $A^k$.
Hier ist, wie der Algorithmus funktioniert: sei $A$ die matrix des angrenzens der graph mit einer zusätzlichen selbst-Schleife für jeden Knoten. Set $M_0 = A$. Während $M_k$ enthält mindestens eine null ist, berechne $M_{k+1} = M_{k}^2$.
Schließlich finden Sie eine matrix $M_{K}$ mit allen von null verschiedenen Einträge. Wir wissen, dass $K \le \log n$ durch die Eigenschaft oben besprochen; deshalb haben wir durchgeführt-matrix-Multiplikation nur $O(\log n)$ - mal so viel. Wir können jetzt fortfahren, indem Sie die binäre Suche zwischen $M_{K} = A^{2^K}$ und $M_{K-1} = A^{2^{K-1}}$. Set $B = M_{K-1}$ wie folgt.
Set DURCHMESSER = $2^{k-1}$. Für $i = (K-2 \dots, 0)$, führen Sie den folgenden test:
Multiplizieren $B$ durch $M_{i}$ und prüfen Sie die sich ergebenden matrix mit Nullen. Wenn wir alle Nullen sind, dann setzen $B$ um diese matrix-Produkt, und fügen Sie $2^i$ DURCHMESSER. Ansonsten, nichts tun.
Schließlich, Rückkehr DURCHMESSER.
Als ein unbedeutendes detail, ist es möglicherweise notwendig, um alle von null verschiedenen Einträge in einer matrix zu $1$ nach jeder matrix-Multiplikation durchgeführt, so dass die Werte nicht zu groß und unhandlich zu notieren, in eine kleine Menge von Zeit.
Boost BGL hat einen kleinen verlängerten deque Klasse mit dem Namen "rcm_queue", mit der die Exzentrizität eines Knotens kann durch eine einfache Breite-zuerst-Suche, also eine Komplexität von O(E).
http://www.boost.org/doc/libs/1_54_0/boost/graph/detail/sparse_ordering.hpp
Als der Durchmesser berechnet werden kann, indem die Exzentrizität aller Knoten, kann man die Berechnung der Durchmesser eines Graphen mit einer Komplexität von O(V*E).
Insbesondere für eine sehr spärliche Grafik mit deg(G) <<< V, ich habe nichts gefunden, mit besserer Laufzeit.
Ich schaue nicht in den Floyd-Warshall-Algorithmus. Ich war nur der Umgang mit einem Diagramm, das mit > 5.000.000 Eckpunkte aber mit einem höchsten Grad an jeder Ecke für weniger als 15 und gedacht, das sollte wohl übertreffen, ein Algorithmus mit V*V*log(V) Komplexität.
BEARBEITEN
Sicher, das funktioniert nur mit ein ungerichteter graph und nicht-negativ gewichtet (oder noch unbewertet nur? Ich bin mir nicht sicher atm)
Als eci erwähnt, eine der Lösungen ist die Verwendung des Algorithmus von Floyd und Warshall. Wenn Sie den code für eine C++ - version davon gefunden werden kann hier.
Zuerst müssen Sie finden die konvexe Hülle des Graphen (Suche nach es die ist O(nh), wo h die Zahl der Knoten auf Rumpf). Die Punkte der Durchmesser liegen auf der konvexen Hülle und somit ist das problem reduziert auf das finden der am weitesten Punkte in der h-Punkte. Daher, gesamte Bestellung wird O(nh+h*h).
Eigentlich, wenn das Diagramm sehr groß ist, werden Sie brauchen, um den Dijkstra-Algorithmus zum finden der kürzesten Entfernung. Also es hängt davon ab, wie viele Knoten die OP ' s graph.
Unter der Annahme, dass der graph unbewertet dann können die folgenden Schritte finden Sie die Lösung in O(V * ( V + E), wobei V die Anzahl der Knoten und E die Anzahl der Kanten ist.
Definieren wir den Abstand zwischen 2 vertices u, v die Länge des kürzesten Pfades zwischen u und V Bezeichnen es mit d(u, v)
Definieren Exzentrizität eines Knotens v zu e(v) = max {d(u, v) | u ∈ V(G)} (V(G) ist die Menge der Knoten in graph G)
Definieren Durchmesser(G) = max{e(v) | v ∈ V(G)}
Nun an den Algorithmus:
1 - Für jeden Knoten v in V(G) ausführen BFS(v) und bauen ein 2-dimensionales array von Entfernungen von jedem Knoten zum anderen.
(Berechnung der Distanz von jedem Knoten zu anderen ist einfach zu tun, in der BFS-Algorithmus)
2 - Berechnen Sie e(v) für jeden Scheitelpunkt aus der 2 dimensionalen array in Schritt 1 erstellt haben
3 - berechnen Sie den Durchmesser(G) finden Sie den maximum e(v) aus Schritt 2
Nun zu analysieren, die diesem Algorithmus ist es leicht zu sehen, dass es dominiert der erste Schritt ist O (V * (V + E))
Lesen Sie diesen Teil über Durchmesser in der Wikipedia
Einen anderen Algorithmus läuft in linearer Zeit O(V + E)
1 - Führen Sie das BFS auf beliebigen Knoten v ∈ V(G)
2 - Wählen Sie den Eckpunkt u mit maximaler Distanz
3 - Führen Sie das BFS wieder auf, dass die vertex u
4 - Durchmesser ist die maximale Distanz generiert, form Schritt 3
Graph Beschreibung - ungerichtete und ungewichtete, n Knoten m Kanten
Für den Durchmesser des Graphen, müssen wir berechnen den kürzesten Weg zwischen allen Paaren von Knoten. Kürzeste Wege zwischen einem Quellknoten zu allen anderen Knoten berechnet werden kann mithilfe der BFS-Algorithmus für eine ungerichtete und ungewichtete Graphen. Time Komplexität ist O(n + m) für 1 Knoten. Hier, da müssen wir eine BFS für n Knoten, die Gesamtzeit, die Komplexität des Findens des kürzesten Weges zwischen allen Paaren von Knoten wird O(n(n + m)). Da gibt es n(n-1)/2 Paaren von Knoten, so haben wir n(n-1)/2 Werte der kürzeste Pfad zwischen den Knoten. Für den Durchmesser, die wir brauchen, um die max, diese Werte, das ist wieder O(n*n). Also die Letzte Zeit Komplexität wird:
Pseudocode für immer die kürzesten Wege zwischen allen Paaren von Knoten. Wir verwenden eine matrix namens Shortest_paths speichern, um die kürzesten Pfade zwischen zwei beliebigen paar von Knoten. Wir sind eine Wörterbuch-namens flag die Werte true oder false gibt an, ob die Knoten besucht wurde oder nicht. Für jede iteration des BFS, initialisieren wir das Wörterbuch, um alle falsch. Benutzen wir eine Queue Q zur Ausführung unserer BFS.
Algorithmus BFS(für alle Knoten)
Dies kann nur passieren, mit einem ungewichteten Graphen. Wo bfs gibt shortest path tree in o(v+e) und wiederholen Sie das gleiche für v-Quellen.