Intervall Heaps

Werbung
Intervall Heaps
Studienarbeit von
Thomas Schwanck
am
Institut für Informationssysteme
Fachgebiet Programmiersprachen und Übersetzer
Prof. Dr. R. Parchmann
2004
auf Basis des Artikels
Interval Heaps
von J. van Leeuwen and D. Wood
The Computer Journal Vol. 36 Nr. 3 1993 S.209-216
Intervall Heaps
1.
Einführung
Sei X eine total geordnete Menge von Werten. (z.B. eine Untermenge von R).
Eine double-ended oder min-max Priority Queue ist eine Datenstruktur
für endliche Untermengen Y von X die die folgenden Operationen erlaubt:
1. MIN - bestimme den kleinsten Wert.
2. MAX - bestimme den größten Wert.
3. INSERT(x) - füge den Wert x ∈ X der Menge Y hinzu.
4. DELETEMIN - entferne das kleinste Element.
5. DELETEMAX - entferne das größte Element.
wobei vorausgesetzt sei, daß der Leser die entsprechenden Operationen für
normale Heaps kennt. Es können noch weitere Operationen eingeführt werden, wie z.B. das Ersetzen von Elementen (entspricht einer Prioritätsveränderung, wenn der Wert eines Eintrags seine Priorität ist) oder das Verschmelzen
von Priority Queues, die hier aber nicht weiter betrachtet werden sollen.
Es wird eine effiziente implizite Datenstruktur für double-endede Priority
Queues, also eine Datenstruktur zur Verwaltung einer Menge von n Punkten
aus X in den Positionen A [0] bis A [n − 1] eines Arrays A ohne zusätzliche Zeiger, die die oben aufgeführten Operationen mit einem Zeitbedarf von
O(log n) oder schneller unterstützt vorgestellt, die Heaps in einer konsequenten Weise verallgemeinert. Diese Datenstruktur nennt sich Intervall Heap
und besteht im wesentlichen aus einem Heap, in dem fast alle Knoten ein Paar
von Punkten a, b (mit a ≤ b) aus der zu verwaltenden Menge Y tragen. Die
beiden Punkte eines Paares werden als Endpunkte eines Intervalls aus X betrachtet. Die normale Heapeigenschaft wird durch die Inklusion ersetzt, d.h.
das Intervall eines Knoten enthält die Intervalle aller seiner Nachfolger. Ist
[a, b] das Intervall in der Wurzel, dann impliziert diese Heapeigenschaft, das
a das aktuelle Minimum der Punkte in Y und b das aktuelle Maximum von
Y ist. Eine präzisere Definition von Intervall Heaps wird in Abschnitt 2 gegeben. Dort wird zudem gezeigt, das sich Intervall Heaps mit einem Zeitbedarf
von O(n) erzeugen lassen, die MIN- und MAX-Operationen einen Zeitbedarf
von O(1) haben und für die anderen Operationen höchstens O(log n) Zeiteinheiten benötigen.
In Abschnitt 3 soll die d -dimensionale Verallgemeinerung von Intervall Heaps
betrachtet werden, in Abschnitt 4 werden ein paar Beispiele zur Anwendung
von Intervall Heaps behandelt und im Abschnitt 5 Meßwerte und Details der
Implementation.
1
Intervall Heaps
2.
Intervall Heaps
Es wird die Binärbaum Darstellung von Heaps benutzt, um die Diskussion
der Intervall Heaps zu vereinfachen. Dabei sollte beachtet werden, das sich
alle Manipulationen durch einfache Adressrechnungen auf die Darstellung
mit einem Array H übertragen lassen. Zudem sollte beachtet werden, das
hier das Konzept der Heaps von den Details der Darstellung der Punkte und
der Ordnungrelation zwischen ihnen getrennt wird. Dadurch können beliebige Objekte in den Knoten enthalten sein, solange es eine Ordnungsrelation
zwischen ihnen gibt und die Objekte mit der Idee der Heaps harmonisieren.
Ein Intervall Heap ist ein fast vollständiger Baum (d.h. alle Ebenen bis auf
die unterste sind vollständig gefüllt, nur in der untersten Ebene dürfen rechts
beliebig viele Plätze frei sein.), in dem jeder Knoten ein Intervall [a, b] ∈ X
repräsentiert. Sei I(v) das von dem Knoten v repräsentierte Intervall. Der
nte (und letzte) Knoten des Heaps trägt die Bezeichnung left-hand node
oder, kürzer, die L-node des Heaps.
Definition 2.1
Ein Intervall Heap ist eine Heapstruktur die entweder leer ist oder die
folgenden drei Bedingungen erfüllt (die Intervall Heapeigenschaft):
1. Für jeden Knoten v, der nicht die L-node ist, ist I(v) ein Intervall [a, b]
mit a, b ∈ X.
2. Für die L-node ist I(v) entweder ein einzelner Wert a, wobei a ∈ X,
oder ein Intervall [a, b] mit a, b ∈ X.
3. Für alle Knoten v und w gilt, falls v ein Nachfolger von w ist,
I(v) ⊆ I(w).
In der Definition wird zwischen einem einzelnen Punkt a und dem Intervall
[a, a] unterschieden, da eigendlich zwei Werte aus X nötig sind, um ein Intervall zu definieren.
Um die Diskussion zu vereinfachen, wird die ⊆-Relation so erweitert, das die
Inklusion einer einzelnen Zahl in einem Intervall ebenfalls abgedeckt wird.
Ein Intervall Heap enthält die Menge von Punkten die aus den Elementen
von X besteht, die die linken und rechten Endpunkte der Intervalle des Intervall Heaps bilden und, falls die L-node kein Intervall enthält, das Element
aus der L-node.
Das Hauptergebnis dieses Abschnitts ist, das Intervall Heaps eine effiziente implizite Datenstruktur zur Implementation von double-ended Priority
Queues sind.
2
Intervall Heaps
Beachtet man, das ein Intervall Heap mit n Knoten eine Menge mit 2n − 1
oder 2n Elementen repräsentiert, dann ist es sofort klar, das man durch sukzessives Einfügen von Elementen in einen leeren Intervall Heap jede endliche
Menge mit einem Intervall Heap darstellen kann. Das Einfügen in einen Intervall Heap ist im wesentlichen derselbe Algorithmus wie bei einem normalen
Heap, hier auf den Heaps, die aus den linken bzw. rechten Intervallenden
(zusammen mit dem Wert der L-node, falls diese kein Intervall ist) bestehen.
Der Heap, der aus allen linken Intervallenden besteht, ist ein Min-Heap, der
aus den rechten Intervallenden ein Max-Heap. Diese Heaps werden die zugrundeliegenden Min- und Max-Heaps genannt.
Lemma 2.2
Intervall Heaps unterstützen die INSERT Operation in mit einem Zeitbedarf
von O(log n).
Beweis:
Um ein Element N den Intervall Heap hinzuzufügen, wird anhand der L-node
entschieden, in welchen der zugrundeliegenden Heaps das neue Element eingefügt wird. Als erstes erhält man die folgenden Fälle:
1. Die L-node enthält ein Intervall. Es seien L und R das linke bzw. das
rechte Intervallende. Dann erhält man die 3 folgenden Fälle:
• N < L: Füge N in den zugrundeliegen Min-Heap ein und erzeuge
eine neue L-node mit einem Element.
• L ≤ N ≤ R: erzeuge mit N eine neue L-node.
• R < N : Füge N in den zugrundeliegendes Max-Heap ein und
erzeuge eine neue L-node.
2. Die L-node enthält einen einzelnen Wert. Dann erhält man 2 Fälle, die
analog zum obigen Fall behandelt werden können, nur das hier keine
neue L-node erzeugt werden muß.
Die Fallunterscheidung hat einen Zeitbedarf von O(1), das Einfügen des neuen Elementes in einen der zugrundeliegenden Heaps benötigt einen Zeitbedarf
von O(log n), also insgesamt hat das Einfügen eines neuen Elementes in einen
Intervall Heap einen Zeitbedarf von O(log n).
❏
3
Intervall Heaps
Lemma 2.3
Intervall Heaps benötigen für die DELETEMIN und die DELETEMAX Operation einen Zeitbedarf von O(log n).
Beweis:
Es wird hier nur das Argument für die DELETEMIN Operation gezeigt, die
DELETEMAX Operation kann analog behandelt werden.
Sei I ein Intervall Heap. Wenn die Wurzel von I die L-node ist, beschränkt
sich die DELETEMIN Operation auf das Löschen des Minimums aus der
Wurzel. Sei nun die L-node von I nicht die Wurzel und [a, b] das Intervall in
der Wurzel. Dann ist M IN = a und die DELETEMIN Operation kann wie
folgt ausgeführt werden:
Betrachte den zugrundeliegenden Min-Heap von I: Ersetze a mit den linken
Endwert der L-node, dieses sei x. Nun lasse man x den Heap hinabsteigen,
wie bei einem normalen Heap, nur muß, sobald man einen neuen Knoten K
erreicht, getestet werden, ob K ein gültiges Intervall enthält. Ist dies nicht
der Fall, vertauscht man die Endpunkte des Intervalles. Danach fährt man
fort, das Element den Min-Heap absteigen zu lassen. Nun ist es klar, das die
DELETEMIN Operation einen Zeitbedarf von O(log n) hat.
❏
Theorem 2.4
Intervall Heaps sind eine effiziente implizite Datenstruktur zur Implementation von double-ended Priority Queues, die die MIN und MAX Operationen
mit einem Zeitbedarf von O(1) und die übrigen Operationen mit einem Zeitbedarf von O(log n) unterstützt.
Aus den oben gegebenen Argumenten ist leicht ersichtlich, das Intervall
Heaps derselben Effizienzklasse angehören wie normale Heaps, da sich die Update Operationen auf Operationen auf den zugrundeliegenden Heaps zurückführen lassen.
Es bleibt nun noch die Frage nach der Konstruktion einen Intervall Heaps
mit n Knoten aus einer Menge mit 2n − 1 oder 2n Elementen.
Lemma 2.5
Ein Intervall Heap mit n Knoten kann aus einer Menge von 2n − 1 oder 2n
Elementen mit einem Zeitbedarf von O(n) erzeugt werden.
4
Intervall Heaps
Beweis:
Als erstes werden die Elemente zu zweit zu Knoten zusammengefaßt und in
den Knoten dann zu einem gültigen Intervall umsortiert (Zeitbedarf: O(n)).
Danach durchläuft man von unten nach oben Stufenweise die Knoten, und
lässt in jedem Knoten, der mindestens einen Nachfolger hat, die beiden Elemente des Knotens in den entsprechenden Unterheap durch geeignetes Vertauschen hinabsteigen, also das min-Element in den entsprechenden Unterheap des zugrundeliegenden Min-Heaps und das max-Element in den zugrundeliegenden Max-Heap. Dieser Unterheap wird damit zu einem gültigen
Intervall Heap, so daß man, sobald man alle Knoten besucht hat und bei der
Wurzel des ganzen Heaps angekommen
ist, einen Intervall Heap erzeugt hat.
n
Im zweiten Schritt werden 2 Knoten besucht. Sei k = log2 (n). Dann ist k
die ungefähre Anzahl von Stufen im Heap. Dann werden maximal n4 Knoten
in der (k − 1)-ten Stufe besucht, n8 in der (k − 2)-ten Stufe, usw. bis 2nk = 1
in der ersten Stufe des Heaps. Für einen Knoten der (k − i)-ten Stufe sind
dann maximal 2i Vertauschungen notwendig, um im Unterheap die Intervall
Heapstruktur zu erzeugen. Für die maximale Anzahl t der Vertauschungen
(und damit der Elementvergleiche) erhält man:
k
k
X
X
n
1
t=
· (i − 2) < nk ·
i
2
2i
i=2
i=2
k
k
X
X
für k≥7
1
1
k
≤ nk ·
< nk ·
< nk 2 = n ⇒ O(n)
2
2
i
k
k
i=2
i=2
Insgesamt hat dieser Algorithmus also eine Laufzeit von O(n).
❏
Es gibt noch die Variante der Intervall*Heaps, die im Prinzip Intervall Heaps
mit umgekehrter Ordnungsrelation sind.
Definition 2.6
Ein Intervall*Heap ist ein Heap der entweder leer ist oder die folgendes Eigenschaften erfüllt (Die Intervall*Heapeigenschaft):
1. Für jeden Knoten v, der nicht die L-node ist, ist I(v) ein Intervall
[a, b] (a, b, ∈ X).
2. In der L-node v ist I(v) entweder ein einfacher Wert a (a ∈ X) oder
ein Intervall [a, b] (a, b ∈ X).
3. Für zwei Knoten v und w gilt, falls v Nachfolger von w ist, das
I(w) ⊆ I(v).
5
Intervall Heaps
Sei [a, b] das Intervall der Wurzel eines Intervall*Heaps. Dann sind a und b
offensichtlich die Mediane der Menge V . Im Gegensatz zu Intervall Heaps
bilden hierbei die linken Intervallenden einen Max-Heap und die rechten Intervallenden einen Min-Heap. Das Erzeugen eines Intervall*Heaps und die
Updateoperationen arbeiten offensichtlich nach denselben Prinzipien und in
den selben Laufzeitklassen wie die entsprechenden Operationen von Intervall
Heaps. Deshalb soll hier auf eine erneute Darstellung und einen erneuten
Beweis der Laufzeiten verzichtet werden.
6
Intervall Heaps
3.
d -dimensionale Intervall Heaps
Hier soll die d -dimensionale Verallgemeinerung von Intervall Heaps betrachtet werden. Das Hauptproblem, das zu betrachten ist, ist die Konstruktion
einer impliziten 2d-endigen Priority Queue, die eine Menge V ⊆ X d speichert und die folgenden Operationen gestattet:
1. MINi : bestimme das Element mit der kleinsten i ten Koordinate.
2. MAXi : bestimme das Element mit der größten i ten Koordinate.
3. INSERT: füge einen Wert x ∈ X der Menge V hinzu.
4. DELETEMINi : lösche das Element mit der kleinsten i ten Koordinate.
5. DELETEMAXi : lösche das Element mit der größten iten Koordinate.
Es sei im folgenden d ≥ 2.
Benötigt wird eine Verallgemeinerung des Intervalls für eine Menge von Punkten W ⊆ X d , wobei |W | ≥ 2d sei.
Definition 3.1
Ein d-Intervall definiert durch eine Menge W ⊆ X d von Punkten ist der
d-dimensionale Quader, der durch die Hyperflächen H1 bis H2d gegeben wird,
die wie folgt definiert sind:
1. H1 ist die 1-Hyperfläche, die durch den Punkt h1 ∈ W , der die kleinste
erste Koordinate von allen Punkten aus W hat, gegeben wird, H2 ist
die 1-Hyperfläche, die durch einen Punkt h2 ∈ W − {h1 } mit größter
erster Koordinate gegeben wird.
2. Für 1 < i ≤ d ist H2i−1 die i-Hyperfläche, die durch einen Punkt
h2i−1 ∈ W − {h1 , · · · , h2i−2 } mit kleinster i-ter Koordinate gegeben
wird und H2i ist die i-Hyperfläche, die durch einen Punkt h2i ∈ W −
{h1 , · · · , h2i−1 } mit größter i-ter Koordinate gegeben wird.
Dabei bezeichne eine i-Hyperfläche die Menge aller Punkte H ⊆ X d mit gegebener i-ter Koordinate.
Falls |W | = j < 2d, dann kann dieselbe Definition benutzt werden, wobei
nur j Hyperflächen definiert sind und der Quader“ nicht komplett geschlos”
sen ist. Für endliche Mengen W ⊆ X d lässt sich das zugehörige d -Intervall
IW (begrenzt durch die Hyperflächen Hi mit den Randpunkten hi ) offensichtlich mit einem Zeitbedarf von O(d2 ) bestimmen. Man sagt, das W in
7
Intervall Heaps
IW enthalten ist, obwohl genau gesagt nur W − {h1 , · · · , h2d } ⊆ IW . Ein
d -Intervall wird eindeutig definiert durch die (geordnete) Menge von Randpunkten h1 , · · · , h2d , oder h1 , · · · , hj im Falle eines unvollständigen Intervalls,
und wird als [h1 , · · · , h2d ] bzw. [h1 , · · · , hj ] notiert.
Definition 3.2
Ein d-dimensionaler Intervall Heap (d-Intervall Heap) ist ein Heap
der entweder leer ist, oder die folgenden Bedingungen erfüllt (die d-Intervall
Heapeigenschaft):
1. Für jeden Knoten v, der nicht die L-node ist, ist I(v) ein d-Intervall
[a1 , · · · , a2d ] (ai ∈ X d , für 1 ≤ i ≤ 2d).
2. Für die L-node v ist I(v) entweder eine Menge von Punkten aus X d
mit 1 ≤ |I(v)| < 2d oder ein d-Intervall [a1 , · · · , a2d ] (ai ∈ X d für 1 ≤
i ≤ 2d).
3. Für alle Paare von Knoten v und w gilt, wenn v Nachfolger von w ist,
das I(v) ⊆ I(w).
Diese Definition ist dieselbe wie die für eindimensionale Intervall Heaps. Ein
d -Intervall Heap repräsentiert die Punkte aus X d , die die Intervallgrenzen d Intervalle des Heaps sind, also die Punkte, deren Koordinaten der die Hyperflächen der Intervalle definieren, und, falls die L-node kein d -Intervall enthält,
die in der L-node gespeicherte Menge von Punkten. D-Intervall Heaps lassen
sich genauso wie eindimensionale Intervall Heaps als implizite Datenstrukturen implementieren, auch wenn die Implementation nicht ganz so einfach ist.
Das folgende Lemma folgt sofort aus der Definition:
Lemma 3.3
D-Intervall Heaps unterstützen die MINi und MAXi Operationen mit einer
Laufzeit von O(d).
Lemma 3.4
D-Intervall Heaps unterstützen die INSERT Operation in einer Laufzeit von
O(d log n).
Beweis:
Sei I ein d -Intervall Heap, x ∈ X d ein Punkt, der zu I hinzugefügt werden
soll. Wenn I leer ist, oder die L-node mit der Wurzel identisch ist und kein
ganzes d -Intervall enthält, wird x trivialerweise in die Wurzel eingesetzt.
Betrachte nun den nicht-trivialen Fall, das die L-node v nicht die Wurzel ist.
8
Intervall Heaps
Sei w der Vorgänger von v und I(w) = [a1 , · · · , a2d ].
Falls x ∈ I(w), d.h. x ist in dem d -Intervall von w enthalten, dann füge x zu
I(v) hinzu und erzeuge aus I(v) ein d -Intervall, wenn I(v) nun 2d Punkte
enthält. Dieses bewahrt die d -Intervall Heapeigenschaft.
Falls x ∈
/ I(w), dann steige in Richtung der Wurzel auf und teste bei jeden
Knoten w der besucht wird, ob x ∈ I(s), wobei s der Vorgänger von w sei.
(ist w die Wurzel, dann sei I(s) das unendliche d -Intervall X d ). Sei w0 der
erste Knoten auf dem Weg zur Wurzel, für den dieses gilt. (Beachte, das w0
wohldefiniert ist, da der Test an der Wurzel immer ein positives Ergebnis hat,
und das jeder Test x ∈ I(s) mit einem Zeitbedarf von O(d) ausgewertet werden kann.) Sei I(w0 ) = [a1 , · · · , a2d ], wobei sicher x ∈ I(w0 ) gilt. Nun ersetze
man I(w0 ) durch das von der Menge {a1 , · · · , a2d , x} definierte d -Intervall.
Die definierenden Randpunkte setzten sich dann aus x und a1 , · · · , a2d ohne
einen Punkt at zusammen. Beachte, das at ∈ I(w0 ).
Nun benutze man, das in O(1) bestimmt werden kann, unterhalb welches
Nachfolgers eines Knotens, der nicht notwendigerweise die Wurzel ist, sich
die L-node befindet. Dies geht, wenn man bedenkt, das dafür zwar O(log n)
Operationen mit Arrayindizes oder Zeigern benötigt werden, aber eben O(1)
(eben keine) Operationen mit Elementen des Heaps, deren Vergleich oder
Vertauschen erheblich aufwendiger sein kann, als ein Integer-Vergleich (z.B.
bei Zeichenketten). Nun verfolge man den Weg von wo zurück zu der L-node
v und suche dabei den ersten Knoten w1 mit at ∈
/ I(w1 ).
Falls ein solcher Knoten nicht existiert, dann endet man bei v und kann
den Punkt einfach zur Menge I(v) hinzufügen. Gilt |I(v)| = 2d, dann erzeuge man aus der Punktmenge der L-node ein d -Intervall. Dies stellt die
d -Intervall Heapeigenschaft wieder her und man ist fertig.
Falls ein solcher Knoten w1 existiert, dann verfahre man mit w1 und at so
wie mit w0 und x. Dies ergibt ein neues d -Intervall in w1 und einen Punkt
at0 ∈ I(w1 ). Nun arbeite man nach unten weiter und wiederhole das Verfahren mit at0 , etc., bis man v erreicht.
Es bleibt der Fall zu betrachten, wenn I(v) ein ganzes d -Intervall ist. Dann
erzeuge man den nächsten Knoten u der Heapstruktur und initialisiere I(u)
als leere Menge. Nun beginnt man in u mit derselben Prozedur wie oben. Dies
erhält ebenfalls die d -Intervall Heap Eigenschaft und erzeugt einen gültigen
d -Intervall Heap, der nun auch x enthält.
Offensichtlich benötigt das Verfahren O(log n) Schritte mit O(d) Kosten, also
insgesamt einen Zeitbedarf von O(d log n).
❏
9
Intervall Heaps
Lemma 3.5
D-Intervall Heaps unterstützen die DELETEMINi und DELETEMAXi Operationen in einem Zeitbedarf von O(d2 log n).
Beweis:
Wie beim eindimensionalen Fall soll das Argument hier nur für die DELETEMINi Operationen gezeigt werden. Die DELETEMAXi Operationen arbeiten
analog.
Sei I ein d -Intervall Heap. Falls die L-node v die Wurzel ist, dann besteht
die DELETEMINi Operation daraus, den Punkt mit der kleinster i-ten Koordinate aus der Menge I(v) zu löschen.
Sei nun die Wurzel nicht die L-node von I und [a1 , · · · , a2d ] das d -Intervall
der Wurzel.
Sicherlich ist MINi der Punkt aj ∈ {a1 , · · · , a2d } mit kleinster i-ter Koordinate (beachte, das dies nicht notwendigerweise der Punkt a2i−1 sein muß).
Sei nun MINi = aj . Im wesentlichen muß man jetzt aj löschen und seinen
Platz wieder auffüllen, dieses ist aber aufwendiger als im eindimensionalen
Fall. Die Nachfolger der Wurzel seien u und v.
Betrachte das Verfahren zur Erzeugung von d -Intervallen: Klar ist, das a1 ,
· · · , aj−1 genau dieselben Punkte sind wie vorher, aber aj hinterläßt ein Loch.
Der Punkt mit extremer j-ter Koordinate (es kann das Minimum genauso
wie das Maximum gesucht sein!), der dieses Loch füllt, kann einer der Punkte
aus I(u) oder I(v) sein, aber auch einer der Punkte aj+1 , · · · , a2d . In diesem
Fall wird aj durch ein ak (j < k) ersetzt, und man erhält ein Loch weiter hinten in der Liste. Danach muß man aj+1 , · · · , ak−1 nehmen und bestimmt den
Ersatz für ak auf dieselbe Art und Weise. Letztendlich wird das Loch dann
aber mit einem Element aus I(u) oder I(v) gefüllt. Beachte, das man O(d)
Schritte mit O(d) Kosten benötigt, um diese Konstruktion durchzuführen.
Das resutierende d -Intervall umschließt sowohl I(u) als auch I(v).
Nun ist es klar, daß das Verfahren mit den Knoten, dem das Element entnommen wurde, iteriert werden muß, solange bis der Knoten keinen Nachfolger
mehr hat. Wenn dieser Knoten die L-node ist, dann ist man fertig, sonst muß
man einen beliebigen Punkt aus der L-node entfernen und mit dem Verfahren
von Lemma 3.4 in den Knoten einfügen.
Dieses erzeugt aus I mit einem Zeitbedarf von O(d2 log n) wieder einen gültigen d -Intervall Heap.
❏
Verbleibt die Frage nach der Konstruktion eines d -Intervall Heap aus einer
Menge von n Punkten aus X d .
10
Intervall Heaps
Theorem 3.6
d-Intervall Heaps können mit einem Zeitbedarf von O(d3 n) aus einer Menge
von Punkten aufgebaut werden.
Beweis:
Als erster werden die Punkte in Gruppen von 2d Punkten zu den Knoten der
Heapstruktur zusammengefasst, d.h. aus den jeweils 2d Punkten wird ein
d -Intervall erzeugt. Beginnend mit den untersten Knoten wird dann schrittweise ein d -Intervall Heap erzeugt, indem nacheinander, Stufe für Stufe aus
jedem Knoten, der kein Blatt ist, und seinen Nachfolgern ein Unterheap
erzeugt wird. In einem typischen Schritt wird ein Knoten w, der die Nachfolger u und v hat, die in einen vorhergegangenen Schritt mit ihren Nachfolgern in Unter-d -Intervall Heaps transformiert wurden, mit seinen Nachfolgern
zu einem Unter-d -Intervall Heap transformiert. Sei P (x) die Menge der in
I(x) gespeicherten Punkte. Dann wird dazu aus den Punkten aus der Menge
P = P (w)∪P (u)∪P (v) ein neues d -Intervall erzeugt, indem die entsprechenden Punkte nacheinander ausgewählt und aus P gelöscht werden. Wird ein
Punkt aus P (u) oder P (v) gewählt, dann wird dieser Punkt sofort nach dem
Verfahren aus dem obigen Lemma aus dem entsprechenden Unter d -Intervall
Heap gelöscht, und der Punkt, der stattdessen in P (u) (bzw. P (v)) aufsteigt,
zu der Menge P hinzugefügt. Nachdem so ein neues d -Intervall I(w)0 erzeugt
wurde, wird es in w gespeichert. Dabei wurden i Punkte aus P (u) und j
Punkte aus P (v) benutzt. Offensichtlich gilt i + j ≤ 2d. Anschließend werden
i von den i + j Punkten aus I(w), die nicht in I(w)0 enthalten sind, dem
Unterheap mit Wurzel u und j dem Unterheap mit Wurzel v hinzugefügt.
Für einen Knoten benötigt man damit maximal 2d Schritte mit O(d2 ·Höhe(w))
Kosten zum Löschen der Elemente und genau soviele Schritte mit O(d2 ·
Höhe(w)) Kosten zum Einfügen der neuen Elemente, wobei Höhe(w) die Anzahl der Stufen unter dem Knoten w sei. Insgesamt hat ein Knoten damit
Kosten von O(d3 · Höhe(w)), also folgt mit den selben Argumenten wie im
eindimensionalen Fall, das der Algorithmus eine Komplexität von O(d3 · n)
hat.
❏
11
Intervall Heaps
4.
Anwendungen von Intervall Heaps
Hier werden zwei Anwendungen für Intervall Heaps betrachtet.
In der üblichen Implementation als Array wächst und schrumpft ein Intervall
Heap am rechten Ende, also an der L-node, wenn Elemente eingefügt oder
gelöscht werden. Es kann sinnvoll sein, den Intervall Heap so zu implementieren, das er am linken Ende schrumpft, wenn die DELETEMIN Operation
ausgeführt wird, und am rechten Ende schrumpft, wenn die DELETEMAX
Operation ausgeführt wird. Dieses lässt sich z.B. beim double Heapsort
einsetzen, die offensichtliche Modifikation des Heapsorts, bei der das Array
sortiert wird, indem gleichzeitig (i.allg. abwechselnd) am niedrigwertigen und
am hochwertigen Ende gearbeitet wird. Für diese Anwendung ist der Intervall Heap eine einfache Lösung in folgender Bedeutung: Das Array mit den
zu sortierenden Elementen enthalte 2n Werte. Das umwandeln dieses Arrays
in einen Intervall Heap mit n Knoten benötigt einen Zeitbedarf von O(n),
wobei der linke Endpunkt des Intervalls eines Knoten i an der Arrayposition
n − i und der rechte an Position n − 1 + i (1 ≤ i ≤ n) zu finden ist. Da sich
DELETEMIN und DELETEMAX Operationen beim double Heapsort abwechseln, schrumpft der Intervall Heap bei jedem Schritt am richtigen Ende.
Dieses macht den double Heapsort zu einem effizienten Sortieralgorithmus für
Arrays, der, bezogen auf die Komplexität der Löschoperationen, vergleichbar
mit dem Heapsort ist.
Eine interressantere Anwendung betrifft die Theorie der mehrdimensionalen
Datenstrukturen und die computational geometry“. Es soll das complemen”
”
tary-range query“ Problem betrachtet werden, welches wie folgt definiert ist:
Gegeben sei eine Menge V von n Punkten im d-dimensionalen Raum und ein
d-Intervall B. Bestimme die Punkte von V , die nicht in B enthalten sind.
Es lässt sich zeigen, das sich dieses Problem mit Hilfe der d -dimensionalen
Intervall Heaps lösen lässt, und zwar mit einem Zeitaufwand von O(d2 n) zum
Erzeugen der Datenstruktur und O(d3 K) für eine Anfrage, wobei K die Anzahl der Punkte im Ergebnis ist.
Hier soll nur die 1-dimensionale Variante betrachtet werden, dann lautet das
Problem wie folgt:
Gegeben ist eine Mengen V von n Punkten auf der reellen Zahlengeraden
und ein Intervall [x, y], bestimme alle Punkte von V , die nicht im Intervall
enthalten sind.
In der dynamischen Variante ist ein Algorithmus (und eine Datenstruktur)
gesucht, die auch dann effizient ist, wenn Punkte eingefügt oder gelöscht werden können.
12
Intervall Heaps
Theorem 4.1
Das (dynamische) 1-dimensionale complementary-range query Problem kann
mit einem Intervall Heap mit einem Zeitbedarf von O(n) zum Erzeugen und
einem Zeitbedarf von O(K) für eine Anfrage gelöst werden, wobei K die Anzahl der Punkte ist, die die Anfrage zurück gibt.
Beweis:
Als erstes werden die Punkte in einem Intervall Heap organisiert. Dies lässt
sich nach Abschnitt 2 in O(n) bewältigen.
Nun soll gezeigt werden, das complementary-range queries in O(K) beantwortet werden können. Sei [x, y] das Anfrageintervall. Der Anfragealgorithmus beginnt an der Wurzel des Intervall Heaps und arbeitet rekursiv in der
folgenden Weise, sobald ein Knoten v erreicht wird.
Wird ein Knoten v erreicht, dann sind zwei Fälle möglich, wenn I(v) mit
[x, y] verglichen wird:
Fall i): I(v) ⊆ [x, y]. In diesem Fall muß kein Punkt aus v oder dem Unterheap mit Wurzel v zurückgegeben werden. Der Algorithmus ignoriert
den gesamten Unterheap und fährt mit dem nächsten Knoten fort.
Fall ii): I(v) ∩ [x, y] ⊆ I(v). In diesem Fall enthält I(v) mindestens einen
Punkt der nicht im Intervall [x, y] enthalten ist und zurückgegeben
werden muß. Wenn der andere Endpunkt von I(v) auch nicht in [x, y]
enthalten ist, dann muß er ebenfalls zurückgegeben werden. Wenn v
kein Blatt ist, dann besucht der Algorithmus als nächstes die Blätter
von v.
Der Anfrage Algorithmus wird also als ein preorder - Durchlauf von I implementiert, wobei Unterbäume, die keine Ergebnisse enthalten, abgeschnitten
werden (Fall i)).
Die Komplexität des Anfragealgorithmus von O(K) erschließt sich mit den
folgenden Argumenten: Der Algorithmus ist linear in der Anzahl der Knoten,
die besucht werden. Wenn Fall ii) in einem Knoten eintritt, entstehen Kosten für die ein oder zwei Punkte, die zurückgegeben werden müssen. Wenn
Fall i) in einem Knoten v eintritt, dann muß Fall ii) in dem Vorgänger von
v eingetreten sein. Deshalb können die Kosten, die durch den Besuch von v
entstehen, mit den Kosten, die beim Vorgänger von v entstehen, verrechnet
werden. Das kein Knoten mehr als 2 Nachfolger hat, kostet kein gefundener
Punkt mehr als O(1), und daraus folgt die Komplexität von O(K).
❏.
Zu beachten ist, das ein Intervall Heap nur im folgenden Sinne dynamisch
ist: Ein Intervall Heap unterstützt das Einfügen von Objekten mit einem
13
Intervall Heaps
Zeitbedarf von O(log n), aber das Löschen von Objekten arbeitet nur dann
in derselben Laufzeitklasse, wenn die Position des zu löschenden Objektes im
Intervall Heap bekannt ist (und dies dürfte recht selten der Fall sein, zumindest wenn der Intervall heap als Array implementiert wurde, denn dann kann
die Information nach der ersten Einfüge- oder Löschoperation schon falsch
sein).
Das d -dimensionale range-query Problem lässt sich mit einem d -dimensionalen
Intervall Heap lösen, darauf soll hier aber nicht weiter eingegangen werden.
Ein Anderes Problem ist das 1-dimensionale range query“ Problem:
”
Gegeben sein eine Menge V mit n Punkten und ein Intervall [x, y], bestimme
alle Punkte von V , die im Intervall liegen.
Es ist wesentlich schwerer, für dieses Problem eine dynamische implizite Datenstruktur zu entwerfen, die in linearer Zeit aufgebaut werden kann und
Anfregen in O(K) unterstützt. Hier sei nur erwähnt, das man dieses unter
der Vorraussetzung, das der Median von V in [x, y] enthalten ist, mit einen
ganz ähnlichen Algorithmus wie bei dem des complementary-range query
Problems mit Intervall*Heaps lösen kann.
14
Intervall Heaps
5.
Implementation & Meßwerte
5.1.
Implementation
Als erstes ist festzuhalten, das es verschiedene Möglichkeiten gibt, einen Intervall Heap zu implementieren. Als erstes sei die von Van Leeuwen und Wood
vorgeschlagene
wird
Methode
genannt (der Intervall Heap): Implementiert
ein Array H 1 . . . n2 , wobei jedes Element H [i] (1 ≤ i ≤ n2 ) zwei Werte
H [i] .min und H [i] .max
mit H [i] .min ≤ H [i] .max enthält, wobei H n2
nur den Wert H n2 .min enthält, wenn n eine ungerade Zahl ist. Dabei
gilt:
• H 2i .min ≤ H [i] .min
• H 2i .max ≥ H [i] .max
Diese Datenstruktur wird auch min-max-pair heap genannt.
Eine andere Methode ist die Implementation als sog. twin-heap, wobei ein
Array T [1 . . . n] einen twin-heap mit n Elementen repräsentiert. Ein Array T
ist ein twin-heap, wenn es die folgenden Bedingungen erfüllt (auch twin-heap
Eigenschaft genannt):
• T 2i ≤ T [i] für 1 < i ≤ n2
j n n
≥
T
j
+
für
1
<
j
≤
n
−
2
2
2
2
n n
• T [i] ≤ T i + 2 für 1 ≤ i ≤2 (falls existent, sonst T [i] ≤ T 2i + n2 ).
Dabei ist T [1] das kleinste Element und T n2 + 1 ist das größte Element.
Eine weitere Implementation der twin-heaps ist die sog. diamond deque:
Sei D [1 . . . n] ein Array mit n Einträgen. Dann muß D den folgenden Bedingungen genügen: Für jedes ungerade i, 1 ≤ i ≤ n gilt:
• T
+
n • D [i] ≤ min {D [2i + 1] , D [2i + 3]}
• D [i + 1] ≥ max {D [2i + 2] , D [2i + 4]}
• D [i] ≤ D [i + 1].
Es ist sofort ersichtlich, das die beiden Varianten äquivalent sind, da sie sich
nur durch eine einfache Adressumrechnung unterscheiden. Der Intervall Heap
15
Intervall Heaps
ist ebenfalls zu der diamond deque (und damit zu den twin-heaps) äquivalent,
wenn man folgende Gleichungen betrachtet:
H [i] .min = D [2i − 1] und
lnm
H [i] .max = D [2i] ∀1 ≤ i ≤
2
Hier wurde die Implementation als diamond-deque gewählt, da sie eine bessere Laufzeit versprach als die Implementation als Intervall Heap und, da die
Min- und Maxeinträge eines Knoten nebeneinander im Array liegen, näher
am Intervall Heap ist als ein twin-heap.
5.2.
Meßwerte
Hier werden ein paar ausgewählte Meßwerte des eindimensionalen Intervall
Heaps und des d -Intervall Heaps gezeigt, um einen Vergleich der Theoretisch
zu erwartenden Laufzeit mit der Realität zu haben.
Alle Messungen wurden mit einem Pentium III mit 1,2 Ghz (mit Tualatin
Kern, CPUID = 6B1) und 384 MB RAM gemacht. Das verwendete Betriebssystem war Windows XP Home Version 2002 mit Service Pack 2, die verwendete Javaversion war Java 2 Standard Edition Version 1.4.2 05.
Die Java Virtual Maschine wurde mit dem Parameter -Xmx180M“ gestartet,
”
um sicherzustellen, das 180 MB Speicher für das Programm zur Verfügung
stehen.
16
Intervall Heaps
Erzeugen eines Intervall Heaps
msec
2750
2500
2250
2000
1750
1500
Minimum
Mittelwert
Maximum
1250
1000
750
500
250
0
1
2
3
4
5
6
7
8
9 10 11 12 13 14 15 16 17 18 19 20
* 500000 Objekte
Anzahl
Objekte
Minimum in
msec
Mittelwert
in msec
Maximum in
msec
500000
1000000
1500000
2000000
2500000
3000000
3500000
4000000
4500000
5000000
5500000
6000000
6500000
7000000
7500000
8000000
8500000
9000000
9500000
10000000
120
250
390
501
631
751
881
991
1112
1232
1372
1482
1603
1732
1843
1983
2093
2223
2353
2454
131
259
396
513
646
774
897
1008
1124
1247
1379
1515
1636
1752
1871
2024
2119
2242
2387
2500
140
271
420
521
681
821
942
1041
1142
1272
1402
1582
1713
1773
1902
2103
2144
2284
2474
2524
Die Messungen geben die Zeiten in msec an, die benötigt wurden, um 500000
Objekte in einen Heap mit der angegebenen Anzahl von Objekten einzufügen.
Dabei sind Minimal-, Mittel-, und Maximalwert von 10 Messungen angegeben.
17
Intervall Heaps
Einfügen in einen Intervall Heap
msec
220
200
180
160
140
120
Minimum
Mittelwert
Maximum
100
80
60
40
20
0
1
#Objekte
250000
500000
750000
1000000
1250000
1500000
1750000
2000000
2250000
2500000
2750000
3000000
3250000
3500000
3750000
4000000
4250000
4500000
4750000
5000000
5
10
15
20
Mittelwert
Minimum
Maximum
130
140
150
150
150
150
150
150
160
160
160
160
160
160
160
160
160
170
170
170
137
147
155
156
160
161
162
162
167
169
167
169
168
169
168
168
169
176
176
175
35
* 250000 Objekte
151
160
171
171
171
181
171
181
190
191
190
190
190
190
181
200
190
200
191
191
30
#Objekte
5250000
5500000
5750000
6000000
6250000
6500000
6750000
7000000
7250000
7500000
7750000
8000000
8250000
8500000
8750000
9000000
9250000
9500000
9750000
10000000
35
40
Mittelwert
Minimum
Maximum
170
170
170
170
160
160
170
170
170
170
170
170
160
170
170
170
170
170
170
170
175
174
174
175
175
175
175
175
175
176
174
174
175
177
183
181
180
183
181
182
210
191
190
190
191
191
191
191
191
191
201
190
191
191
201
200
200
200
200
200
Die Messungen geben die Zeiten in msec an, die benötigt wurden, um 250000
Objekte in einen Intervall Heap mit der angegebenen Anzahl von Objekten einzufügen, an. Da durch die sehr kurzen Zeiten die Messgenauigkeit zu
wünschen übrig lies, wurden hier alle Messungen 50 mal wiederholt. In der
Tabelle sind jeweils Minimal-, Maximal- und Mittelwert dieser Messungen
angegeben.
18
Intervall Heaps
Löschen aus einem Intervall Heap
msec
2200
2000
1800
1600
1400
1200
Minimum
Mittelwert
Maximum
1000
800
600
400
200
0
1
2
3
4
5
6
7
8 9 10 11 12 13 14 15 16 17 18 19 20
*500000 Objekte
#Objekte
Mittelwert
Minimum
Maximum
500000
1000000
1500000
2000000
2500000
3000000
3500000
4000000
4500000
5000000
762
1131
1271
1372
1442
1492
1562
1602
1642
1682
783
1149
1291
1381
1458
1504
1570
1633
1658
1693
811
1212
1322
1392
1472
1512
1603
1722
1682
1712
#Objekte
Mittelwert
Minimum
Maximum
5500000
6000000
6500000
7000000
7500000
8000000
8500000
9000000
9500000
10000000
1693
1723
1773
1792
1823
1843
1872
1892
1893
1922
1707
1758
1797
1806
1832
1859
1913
1903
1926
1938
1723
1833
1853
1822
1843
1883
2003
1913
1943
1983
Die Messungen geben die Zeiten in msec an, die benötigt wurden, um 500000
Objekte aus einen Heap mit der angegebenen Anzahl von Objekten zu löschen.
Dabei sind Minimal-, Mittel-, und Maximalwert von 10 Messungen angegeben. Hier wurde nur die DELETE-MIN Operation benutzt, die DELETEMAX Operation sollte identische Messwerte ergeben.
19
Intervall Heaps
1D Complementary Range Query
msec
6500
6000
5500
5000
4500
4000
3500
Minimum
Mittelwert
Maximum
3000
2500
2000
1500
1000
500
0
0
5
10
*500000 Objekte
#Objekte
Mittelwert
Minimum
Maximum
0
100000
200000
300000
400000
500000
600000
700000
800000
900000
1000000
0
711
1001
1282
1562
1843
2113
2394
2663
2955
3234
0
725
1004
1293
1571
1853
2134
2419
2706
3007
3264
0
732
1012
1311
1582
1873
2143
2454
2774
3085
3364
15
20
#Objekte
Mittelwert
Minimum
Maximum
1100000
1200000
1300000
1400000
1500000
1600000
1700000
1800000
1900000
2000000
3505
3785
4066
4336
4617
4877
5157
5418
5668
5948
3544
3827
4096
4360
4632
4913
5212
5482
5731
5971
3656
3916
4166
4386
4687
4977
5297
5558
5829
6079
Dargestellt sind die Zeiten in msec, die benötigt wurden, um eine Complementary Range Query, die die angegebene Anzahl von Elemente als Antwort
ergab, in einem Intervall Heap mit 2000000 Objekten durchzuführen. Angegeben sind Minimal-, Mittel- und Maximalwert von 10 Messungen.
Es ist leicht zu sehen, das die Implementation die aus der Theorie gegebenen Laufzeitverhalten von O(log n) beim Einfügen und Löschen und O(n)
beim Erzeugen einhält. Überraschend ist, daß das Einfügen von Elementen
erheblich schneller vonstatten geht als das Löschen von Elementen.
20
Intervall Heaps
Einfügen in einen d -dimensionalen Intervall Heap
msec
1000
900
800
700
600
Minimum
Mittelwert
Maximum
500
400
300
200
100
0
2
5
10
15
Dimensionen
20
25
30
Dimension
Dimension
Mittelwert
Mittelwert
Minimum
Maximum
Minimum
Maximum
2
3
4
5
6
7
8
9
10
11
12
13
14
15
200
240
260
291
331
350
381
400
421
450
481
501
531
551
218
247
273
310
340
364
393
415
442
479
514
532
553
579
261
261
290
330
361
380
410
441
471
511
551
561
571
611
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
590
611
631
651
681
711
731
761
791
811
841
861
901
911
942
605
633
658
678
699
724
750
778
818
850
862
890
914
939
956
641
671
681
701
721
731
761
791
872
892
911
941
951
981
972
Hier ist die Zeit, die benötigt wurde, um 500000 Objekte in einen d -Intervall
Heap einzufügen, in Abhängigkeit der Dimension dargestellt. Es wurden 10
Messungen gemacht, von denen jeweils Minimal-, Mittel- und Maximalwert
angegeben sind. Die Angabe, das die Laufzeit in Bezug auf die Dimension
linear ist, scheint zu stimmen.
21
Intervall Heaps
Löschen aus einen d -dimensionalen Intervall Heap
msec
30000
27500
25000
22500
20000
17500
Minimum
Mittelwert
Maximum
f(x)=x^2*33+190
15000
12500
10000
7500
5000
2500
0
1
5
Dimension
1
5
10
15
20
25
30
10
Minimum
180
440
771
1132
1523
1952
2453
2984
3535
4116
4747
5377
6109
6860
7651
8472
9333
10224
11136
12077
13049
14040
15062
16103
17205
18377
19588
20819
22101
23373
15
Dimension
20
25
Mittelwert
Maximum
187
454
783
1156
1543
2003
2480
3010
3570
4146
4807
5410
6160
6943
7705
8560
9404
10326
11236
12166
13158
14164
15185
16224
17370
18518
19754
20978
22280
23581
200
480
832
1242
1582
2163
2553
3124
3705
4216
5017
5518
6359
7140
7891
8733
9594
10485
11407
12338
13309
14320
15332
16354
17545
18647
19909
21131
22382
23654
30
f (x) = x2 · 33 + 190
223
322
487
718
1015
1378
1807
2302
2863
3490
4183
4942
5767
6658
7615
8638
9727
10882
12103
13390
14743
16162
17647
19198
20815
22498
24247
26062
27943
29890
Hier ist die Zeit, die benötigt wurde, um 50000 Objekte aus einen d -Intervall
Heap zu löschen, in Abhängigkeit der Dimension dargestellt. Es wurden 10
Messungen gemacht, von denen jeweils Minimal-, Mittel- und Maximalwert
angegeben sind. Hierbei zeigt sich, daß das Laufzeitverhalten in Bezug auf
die Dimension etwas besser als O(d2 ) ist (vgl. mit der dunkel lilanen Kurve).
22
Intervall Heaps
Erzeugen eines d -Intervall Heaps
msec
2500
2250
2000
1750
1500
Minimum
Mittelwert
Maximum
1250
1000
750
500
250
0
1
5
10
15
20
25
30
Dimensionen
Dimensionen
Mittelwert
Minimum
Maximum
1
952
967
1072
2
941
958
981
3
1031
1035
1042
4
1052
1080
1142
5
1101
1115
1161
6
1142
1148
1162
7
1192
1205
1242
8
1252
1264
1302
9
1282
1304
1372
10
1332
1347
1392
11
1382
1397
1462
12
1432
1455
1533
13
1472
1487
1502
14
1522
1533
1562
15
1582
1593
1603
Dimensionen
Mittelwert
Minimum
Maximum
16
1633
1649
1743
17
1663
1682
1763
18
1722
1738
1783
19
1763
1787
1883
20
1813
1841
1903
21
1873
1889
1973
22
1913
1937
2003
23
1973
1990
2073
24
2013
2036
2073
25
2073
2082
2093
26
2123
2145
2233
27
2173
2192
2284
28
2223
2238
2273
29
2263
2285
2333
30
2313
2341
2423
Dargestellt ist die Zeit, die benötigt wurde, um einen d -Intervall Heap mit
1000000 Objekten zu erzeugen, in abhängigkeit von der Dimension d. Es
wurden 10 Messungen gemacht, von denen der Minimal-, Mittel- und Maximalwert angegeben sind.
23
Intervall Heaps
msec
5000
4500
4000
3500
3000
Minimum
Mittelwert
Maximum
2500
2000
1500
1000
500
0
1
10
20
#Objekte
Mittelwert
Minimum
Maximum
100000
50
64
160
200000
100
120
191
300000
260
263
270
400000
340
346
351
500000
420
429
441
600000
491
509
521
700000
590
596
611
800000
651
673
711
900000
761
774
821
1000000
831
844
852
1100000
901
915
952
1200000 1001
1005
1012
1300000 1061
1079
1122
1400000 1151
1170
1221
1500000 1231
1249
1271
1600000 1301
1318
1352
1700000 1392
1412
1423
1800000 1462
1490
1543
1900000 1562
1571
1583
2000000 1642
1663
1712
2100000 1703
1723
1743
2200000 1812
1827
1883
2300000 1863
1886
1923
2400000 1933
1954
1993
2500000 1392
1412
1472
24
30
*100000 Objekte
40
50
#Objekte
Mittelwert
Minimum
Maximum
2600000 2153
2178
2274
2700000 1502
1521
1612
2800000 2313
2333
2394
2900000 1582
1602
1663
3000000 2524
2561
2674
3100000 1712
1734
1812
3200000 2634
2665
2754
3300000 1833
1853
1923
3400000 2794
2828
2925
3500000 1942
1965
2033
3600000 3034
3063
3174
3700000 2073
2099
2203
3800000 2123
2143
2213
3900000 2193
2222
2313
4000000 2243
2264
2343
4100000 4105
4135
4237
4200000 2483
2519
2603
4300000 2483
2505
2594
4400000 3595
3618
3675
4500000 2523
2549
2624
4600000 2553
2576
2644
4700000 2664
2707
2814
4800000 2674
2704
2784
4900000 4878
4907
4978
5000000 2934
2967
3074
Intervall Heaps
Dargestellt sind die Zeiten, die benötigt wurden, um einen d -Intervall Heap
mit der gegebenen Anzahl von Objekten zu erzeugen. Es wurden 10 Messungen gemacht, von denen der Minimal-, Mittel- und Maximalwert angegeben
sind.
Auffällig ist bei dem ersten dieser beiden Diagramme, daß das Einfügen im
Mittel eher linear von der Dimension abhängt und nicht, wie theoretisch für
den Worst-Case-Fall zu erwartet, kubisch.
Das zweite Diagramm zeigt zumindest ansatzweise den erwarteten linearen
Zusammenhang von Zeit und der Anzahl der Elemente. Woher die Spitzen
und Einbrüchen kommen weiß ich nicht, da aber alle drei Kurven (Minimal-,
Mittel- und Maximalwert) dieselbe Form haben, und auch ein weiterer Meßversuch keine signifikant abweichenden Ergebnisse zeigte, dürften es keine
Einflüsse aus Multitasking sein. Ich würde die Ursache im Zusammenspiel
der Hardware mit der Java Virtual Maschine und dem Algorithmus vermuten, kann da aber nichts beweisen. Es erscheint mir unwahrscheinlich, daß
die Ursache des beobachteten Verhaltens nur im Algorithmus zu suchen ist.
Unterschiede Implementation ⇔ Vorschlag
Zudem bestehen kleine Unterschiede zwischen der Implementation der d Intervall Heaps und der von van Leeuwen und Wood Vorgeschlagenen Implementation:
• In der Implementation ist die L-node der letzte Knoten, der die Menge
der Elemente, die kein ganzes d -Intervall ergeben enthält, und nicht existent, falls der letzte Knoten ein ganzes d -Intervall enthält, und nicht
der letzte Knoten des Heaps. Da die L-node aber nicht explizit gespeichert wird, ist dies rein eine Frage der Interpretation der Werte
Anzahl der Elemente“ und Anzahl der Knoten“. Eine Ausnahme ist
”
”
die Löschmethode, die die L-node so Interpretiert, wie von van Leeuwen
und Wood vorgeschlagen.
• In der Implementation sind Elemente eine Knotens in der Reihenfolge
[M in1 , M in2 , . . . , M inn , M ax1 , M ax2 , . . . , M axn ], wobei n die Dimension des d -Intervall Heaps sei und M ini (M axi ) das Element mit der
kleinsten (größten) i-ten Koordinate aus dem Knoten, und nicht wie
vorgeschlagen, also [M in1 , M ax1 , M in2 , M ax2 , . . . , M inn , M axn ] sortiert. Beide Vorgehensweisen haben ihre Vor- und Nachteile, würde
ich diese Algorithmen nochmal implementieren, dann würde ich wahrscheinlich die Vorgeschlagene Reihenfolge wählen.
• Der d -Intervall Heaps erzeugende Algorithmus arbeitet etwas anders
25
Intervall Heaps
als von van Leeuwen und Wood vorgeschlagen, es schien mir günstiger,
die Elemente des neuen Intervalls in w auch aus den Elementen des
alten Intervalls von w auszuwählen, zudem werden die Elemente aus u
und v gelöscht, sobald sie gewählt wurden. Wird ein Element gelöscht,
ist das nachgerückte Element auch ein Kandidat für das Intervall in w.
Dies ist notwendig, um einen funktionierenden Algorithmus zu erhalten, diese Notwendigkeit könnte aber auch an meiner oben genannten
Abwandlung liegen.
Im Theorem 3.6 habe ich meinen Algorithmus vorgeschlagen, und nicht
den von van Leeuwen und Wood, die beiden Vorschläge haben dieselbe
Laufzeitklasse.
• Im Gegensatz zu dem Vorschlag von van Leeuwen und Wood kann die
Implementation des d -dimensionalen Algorithmus auch mit einer Dimension arbeiten, ich würde es aber nicht empfehlen, da diese deutlich
langsamer ist als die eindimensionale Variante, wenn sie auch in denselben Laufzeitklassen arbeiten.
26
Intervall Heaps
6.
Quellenangabe
Für die Anfertigung dieser Studienarbeit wurden folgende Quellen benutzt:
• J. van Leeuwen and D. Wood, Interval Heaps, The Computer Journal,
Vol. 36 No. 3 S. 209-216 (1993)
• Jingsen Chen, An Efficient Contruction Algorithm for a Class of Implicit Double-Ended Priority Queues, The Computer Journal, Vol .38
No. 10 S. 818-821(1995)
• On the complexity of building an interval heap, Yuzheng Ding and
Mark Alen Weiss, Information Processing Letters 50 S. 143-144 (1994)
• Vorlesung
COP 5536/NTU AD 711R, Advanced Data Structures“
”
University of Florida
http://www.cise.ufl.edu/˜sahni/cop5536/
Basiert auf
Fundamentals of data structures in C++, by E. Horowitz, S. Sahni,
and D. Mehta, W. H. Freeman, 1995.
27
Intervall Heaps
Anhang A.
Programm
Verzeichnis der Programme
Beschreibung
Parameter
Ausgabe
Verschiedene
Konsole
Faktor
für
die Anzahl
der Elemente
(2)
Konsole
Anzahl Tests
Konsole
Anzahl Tests
Konsole
Anzahl Tests
Konsole
Anzahl Tests
Konsole
Anzahl Tests
Konsole
Anzahl
Dimensionen
Konsole
Datei
Anzahl Tests
Konsole
Anzahl Tests
Anzahl
Objekte
Konsole
Eindimensionale Intervall Heaps
IntervallHeap
...Test
...ZeittestCRQ
...ZeittestEinfuegen
...ZeittestErzeugen
...ZeittestLoeschen
Die Klasse IntervallHeap
Parametergesteuertes Programm
zum Intervall Heap Test.
Misst die Zeiten, die für
complementary-range
queries mit Ergebnismengen von 0
bis 2 · 106 Objekten benötigt
werden.
Misst die Zeiten, die benötigt
werden, um 25 · 104 Objekte in
einen Intervall Heap mit 0 bis
975 · 104 Objekten einzufügen.
Misst die Zeiten, die benötigt
werden, um Intervall Heaps mit
.
5 · 105 bis 107 Objekten (in 5 · 105
Schritten) zu erzeugen
Misst die Zeiten, die benötigt
werden, um 5 · 105 Objekte aus
einen Intervall Heap mit 5 · 105
bis 10 · 107 Objekten zu löschen.
d -dimensionale Intervall Heaps
DIntervallHeap
...ZeittestEinfuegen
...ZeittestErzeugenDim
...ZeittestErzeugenAnz
...ZeittestLoeschen
...Test
28
Die Klasse DIntervallHeap
Misst die Zeit, die benötigt wird
um 5 · 105 Objekte in einen d Intervall Heap mit 2 bis 30 Dimensionen einfügen.
Misst die Zeit, die benötigt wird
um einen d -Intervall Heap mit
106 Objekten und 1 bis 30 Dimensionen zu Erzeugen.
Misst die Zeit, die benötigt wird
um einen d -Intervall Heap mit 3
Dimensionen und 25 · 103 bis 5 ·
106 Objekten zu Erzeugen.
Misst die Zeit, die benötigt wird
um 5 · 104 Objekte aus einen d Intervall Heap mit 1 bis 30 Dimensionen zu löschen.
Erzeugt 5000 Heaps mit 32 · 103
Objekten und liest zufällig Extremelemente aus, bis der Heap
wieder leer ist.
Herunterladen