Route Existenz zwischen n Knotenpaaren


8

Wie kann man bei einem gerichteten azyklischen Graphen mit Knoten bestimmen, ob es einen Pfad zwischen einem der folgenden n Knotenpaare gibt ? Es gibt einen einfachen Algorithmus in (wobei m die Anzahl der Kanten ist), indem von jedem Knoten gesucht wird , aber kann es besser gemacht werden?( 1 n + 1 ) , , ( n n + n ) O ( n ( n + m ) ) 1 n2n(1n+1),,(nn+n)O(n(n+m))1n

EDIT: Ich suche Existenz, nicht vollständige Pfade.


Es ist nicht ganz klar, was Sie fragen. Suchen Sie einen einzelnen Pfad mit den von Ihnen genannten Kanten? Oder suchen Sie mehrere Wege?
Dave Clarke

2
@ Dave: Er sucht nach dem OP eines kleinen Stücks der transitiven Verschlussmatrix.
Radu GRIGore

1
@Alexandru, 1-> 4, 2-> 3. Sie addieren 3-> 1, 4-> 2.
Radu GRIGore

6
Sie können den transitiven Abschluss über eine schnelle Matrixmultiplikation berechnen, die besser wäre als die O (nm) -Zeit, wenn m groß ist.
Chandra Chekuri

4
@alexandru: Das ist aber nicht das, was deine Frage gestellt hat, um fair zu sein. Sie haben nach einer schnelleren, nicht praktischen Implementierung gefragt (was eine gültige, aber separate Frage ist)
Suresh Venkat

Antworten:


5

Wie Chandra Chekuri in einem Kommentar betonte, könnten Sie den transitiven Abschluss einfach durch schnelle Matrixmultiplikation berechnen und das Problem in O ( ) (verwenden Sie Ihre Lieblingsmethode, O ( ) über Coppersmith und Winograd oder praktischer mit Straßens O ( )), und dies wäre gut für dichte Graphen.n 2,376 n 2,81nωn2.376n2.81

Nun behaupte ich, wenn Sie diese Laufzeit für Ihr Problem für dichte Graphen übertreffen könnten, würden Sie einen Algorithmus für die Dreieckserkennung erhalten, der effizienter ist als die Berechnung des Produkts zweier Boolescher Matrizen. Die Existenz eines solchen Algorithmus ist ein großes offenes Problem.

Ich werde das Dreiecksproblem auf das Problem der Erreichbarkeit von n-Paaren-DAG reduzieren. Angenommen, wir erhalten einen Graphen G auf n Knoten und möchten bestimmen, ob G ein Dreieck enthält.

Erstellen Sie nun aus G eine DAG G 'wie folgt. Erstellen Sie vier Kopien der Scheitelpunktmenge , V 2 , V 3 , V 4 . Fügen Sie für Kopien u iV i , v i + 1V i + 1 für i = 1 , 2 , 3 eine Kante ( u i , v i + 1 ) hinzu, wenn ( u , v )V1V2V3V4uiVivi+1Vi+1i=1,2,3(ui,vi+1)(u,v)war in G. Wenn wir nun fragen, ob es einen Pfad zwischen einem der Paare für alle u G gibt, dann würde dies genau fragen, ob es in G ein Dreieck gibt . Der aktuelle Graph hat 4 n Knoten und wir fragen nach n Paaren. Wir können jedoch 2 n isolierte Dummy-Knoten hinzufügen und stattdessen 3 n Abfragen haben (indem wir eine Abfrage für 2 n verschiedene Paare ( y , d ) hinzufügen , wobei y V 2 ist(u1,u4)uG4nn2n3n2n(y,d) und d ein Dummy), wodurch eine 6 n- Knoten-Instanz genau Ihres Problems erhalten wird.yV2V3d6n


0

Die topologische Sortierung ( ) arbeitet dann daran, ein Bit-Set von Knoten zu verbreiten, von denen aus jeder Knoten erreicht werden kann ( O ( m n ) ).O(m+n)O(mn)

Nach der topologische Sortierung können Sie tun , Schnell Ablehnung (wenn der Knoten n + x , bevor der Knoten kommt x in der Art , dann gibt es keinen Weg von x nach n + x ).O(n)n+xxxn+x


Das scheint mir nicht wirklich schneller zu sein. Wenn , könnte der Algorithmus der Frage einfach eine einfache Vorverarbeitung durchführen und NEIN beantworten, wenn es einen isolierten Scheitelpunkt gibt. m=o(n)
Serge Gaspers

1
Wie ist das besser als mein grundlegender Algorithmus?
Alexandru

@Alexandru, ich denke es ist etwas besser, weil es Bits packt. Das heißt, es ist wobei w die Wortbreite ist. Es ist nicht klar, ob Sie sich für solche Verbesserungen interessieren. O((m+n)n/w)w
Radu GRIGore

Es ist ein Kompromiss: Sie verwenden O (n * n / w) zusätzlichen Speicher anstelle von O (n).
Alexandru

@Alexandru, asymptotisch im schlimmsten Fall ist es dasselbe, aber die Analyse des Durchschnittsfalls ist schwierig und was besser ist, hängt möglicherweise von der Statistik der erwarteten Diagrammstruktur ab.
Peter Taylor

0

O(N2)

yespath = array(1..N)       // output of the algorithm
                            // initially filled with false
processed = array(1..N)     // processed nodes

// HEURISTIC 1: some preprocessing
for every node u in 1..N
  if (no outbound edges from u) then processed[u] = true
  if (no inbound edges to u+N) then processed[u] = true

for each node u in [1..N]    // MAIN loop 
  if (not processed[u]) then
    collected = [u]          // a list that initially contains u
    visited = array(1..2*N)  // filled with zeroes        
    do a breadth first scan from u
       for each node v found in the search
         set visited[v] = distance from u
         if (v <= N) then add v to collected
    end do

    // HEURISTIC 2: useful collected info on other nodes <= N
    foreach node v in collected
      processed[v] = true
      if ( visited[ v + N ] > 0 and visited[v] < visited[v+N] ) then yespath[v] = true
    end foreach

  end if
end for // MAIN loop


O(N2)O(Nk)e>u+N

Andere Heuristiken können hinzugefügt werden, aber ihre Effizienz (und Effizienz der drei vorgeschlagenen) hängt stark von der Graphstruktur ab.

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.