Gibt es eine Prioritätswarteschlange mit


46

Es gibt sehr viele Datenstrukturen, die die Priority-Queue-Schnittstelle implementieren:

  • Einfügen: Fügt ein Element in die Struktur ein
  • Get-Min: Gibt das kleinste Element in der Struktur zurück
  • Extract-Min: Entfernt das kleinste Element in der Struktur

Übliche Datenstrukturen, die diese Schnittstelle implementieren, sind (min) Heaps .

Normalerweise betragen die (amortisierten) Laufzeiten dieser Vorgänge:

  • Einfügen: (manchmal O ( log n ) )O(1)O(logn)
  • Get-Min: O(1)
  • Extrakt-Min: O(logn)

Der Fibonacci-Heap erreicht beispielsweise diese Laufzeiten. Nun ist meine Frage die folgende:

Gibt es eine Datenstruktur mit folgenden (amortisierten) Laufzeiten?

  • Einfügen: O(logn)
  • Get-Min: O(1)
  • Auszug-Min: O(1)

Wenn wir bei sortierter Eingabe eine solche Struktur in -Zeit aufbauen können, können wir zum Beispiel Linienschnittpunkte auf vorsortierten Eingaben mit o ( n) findenO(n)Kreuzungen sind strikt schneller als wenn wir die 'üblichen' Prioritätswarteschlangen verwenden.o(nlogn)


Ich denke , dass die Verwendung eines ausgeglichenen BST, das bei der Ausführung von Extract-Min nicht ausgeglichen werden kann, funktionieren könnte. Oder vielleicht eine überspringende Liste.
Svick

@svick: Überspringlisten sind zufällig, was ich nicht suche. Wenn Sie es mit einem BST schaffen, dann ist das großartig, aber ich denke, Sie müssen eine Art Balancing machen.
Alex ten Brink

Nebenbei bemerkt: Dies ist eine Seeding-Frage, und ich kenne die Antwort, aber es ist schön zu sehen, dass sie nicht so einfach zu lösen ist. Wenn jemand die Antwort kennt, zögern Sie nicht, sie zu geben :)
Alex ten Brink

Wenn Sie amortisierte Aktualisierungszeiten akzeptieren, können Sie Ihre Standard-Heap-Strukturen beibehalten und nur geringfügige Änderungen an Ihrer Analyse vornehmen. Siehe meine Antwort unten.
Joe

Antworten:


27

Unsere Idee ist es, mit Gewinde versehene Spreizbäume zu verwenden . Anders als im Wikipedia-Artikel werden wir die Bäume so fädeln, dass jeder Knoten einen Zeiger nextauf seinen Nachfolger in der Durchquerung in der richtigen Reihenfolge hat. Wir halten auch einen Zeiger startauf das kleinste Element im Baum.

Es ist leicht zu erkennen, dass das Extrahieren des kleinsten Elements in der (schlimmsten) Zeit : Folgen Sie einfach dem Zeiger, entfernen Sie das Minimum und ändern Sie den Zeiger auf das Minimum . Das Minimum kann niemals ein verlassenes Kind haben; Wenn es ein richtiges Kind hat, setzen wir es an die Stelle des Minimums im Baum. Wir führen nicht die Spreizoperation durch, die Spreizbäume normalerweise ausführen würden. Das Ergebnis ist ein noch recht ausgeglichener Suchbaum: Da wir nur die Knoten an der linken Flanke entfernen, wissen wir, dass bei einer Verringerung der Anzahl der Knoten (in einem betroffenen Teilbaum) aufgrund von Löschungen die Zahl (sub ) Die Höhe des Baumes wird um eins verringert.O(1)startnext

Einfügungen sind in amortisierter Zeit möglich; Die Zick-Zack-Operationen (und was nicht) bringen auch hier den Baum wieder ins Gleichgewicht.O(logn)

Dies ist bestenfalls eine grobe Skizze. Dank geht an F. Weinberg, der mit mir und unserem Berater M. Nebel, der Spreizbäume erwähnte, über die einzige Baumvariante nachgedacht hat, die wir nicht ausprobiert hatten.


2
Mir ist nicht klar, wie ich die amortisierte Analyse zum Laufen bringen kann, wenn Sie nicht auf extractMin spielen. Können Sie einen Hinweis geben?
Jbapple

Wir haben es nicht im Detail gemacht. Die Idee ist, dass eine Reihe von Extrakt-Min-Operationen den Baum nicht aus dem Gleichgewicht bringt, daher ist kein Spreizen erforderlich und die normale Analyse sollte für Einfügungen funktionieren.
Raphael

9
Vorsichtig! Spreizbäume sind nicht unbedingt ausgewogen. Knoten, auf die lange Zeit nicht zugegriffen wurde, befinden sich möglicherweise sehr tief in der Struktur. Um die Analyse durchlaufen zu lassen, müssen Sie sich mit der gleichen potenziellen Funktion auseinandersetzen, die für die Analyse von Splays verwendet wird.
JeffE

20
  • Einfügen: O(logn)
  • Get-Min: O(1)
  • Auszug-Min: O(1)

Amortisierte Zeit

cnlognO(logn)O(logn)Ω(logn)O(1)

Schlimmsten Fall

Sie können eine vorhandene Datenstruktur in der Literatur verwenden: Finger-Suchbäume, und einfach einen Zeiger auf das minimale Element verwalten. Sehen Sie diese Umfrage für einen Überblick, und das 1988 Papier von Levcopoulos und Overmars für eine umsetzbare Version , die Ihren Bedürfnissen entspricht.


1
Wie hinterhältig. Du hast recht, ich denke, ich hätte etwas Stärkeres verlangen sollen, um dies auszuschließen. Gute Idee :)
Alex ten Brink

O(1)

14

O(1)O(1)

O(1)

O(1)


8

Auf Anfrage, hier ist die Struktur, die ich gefunden habe, nachdem ich die Frage formuliert habe:

Die Grundidee besteht darin, einen mit einem Thread versehenen Sündenbockbaum zusammen mit einem Zeiger auf das Minimum (und zum guten Teil auch auf das Maximum) zu verwenden. Eine einfachere Alternative zum Threading besteht darin, in jedem Knoten Vorgänger- und Nachfolgerzeiger zu verwalten (was äquivalent, einfacher, aber mit mehr Aufwand verbunden ist). Ich bin gekommen , es ist ein Sündenbock zu nennen Haufen , nur um es zu geben , einen Namen.

Gerade diese Grundstruktur gibt Ihnen diese Operationen:

  • O(logn)
  • O(logn)
  • O(1)
  • Get-Min / Max: Gibt den Zeiger auf das Minimum oder Maximum zurück.

O(logn)O(1)O(logn)O(1)O(1)O(1)

  • O(1)

Dies kombinieren:

  • O(1)

Mit Zeigern können Sie ein bisschen mehr anfangen: Beispielsweise ist es nicht schwierig, einen Zeiger auf den Median oder eine andere Ordnungsstatistik zu pflegen, sodass Sie eine konstante Anzahl solcher Zeiger pflegen können, wenn Sie sie benötigen.

Einige andere Dinge:

  • nO(n)
  • O(n)

Und schließlich bin ich mir ziemlich sicher, dass Sie diese Operationen unterstützen können, aber ich muss ein bisschen mehr darüber nachdenken, bevor ich das sicher weiß:

  • O(1)

Die wichtigste Erkenntnis ist, dass Sündenbockbäume Ihnen versichern, dass das Löschen eines Knotens ohne Neuverteilung die Leistung anderer Operationen auf lange Sicht nicht beeinträchtigt, selbst wenn Sie viele Knoten löschen.
Raphael

O(lgn)O(1)O(lgn)

2
O(1)O(1)O(1)O(1)
Alex ten Brink

Ah, ich verstehe jetzt.
Jbapple

2

ϵO(1)log(1/ϵ)ϵ

ϵn

Das originale, klare und gut geschriebene Papier finden Sie unter Bernard Chazelle, The Soft Heap: Eine Warteschlange mit ungefährer Priorität und optimaler Fehlerrate, Journal of the ACM, 47 (6), S. 1012-1027, 2000 . Eine alternative Implementierung und Analyse, die nach SODA'09 einfacher und intuitiver zu sein scheint, finden Sie in Kaplan H. & Zwick U., Eine einfachere Implementierung und Analyse von Chazelles weichen Haufen, 2009 .


Obwohl es sich um eine hochinteressante Datenstruktur handelt, sind weiche Heaps nicht genau: findmin gibt möglicherweise einen Wert zurück, der nicht das Minimum darstellt, sondern lediglich ein ungefähres Minimum darstellt. Trotzdem danke für die Links :)
Alex ten Brink

1
@AlextenBrink: Der Punkt der Datenstruktur (wie bei vielen probabilistischen Algorithmen) ist, dass Sie eine ungefähre Datenstruktur verwenden können, um genaue Antworten zu erhalten. In der Tat verhinderte die ungefähre Natur von weichen Haufen nicht, dass sie in dem einzigen bekannten linearen Zeitalgorithmus für minimale Spannweiten verwendet wurden.
Jérémie,

2

Okay, endlich hast du die Komplexität, nach der du gesucht hast, und was am besten ist, fand ich in der Literatur:

Worst-Case-Komplexität

O(1)

O(1)

O(1)

O(log n)

Referenz

[3]O(1)O(log n)O(n)

Brodal, Gerth Stølting. 'Fast Meldable Priority Queues'. In Proceedings of the 4th International Workshop zu Algorithmen und Datenstrukturen, 282–290. WADS '95. London, UK, UK: Springer-Verlag, 1995.

[3]: Dietz, Paul F und Rajeev Raman. 'Ein Finger-Suchbaum mit konstanter Aktualisierungszeit'. Informationsverarbeitungsbriefe 52, nr. 3 (1994): 147-154.

Dabei wird das RAM- Berechnungsmodell verwendet :

Unsere Datenstruktur verwendet das RAM-Modell (Random Access Machine) mit Maßeinheit und logarithmischer Wortgröße.

In jüngerer Zeit wurde ein Pointer-Machine- Modell einer Berechnungslösung vorgestellt [1].

[1]: Brodal, Gerth Stølting, George Lagogiannis, Christos Makris, Athanasios Tsakalidis und Kostas Tsichlas. "Optimale Fingersuchbäume in der Zeigermaschine". J. Comput. Syst. Sci. 67, nein. 2 (September 2003): 381–418.


2

Annäherung an dieses Problem durch Beibehalten von zwei Datenstrukturen: einem Array und einem Binärbaum.

Ω(lognloglogn)Ω(logn)

O(logn)O(logn)

nullO(logn)

O(1)O(1)

O(logn)O(1)delete_at(idx)


1 Patrascu, Mihai und Erik D. Demaine. "Logarithmische untere Grenzen im Zell-Sonden-Modell". SIAM J. Comput. 35, nein. 4 (April 2006): 932–963. doi: 10.1137 / S0097539705447256.


1
O(logn)

Was bedeutet "Threading eines binären Suchbaums in ein Array"?
Jbapple

@AT: Ich teile das Gefühl von jbapple.
Raphael

Ω(k)kO(1)

Ihr Update, in dem Sie erklären, wie Rotationen in konstanter Zeit implementiert werden, funktioniert nicht in Arrays. Diese Antwort ist immer noch falsch. Das Tarjan-Papier, auf das Sie sich beziehen, handelt von Bäumen, die mit Knoten und Zeigern gespeichert sind.
Jbapple

-2

O(1)O(log log n)

Siehe Artikel 2007: Gleichwertigkeit zwischen Prioritätswarteschlangen und Sortieren nach Mikkel Thorup.

O(n log log n)


Obwohl das von Ihnen verlinkte Papier interessant ist, weist die Prioritätswarteschlange keine ständigen Zeitlöschungen auf (wenn ich das Abstract richtig lese) und ist daher nicht das, wonach ich frage.
Alex ten Brink

-2

Analyse

o(n log log n)

o(log log n)

O(1)

O(n)

O(1)

O(1)

Implementierung

  1. O(1)
  2. O(6)O(1)
  3. k±
    ((k>nsize1)(k<n0)((k<ni)(k>ni+1)))
    o(log log n)

[1]: Andersson, Arne und Christer Mattsson. 'Dynamische Interpolationssuche in O (log log n) Zeit'. In Automata, Languages ​​and Programming, herausgegeben von Andrzej Lingas, Rolf Karlsson und Svante Carlsson, 700: 15–27. Vorlesungsnotizen in der Informatik. Springer Berlin / Heidelberg, 1993. http://dx.doi.org/10.1007/3-540-56939-1_58 .


2
Nun, die Einfügezeit ist weit von der Marke entfernt.
Raphael

nsize1n0nini+1

Wenn Sie die Zusammenfassung des von Ihnen verlinkten Artikels lesen, scheint es, als seien diese Grenzen erwartete Grenzen für Eingaben einer bestimmten Distribution. Deshalb suche ich nicht danach: Ich möchte die Grenzen, die ich für Eingaben erwähne.
Alex ten Brink

O(log n)

Die logarithmische Binärsuche von @AT erfordert einen wahlfreien Zugriff. Wie ist die zugrunde liegende Liste implementiert? Sie sollten wirklich für Ihre behaupteten Grenzen streiten. Auch "Positionen in der Liste" sind vage - auf welche Positionen und worauf beziehen sich die Symbole? Nicht jeder hat Zugriff auf das von Ihnen verlinkte Papier. Bitte versuchen Sie, Ihre Antwort (mehr) in sich geschlossen zu machen und zumindest die Fakten zusammenzufassen. Zum jetzigen Zeitpunkt glaube ich nicht, dass Ihre Antwort richtig ist.
Juho
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.