Welche Klassen von Datenstrukturen können persistent gemacht werden?

19

Persistente Datenstrukturen sind unveränderliche Datenstrukturen. Operationen auf ihnen geben eine neue "Kopie" der Datenstruktur zurück, die jedoch durch die Operation geändert wurde. Die alte Datenstruktur bleibt jedoch unverändert. Effizienz wird im Allgemeinen dadurch erreicht, dass einige der zugrunde liegenden Daten gemeinsam genutzt werden und ein vollständiges Kopieren der Datenstruktur vermieden wird.

Fragen:

  • Gibt es Ergebnisse zu Datenstrukturklassen, die persistent gemacht werden können (bei gleichbleibender oder sehr ähnlicher Komplexität)?

  • Können alle Datenstrukturen persistent gemacht werden (unter Beibehaltung der gleichen oder sehr ähnlichen Komplexität)?

  • Können Datenstrukturen bekanntermaßen nicht persistent gemacht werden (bei gleicher oder sehr ähnlicher Komplexität)?

Realz Slaw
quelle
1
Sie können einen Vektor für den Zugriff auf ein zufälliges Element nicht dauerhaft machen, wenn die Komplexität von O (1) erhalten bleibt.
Smossen
2
@smossen kannst du das beweisen?
Realz Slaw
1
Ihre erste Frage ist eine sehr breite Frage. Es gibt viele Ergebnisse zum Thema Datenstrukturen, die persistent gemacht werden können. Man könnte ein ganzes Buch zu diesem Thema schreiben, und einige Leute haben es: Zum Beispiel ist Okasakis Buch ein Klassiker zu diesem Thema. Haben Sie zu diesem Thema recherchiert? Können Sie die Frage eingrenzen? Ich vermute, dass es zu breit ist, um zu dieser Site zu passen. Vielleicht die 3. Frage in eine separate Frage aufteilen?
DW
@ Realz Slaw: Ich kann es formal nicht beweisen, aber ich denke, es ist gesunder Menschenverstand. O (1) Der Zugriff auf Elemente in Vektoren (einschließlich Hash-Tabellen) hängt von einer festen Zeit für die Adressdecodierung auf einer bestimmten Hardware ab. Durch die Persistenz werden zusätzlich zum Vektorindex ein oder zwei Dimensionen hinzugefügt. Hardwareadressen sind jedoch immer noch eindimensional.
Smossen

Antworten:

22

Positives Ergebnis: Beharrlichkeit kostet nicht zu viel. Man kann zeigen, dass jede Datenstruktur mit höchstens einer Verlangsamung von vollständig persistent gemacht werden kann .O(lgn)

Beweis: Sie können ein Array mit Hilfe von Standarddatenstrukturen (z. B. einem ausgeglichenen Binärbaum; weitere Informationen finden Sie am Ende dieser Antwort) dauerhaft machen. Dies verursacht eine Verlangsamung: jeder Array - Zugriff nimmt O ( lg n ) Zeit mit der persistenten Datenstruktur, anstelle von O ( 1 ) Zeit für den nicht-persistente - Array. Nehmen wir nun einen beliebigen zwingenden Algorithmus, dessen Laufzeit im RAM-Modell O ( f ( n ) ) ist , wobei n die Menge des verwendeten Speichers bezeichnet. Stellen Sie den gesamten Speicher als ein großes Array dar (mitO(lgn)O(lgn)O(1)O(f(n))n Elemente), und machen Sie es mit einer persistenten Karte persistent. Jeder Schritt des imperativen Algorithmus führt zu höchstens einerVerlangsamung von O ( lg n ) , sodass die Gesamtlaufzeit O ( f ( n ) lg n ) beträgt.nO(lgn)O(f(n)lgn)

Anscheinend ist es möglich, es ein bisschen besser zu machen: Anscheinend kann man den Verlangsamungsfaktor auf (erwartete, abgeschriebene Zeit) reduzieren , indem man die Techniken aus dem unten genannten Demaine-Papier verwendet - aber ich kenne die Details nicht von dieser Arbeit, so kann ich nicht selbst dafür bürgen. Vielen Dank an jbapple für diese Beobachtung.O(lglgn)


Negatives Ergebnis: Bei einigen Datenstrukturen können Sie eine gewisse Verlangsamung nicht vermeiden. Zur Beantwortung Ihrer dritten Frage gibt es Datenstrukturen, bei denen bekannt ist, dass die Persistenz zu einer gewissen Verlangsamung führt.

nO(1)O(1)Ω(lglgn)

Die Untergrenze wird Mihai Patrascu zugeschrieben, aber es gibt kein Zitat zu einer Quelle, die die Details des Beweises dieser behaupteten Untergrenze angibt.


O(1)

Es besteht auch ein enger Zusammenhang mit funktionalen Programmiersprachen. Insbesondere ist jede Datenstruktur, die rein funktional (ohne Mutationen) implementiert werden kann, bereits eine persistente Datenstruktur. (Das Gegenteil ist leider nicht unbedingt der Fall.) Wenn Sie die Augen zusammenknicken möchten, könnten Sie dies als eine Art schwachen Teilklassifikationssatz ansehen: Wenn er in einer rein funktionalen Programmiersprache mit denselben Zeitgrenzen wie in implementiert werden kann eine imperative Sprache, dann gibt es eine persistente Datenstruktur mit den gleichen Zeitgrenzen wie die nicht persistente. Mir ist klar, dass dies wahrscheinlich nicht das ist, wonach Sie gesucht haben - es ist meistens nur eine triviale Umformulierung der Situation.


O(lgn)

dd

nO(lgn)O(lgn)O(lgn)

Weitere Erklärungen mit schönen Bildern finden Sie in den folgenden Quellen:

Das gibt Ihnen die Hauptidee. Es gibt zusätzliche Details, um die man sich kümmern muss, aber die Details sind für diese Frage nicht relevant. Glücklicherweise ist dies alles Standard, und in der Literatur finden Sie viele Informationen zum Aufbau solcher Datenstrukturen. Sie können auch eine separate Frage stellen, wenn die oben genannten Ressourcen nicht ausreichen und Sie weitere Informationen zum Erstellen einer persistenten Array-Datenstruktur benötigen.

DW
quelle
Ich verstehe den ersten Absatz nicht wirklich. Wie würde ich vorgehen, um ein Array unter Verwendung eines rot-schwarzen Baums persistent zu machen?
G. Bach
@ G.Bach, es gibt eine ziemlich gute Erklärung in den Abschnitten "Binäre Suchbäume" und "Strukturen mit wahlfreiem Zugriff" (speziell die Baummethode) unter toves.org/books/persist/index.html . Eine weitere Beschreibung finden Sie unter netcode.ru/dotnet/?artID=6592#BinaryTrees und in den folgenden Abschnitten. Das gibt Ihnen die Hauptidee. Die Details sind für diese Frage nicht in Betracht zu ziehen, aber das ist alles Standardmaterial. Ich empfehle Ihnen, eine separate Frage zu stellen, wenn Sie weitere Informationen zum Erstellen einer solchen Datenstruktur benötigen.
DW
4
O(lglgn)