Algorithmus, der die Anzahl der einfachen Pfade von


34

G=(V,E)ststG
tp V p o s z o r s V s r r y y v v w zstWenn dies der Unterpfad eines anderen Pfads ist, durchläuft auch DFS diesen Unterpfad erneut. Betrachten Sie beispielsweise die Adjazenzliste, in der die Anzahl der Pfade von nach . Hier beginnt DFS mit und geht dann beispielsweise zu da es nicht auf stößt. DFS wird normal ausgeführt path ist da es auf trifft. Wir werden die Farbe der Eckpunkte in grau ändern .pv
ppzvpsryvvs,r,y,vpovvposryvsporyvv

poszorsvsrryyvvwzwz
ppzvpsryvvs,r,y,vpov da die Farbe von immer noch weiß ist. Dann ist der Pfad da die Farbe von weiß ist und ähnlich wie der Pfad Außerdem wird ein Zähler verwaltet, der inkrementiert wird, wenn angetroffen wird.vposryvsporyvv

Ist mein Algorithmus korrekt? Wenn nicht, werden die Änderungen, die erforderlich sind, um es zu korrigieren, oder andere Ansätze sehr geschätzt.

Hinweis : Hier habe ich den DFS-Algorithmus in dem Buch "Einführung in die Algorithmen von Cormen" betrachtet, in dem die Knoten gemäß ihrem Status gefärbt werden. Wenn der Knoten nicht besucht, nicht erkundet und erkundet wird, ist die Farbe weiß. grau und schwarz. Alle anderen Dinge sind Standard.



4
Beachten Sie, dass alle Pfade in einem gerichteten azyklischen Graphen (aufgrund der Azyklizität) notwendigerweise einfach sind .
Noldorin

Antworten:


37

Ihre aktuelle Implementierung berechnet die richtige Anzahl von Pfaden in einer DAG. Wenn Sie jedoch keine Pfade markieren, dauert dies exponentiell lange. In der folgenden Abbildung erhöht beispielsweise jede Stufe der DAG die Gesamtzahl der Pfade um ein Vielfaches von 3. Dieses exponentielle Wachstum kann mit dynamischer Programmierung bewältigt werden.

dag

Die Berechnung der Anzahl der - - Pfade in einer DAG ergibt sich aus der Wiederholung: t Pfade ( u ) = { 1, wenn  u = t ( u , v ) E Pfade ( v ) ansonsten.st

Paths(u)={1if u=t(u,v)EPaths(v)otherwise.

Eine einfache Modifikation von DFS berechnet dies als

def dfs(u, t):
    if u == t:
        return 1
    else:
        if not u.npaths:
            # assume sum returns 0 if u has no children
            u.npaths = sum(dfs(c, t) for c in u.children)
        return u.npaths

Es ist nicht schwer zu erkennen, dass jede Kante nur einmal betrachtet wird, daher eine Laufzeit von .O(V+E)


Ich habe Ihren Algorithmus verstanden und er kann mit dynamischer Programmierung kaum effizienter gestaltet werden, da dieselben rekursiven Aufrufe oft aufgerufen werden, sodass es besser ist, sie zu speichern. Richtig?
Saurabh

1
@ SaurabhHota, es verwendet dynamische Programmierung. Wenn der Eckpunkt ersten Mal angetroffen wird, berechnet er die Anzahl der Pfade, die er zu . Dies wird in u.npaths gespeichert. Jeder nachfolgende Aufruf von berechnet nicht die Anzahl der Pfade neu, sondern gibt einfach u.npaths zurück. t uutu
Nicholas Mancuso

1
Für solche Graphen ist die Antwort nicht nur m ^ n, wobei m die Anzahl der Knoten in einer Spalte ist (3 hier) und n die Anzahl der Spalten ohne s, t (4 hier). Ausgabe ist 3 ^ 4 = 81 für das Beispieldiagramm.
Saadtaame

@saadtaame, sicher; Meine Absicht war es jedoch, nur eine exponentielle Zunahme zu demonstrieren, wenn die "Länge" eines Graphen wächst. Natürlich können Sie für dieses stark strukturierte Diagramm in geschlossener Form zählen, während der aufgeführte Algorithmus für alle Diagramme funktioniert.
Nicholas Mancuso

3
O(V+E)Θ(V)O(VE)

15

Sie müssen nur beachten, dass die Anzahl der Pfade von einem Knoten zum Zielknoten die Summe der Anzahl der Pfade von den untergeordneten Knoten zum Ziel ist. Sie wissen, dass dieser Algorithmus immer anhält, da Ihr Diagramm keine Zyklen aufweist.

Wenn Sie jetzt die Anzahl der Pfade von einem Knoten zum Ziel speichern, während Sie die Knoten besuchen, wird die Zeitkomplexität linear in der Anzahl der Scheitelpunkte und der Speicher linear in der Anzahl der Knoten.


0

Die Anzahl der Pfade zwischen zwei beliebigen Eckpunkten in einer DAG kann unter Verwendung der Adjazenzmatrixdarstellung ermittelt werden.

Angenommen, A ist die Adjazenzmatrix von G. Wenn man die K-te Potenz von A nach der Addition der Identitätsmatrix nimmt, erhält man die Anzahl der Pfade mit einer Länge <= K.

Da die maximale Länge eines einfachen Pfades in einer DAG | V | -1 ist, würde die Berechnung der | V | -1-ten Potenz die Anzahl der Pfade zwischen allen Knotenpaaren ergeben.

Die Berechnung der | V | -1-ten Potenz kann durchgeführt werden, indem log (| V | -1) -Multiplikationen von TC: | V | ^ 2 durchgeführt werden.


Die Frage fragt nach einem linearen Zeitalgorithmus. Ihr Algorithmus ist langsamer als das.
DW

@Vivek kannst du in deiner Antwort eine Referenz für die Theoreme nennen?
Hamideh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.