Stellen Sie sich einen gerichteten Graphen in dem Sie dynamisch Kanten hinzufügen und bestimmte Abfragen durchführen können.
Beispiel: disjunkte Gesamtstruktur
Betrachten Sie die folgenden Abfragen:
arrow(u, v)
equiv(u, v)
find(u)
der erste fügt dem Graphen einen Pfeil hinzu , der zweite entscheidet, ob , der letzte findet einen kanonischen Vertreter der Äquivalenzklasse von , dh a so dass impliziert .
Es gibt einen bekannten Algorithmus, der die disjunkt gesetzte Walddatenstruktur verwendet, die diese Abfragen in quasikonstanter amortisierter Komplexität implementiert, nämlich . Beachten Sie, dass in diesem Fall mit implementiert wird .equiv
find
Komplexere Variante
Jetzt interessiert mich ein komplexeres Problem, bei dem die Anweisungen eine Rolle spielen:
arrow(u, v)
confl(u, v)
find(u)
Der erste fügt einen Pfeil , der zweite entscheidet, ob es einen Knoten w gibt, der sowohl von u als auch von v aus erreichbar ist , dh u → ∗ ← ∗ v . Der letzte sollte ein Objekt r ( u ) zurückgeben, so dass u → ∗ ← ∗ v r ( u ) ∙ r ( v ) impliziert, wobei ∙ leicht berechenbar sein sollte. (Um beispielsweise zu berechnenconfl
). Ziel ist es, eine gute Datenstruktur zu finden, damit diese Operationen schnell sind.
Fahrräder
Das Diagramm kann Zyklen enthalten.
Ich weiß nicht, ob es eine Möglichkeit gibt, die stark verbundenen Komponenten effizient und inkrementell zu berechnen, um nur DAGs für das Hauptproblem zu berücksichtigen.
Natürlich würde ich mich auch über eine Lösung für DAGs freuen. Dies würde einer inkrementellen Berechnung des am wenigsten verbreiteten Vorfahren entsprechen.
Naiver Ansatz
Die disjunkt gesetzte Gesamtstrukturdatenstruktur ist hier nicht hilfreich, da die Richtung der Kanten nicht berücksichtigt wird. Beachten Sie, dass kein einzelner Knoten sein kann, falls der Graph nicht konfluent ist.
Man kann definieren und definieren ∙ als S 1 ∙ S 2 , wenn S 1 ∩ S 2 & ne; ∅ . Aber wie berechnet man das inkrementell?
Wahrscheinlich ist die Berechnung einer so großen Menge nicht sinnvoll, eine kleinere Menge sollte interessanter sein, wie beim üblichen Algorithmus zum Finden von Vereinigungen.
confl(u,v)
should mergefind
, like in the disjoint-set forest method.find
really can't compute anything useful, because there is no unique object to "find" exceptfind
know what to look for, to make updates? It is only given