Die Tatsache, dass unser Graph azyklisch ist, macht dieses Problem viel einfacher.
Topologische Sortierung kann uns eine Reihenfolge der Eckpunkte so dass, wenn i < j ist , es keine Kante von v j zurück zu v i gibt . Wir haben die Eckpunkte so aufgelistet, dass alle Kanten in unserer Liste "vorwärts" gehen.v1,v2,…,vni<jvjvi
(bearbeitet, um die Analyse zu korrigieren und einen etwas schnelleren Algorithmus zu liefern)
Jetzt gehen wir diese Liste einfach rückwärts durch, beginnend mit dem letzten Scheitelpunkt . v n 's transitiver Abschluss ist nur sich selbst. Addiere auch v n zum transitiven Abschluss jedes Scheitelpunkts mit einer Kante zu v n .vnvnvnvn
Für jeden anderen Eckpunkt , das Ende nach hinten gehen, ersten Add v i auf seine eigenen transitiven Schließung, dann ist alles in der transitiven Hülle hinzufügen v i auf die transitive Schließung aller Ecken mit Ecken und Kanten v i .vivivivi
Die Laufzeit ist im ungünstigsten Fall , wobei n die Anzahl der Eckpunkte und m ∈ O ( n 2 ) die Anzahl der Kanten ist. Die topologische Sortierung benötigt die Zeit O ( n + m ) . Dann machen wir eine weitere O ( m n ) -Arbeit im Rückwärtsdurchlauf: Wenn wir die Liste rückwärts durchgehen, müssen wir für jede Kante n addierenO(n+m+nm)=O(n3)nm∈O(n2)O(n+m)O(mn)n Eckpunkte zu jemandes transitiven Schließung.
Beachten Sie, dass Sie eine schöne Beschleunigung des konstanten Faktors erzielen können, indem Sie die transitive Schließung aller durch Bit-Arrays darstellen. Angenommen, Sie hatten nur ; Dann würden Sie eine einzelne 64-Bit-Ganzzahl verwenden, wobei Bit i 1 ist, wenn ich in meinem transitiven Abschluss bin, und sonst 0. Dann ist der Teil, in dem wir alles in i 's transitiven Abschluss zu j ' s hinzufügen, sehr schnell: Wir nehmen einfach c j | = c i . (Binär-ODER-Operation.)n=64iiijcjci
Für müssten Sie sie in Arrays belassen und ein wenig rechnen, aber es wäre viel schneller als ein Objektsatz.n>64
OO(n3)