56
1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

Embed Size (px)

Citation preview

Page 1: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

1

Vorlesung Informatik 2

Algorithmen und Datenstrukturen

(16 – Fibonacci-Heaps)

T. Lauer

Page 2: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

2

Vorrangswarteschlangen

• Bekannte Datenstrukturen zum Einfügen und Entnehmen von Elementen

– Stapel (Stack): „last in – first out“

– Schlange (Queue): „first in – first out“

• Neue Struktur: Vorrangswarteschlange (Priority Queue)

– Elemente erhalten beim Einfügen einen Wert für ihre Priorität

– Es soll immer das Element mit höchster Priorität entnommen werden

– Veranschaulichung: „To-do“-Liste

Page 3: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

3

Vorrangswarteschlangen: Elemente

Ein Element (Knoten) enthält den eigentlichen Inhalt sowie die ihm zugeordnete Priorität.

Die Priorität muss mit einem Datentyp realisiert werden, auf dem eine Ordnung besteht.

Wir speichern die Priorität als int (wobei eine kleinere Zahl für eine höhere Priorität steht).

class Node { Object content; // Inhalt int key; // Prioritaet}

Page 4: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

4

Vorrangswarteschlangen (Priority Queues)

Kernoperationen:

Ein neues Element wird hinzugefügt (zusammen mit einer Priorität).

Das Element mit der höchsten Priorität wird entfernt.

Weitere Operationen:

Rückgabe des Elements mit höchster Priorität (ohne Entfernen).

Ein gegebenes Element wird „wichtiger“, d.h. seine Priorität erhöht sich.

Ein gegebenes Element wird überflüssig, d.h. es wird entfernt.

Zwei Vorrangswarteschlangen werden zusammengefügt.

Überprüfen, ob eine Vorrangswarteschlange leer ist.

Page 5: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

5

Vorrangswarteschlangen: Operationen

Operationen einer Vorrangswarteschlange (Priority Queue) Q:

Q.insert(int k): Füge einen neuen Knoten mit Schlüssel (= Priorität) k ein.

Q.accessmin(): Gib den Knoten mit niedrigstem Schlüssel (= der höchsten Priorität) zurück.

Q.deletemin(): Entferne den Knoten mit dem niedrigsten Schlüssel.

Q.decreasekey(Node N, int k): Setze den Schlüssel von Knoten N auf den Wert k herab.

Q.delete(Node N): Entferne den Knoten N.

Q.meld(PriorityQueue P): Vereinige Q mit der Vorrangswarteschlange P.

Q.isEmpty(): Gibt an, ob Q leer ist.

Bemerkung: Die effiziente Suche nach einem bestimmten Element oder Schlüssel wird in

Vorrangswarteschlangen nicht unterstützt! Für decreasekey und delete muss man das

entsprechende Element also bereits kennen bzw. Zugriff darauf haben.

Page 6: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

6

Implementationsmöglichkeit 1: Liste

Idee: Doppelt verkettete zirkuläre Liste mit Zeiger auf das Minimum (= Knoten mit

minimalem Schlüssel)

Operationen

insert: füge das neue Element ein und aktualisiere (falls nötig) den Minimum-

Zeiger

accessmin: gib den Minimalknoten zurück

deletemin: entferne den Minimalknoten, aktualisiere den Minimum-Zeiger

decreasekey: setze den Schlüssel herab und aktualisiere den Minimum-Zeiger

delete: falls der zu entfernende Knoten der Minimalknoten ist, führe deletemin

aus; ansonsten entferne den Knoten.

meld: hänge die beiden Listen aneinander

Page 7: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

7

Implementation als lineare Liste

7 15 9 2 1231

Page 8: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

8

Implementationsmöglichkeit 2: (Min-)Heap

Idee: Speichere die Elemente in einem heapgeordneten Array (vgl. Heap Sort)

Operationen

insert: füge das neue Element an der letzten Stelle ein und stelle durch

Vertauschungen die Heapordnung wieder her

accessmin: der Minimalknoten steht immer an der ersten Position

deletemin: ersetze das erste Element durch das letzte, dann versickere

decreasekey: setze den Schlüssel herab und stelle durch Vertauschungen die

Heapordnung wieder her

delete: ersetze das entfernte Element durch das letzte, dann versickere

meld: füge alle Elemente des kleineren Heaps nacheinander in den größeren

ein

Page 9: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

9

Implementation als Min-Heap

7

159

2

12

31

2 7 12 31 9 15

Page 10: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

10

Implementation als Min-Heap

7

159

2

12

31

2 7 12 31 9 15

Page 11: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

11

Implementationen: Vergleich

Lineare Liste (Min-)Heap ???

insert: O(1) O(log n) O(1)

accessmin: O(1) O(1) O(1)

deletemin: O(n) O(log n) O(log n)

decreasekey: O(1) O(log n) O(1)

delete: O(n) O(log n) O(log n)

meld: O(1) O(m log(n+m)) O(1)

Frage: Lassen sich die Vorteile von Listen und Heaps verbinden?

Page 12: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

12

Fibonacci-Heaps: Idee

• Liste von Bäumen (beliebigen Verzweigungsgrades), die alle heapgeordnet sind.

Definition:

Ein Baum heißt (min-)heapgeordnet, wenn der Schlüssel jedes Knotens größer

oder gleich dem Schlüssel seines Vaterknotens ist (sofern er einen Vater hat).

• Die Wurzeln der Bäume sind in einer doppelt verketteten, zirkulären Liste

miteinander verbunden (Wurzelliste).

• Der Einstiegspunkt ist ein Zeiger auf den Knoten mit minimalem Schlüssel.

2 19

13 45 8

36 21

24

15 83 52

79

117

Page 13: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

13

Exkurs: Bäume

Bäume lassen sich als Verallgemeinerung von Listen auffassen:

• Es gibt genau ein Anfangselement („Wurzel“).

• Jedes Element kann beliebig viele Nachfolger („Söhne“) haben.

• Jedes Element (außer der Wurzel) ist Nachfolger von genau einem Knoten.

class Tree { TreeNode root;}

class TreeNode { int key; Node[] children;}

2

13 45 8

36 2115

10

Page 14: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

14

Repräsentation von Bäumen

Bei Bäumen mit hohem Verzweigungsgrad ist es aus Speicherplatzgründen

ungünstig, in jedem Knoten Zeiger auf alle Söhne zu speichern.

class TreeNode { int key; Node[] children;}

Eine platzsparende Alternative ist die Child-Sibling-Darstellung: hier sind alle Söhne in

einer Liste untereinander verkettet. Dadurch genügt es, im Vaterknoten einen

Zeiger auf den ersten Sohn zu speichern.

class ChildSiblingNode { int key; Node child; Node sibling;}

13 45 8 10

2

25 ...

13 45 8 10

2

25 ...

Page 15: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

15

Child-Sibling-Repräsentation

• Um sich im Baum auch aufwärts bewegen zu können, fügt man einen Zeiger auf

den Vaterknoten hinzu.

• Um das Entfernen von Söhnen (und das Aneinanderhängen von Sohn-Listen) in

O(1) zu realisieren, verwendet man doppelt verkettete zirkuläre Listen.

• Also hat jeder Knoten 4 Zeiger: child, parent, left, right

2

13 45 8

36 2115

2

13 45 8

36 2115

2

13 45 8

36 2115

Page 16: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

16

Fibonacci-Heaps: Knotenformat

class FibNode { Object content; // der eigentliche Inhalt int key; // Schlüssel (Priorität) FibNode parent, child; // Zeiger auf Vater und einen Sohn FibNode left, right; // Zeiger auf linken und rechten

Nachbarn

int rank; // Anzahl der Söhne dieses Knotens boolean mark; // Markierung}

Die Zahl rank gibt an, wie viele Söhne der Knoten hat (= der Rang des Knotens)

Die Bedeutung der Markierung mark wird später deutlich. Diese Markierung gibt an, ob der Knoten bereits einmal einen seiner Söhne verloren hat, seitdem er selbst zuletzt Sohn eines anderen Knotens geworden ist.

Page 17: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

17

Fibonacci-Heap: Detaillierte Darstellung

2 19

13 45 8

36 21

24

15 83 52

79

117

Page 18: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

18

Fibonacci-Heap: Vereinfachte Darstellung

2 19

13 45 8

36 21

24

15 83 52

79

117

Page 19: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

19

Fibonacci-Heaps: Operationen

• Q.accessmin(): Gib den Knoten Q.min zurück (bzw. null, wenn Q leer ist).

• Q.insert(int k): Erzeuge einen neuen Knoten N mit Schlüssel k und füge ihn

in die Wurzelliste von Q ein. Falls k < Q.min.key, aktualisiere den Minimum-

Zeiger (setze Q.min = N). Gib den neu erzeugten Knoten zurück.

2 19

13 45 8

36 21

24

15 83 52

79

117

Page 20: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

20

Manipulation von Bäumen in Fibonacci-Heaps

Drei Basis-Methoden zur Manipulation von Bäumen in Fibonacci-Heaps:

link: „Wachstum“ von Bäumen.

Zwei Bäume werden zu einem neuen verbunden.

cut: „Beschneiden“ von Bäumen im Inneren.

Ein Teilbaum wird aus einem Baum herausgetrennt und als neuer Baum in die

Wurzelliste eingefügt.

remove: „Spalten“ von Bäumen an der Wurzel.

Entfernt die Wurzel eines Baums und fügt die Söhne der Wurzel als neue Bäume

in die Wurzelliste ein.

Page 21: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

21

Baummanipulation: link

link:

Input: 2 Knoten mit demselben Rang k in der Wurzelliste

Methode: vereinigt zwei Bäume mit gleichem Rang, indem die Wurzel mit größerem

Schlüssel zu einem neuen Sohn der Wurzel mit kleinerem Schlüssel gemacht wird.

Die Gesamtzahl der Bäume verringert sich um 1, die Knotenzahl ändert sich nicht.

Output: 1 Knoten mit Rang k+1

Laufzeit:

2

13 8

36 21

24

83 52

2

13 8

36 21

24

83 52

Page 22: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

22

Baummanipulation: cut

cut:

Input: 1 Knoten, der nicht in der Wurzelliste ist

Methode: trennt den Knoten (samt dem Teilbaum, dessen Wurzel er ist) von seinem

Vater ab und fügt ihn als neuen Baum in die Wurzelliste ein.

Die Gesamtzahl der Bäume erhöht sich um 1, die Knotenzahl ändert sich nicht.

Laufzeit:

2

13 45 8

36 2115

26

2

13 45 8

36

21

15

26

Page 23: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

23

Baummanipulation: remove

remove:

Input: 1 Knoten mit Rank k aus der Wurzelliste

Methode: entfernt die Wurzel eines Baums und fügt stattdessen seine k Söhne in die

Wurzelliste ein. Die Zahl der Bäume erhöht sich um k-1, die Gesamtzahl der

Knoten verringert sich um 1.

Laufzeit: [sofern die Vaterzeiger der Söhne nicht gelöscht

werden!]

2

13 45 8

36 2115

26

13 45 8

36 2115

26

Page 24: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

24

Weitere Operationen

• Mit Hilfe der drei Manipulationsmethoden

– link

– cut

– remove

lassen sich die noch fehlenden Operationen

– deletemin

– decreasekey

– delete

beschreiben.

Page 25: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

25

Entfernen eines Knotens

Q.deletemin():

• Wenn Q leer ist, gib null zurück.

• Andernfalls:

– Entferne den Minimalknoten (mit remove).

– „Konsolidiere“ die Wurzelliste:Verbinde (mit link) je zwei Wurzelknoten mit demselben Rang, und zwar solange, bis nur noch Knoten mit unterschiedlichem Rang in der Wurzelliste vorkommen.Lösche dabei die Markierungen der Knoten, die zum Sohn eines anderen werden, und entferne außerdem evtl. vorhandene Vaterzeiger der Wurzelknoten.

– Finde unter den Wurzelknoten das neuen Minimum.

– Gib den entfernten Knoten zurück.

Page 26: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

26

deletemin: Beispiel

2 19

13 45 8

36 21

24

15 83 52

79

117

Page 27: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

27

deletemin: Beispiel

19

24

83 52

79

117 13 45 8

36 2115

Page 28: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

28

deletemin: Beispiel

19

24

83 52

79

117

1345 8

36 2115

Page 29: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

29

Herabsetzen eines Schlüssels

Q.decreasekey(FibNode N, int k):

• Setze den Schlüsselwert von N auf k herab.

• Wenn die Heap-Bedingung nicht mehr erfüllt ist (k < N.parent.key):

– Trenne N von seinem Vater ab (mit cut)

– Falls der Vater markiert ist (N.parent.mark == true), trenne auch ihn

von seinem Vater ab; wenn auch dessen Vater markiert ist, trenne auch diesen

ab, usw. („cascading cuts“)

– Markiere den Knoten, dessen Sohn zuletzt abgetrennt wurde (sofern dieser

kein Wurzelknoten ist).

– Aktualisiere den Minimum-Zeiger (falls k < min.key).

Page 30: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

30

decreasekey: Beispiel 1

2 19

13 45 8

36 21

24

15 83 52

79

117

Page 31: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

31

decreasekey: Beispiel 2

2 19

13 45 8

36 21

24

15 83 52

79

117

Page 32: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

32

Entfernen eines Knotens

Q.delete(FibNode N):

• Falls N == Q.min, führe Q.deletemin() aus.

• Andernfalls:

– Falls N nicht in der Wurzelliste ist:

• Trenne N von seinem Vater ab (mit cut)

• Falls der Vater markiert ist (N.parent.mark == true), trenne auch ihn von seinem Vater ab; wenn auch dessen Vater markiert ist, trenne auch diesen ab, usw. („cascading cuts“)

• Markiere den Knoten, dessen Sohn zuletzt abgetrennt wurde (sofern dieser kein Wurzelknoten ist).

– Entferne N aus der Wurzelliste (mit remove).

Page 33: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

33

delete: Beispiel

2 19

13 45 8

36 21

24

15 83 52

79

117

Page 34: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

34

Weitere Operationen

• Q.meld(FibHeap P): Hänge die Wurzelliste von P an die Wurzelliste von Q an.

Aktualisiere den Minimum-Zeiger von Q: falls P.min.key < Q.min.key, setze

Q.min = P.min.

• Q.isEmpty(): Falls Q.size == 0, gib true zurück; ansonsten false.

Page 35: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

35

Laufzeiten

Lineare Liste (Min-)Heap Fibonacci-Heap

insert: O(1) O(log n) O(1)

accessmin: O(1) O(1) O(1)

deletemin: O(n) O(log n) ?

decreasekey: O(1) O(log n) ?

delete: O(n) O(log n) ?

meld: O(1) O(m log(n+m)) O(1)

Page 36: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

36

Laufzeitanalyse

Laufzeit von deletemin():

remove: O(1)

consolidate: ?

updatemin: O(#Wurzelknoten nach consolidate) =

Nach dem Konsolidieren gibt es von jedem Rang nur noch höchstens einen

Wurzelknoten.

Definiere maxRank(n) als den höchstmöglichen Rang, den ein Wurzelknoten in einem

Fibonacci-Heap der Größe n haben kann. (Berechnung von maxRank(n) später.)

Nun müssen wir die Komplexität von consolidate bestimmen.

Page 37: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

37

deletemin: Konsolidieren der Wurzelliste

• Wie kann man das Konsolidieren effizient realisieren?

• Beobachtungen:

– Jeder Wurzelknoten muss mindestens einmal betrachtet werden

– Am Ende darf es für jeden möglichen Rang höchstens einen Knoten geben

• Idee: Trage die Wurzelknoten in ein temporär geschaffenes Array ein. Jeder

Knoten wird an der Arrayposition eingetragen, die seinem Rang entspricht. Ist eine

Position schon besetzt, so weiß man, dass es einen weiteren Knoten mit

demselben Rang gibt, kann diese beiden mit link verschmelzen und den neuen

Baum an der nächsthöheren Position im Array eintragen.

Page 38: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

38

consolidate: Beispiel

1913 45 8

36 21 2415

83 52

79

117

0 1 2 3 4 5Rang-Array:

Page 39: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

39

Analyse von consolidate

rankArray = new FibNode[maxRank(n)+1]; // Erstelle das

Array

for „each FibNode N in rootlist“ {

while (rankArray[N.rank] != null) { // Position besetzt

N = link(N, rankArray[N.rank]); // Verbinde Bäume

rankArray[N.rank-1] = null; // Lösche alte Pos.

}

rankArray[N.rank] = N; // Eintragen in

Array

}

Page 40: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

40

Analyse

for „each FibNode N in rootlist“ {

while (rankArray[N.rank] != null) {

N = link(N, rankArray[N.rank]);

rankArray[N.rank-1] = null;

}

rankArray[N.rank] = N;

}

Sei k = #Wurzelknoten vor dem Konsolidieren. Diese k Knoten lassen sich aufteilen in

W = {Knoten, die am Ende noch in der Wurzelliste sind}

L = {Knoten, die an einen anderen Knoten angehängt wurden}

Es gilt: |W| + |L| = k und T(consolidate) = T(W) + T(L) + maxRank(n)

Kosten(L) =

Kosten(W) =

Page 41: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

41

Gesamtkosten von deletemin

remove: O(1)

Erstellen des Rang-Arrays: O(maxRank(n))

link-Operationen: #links · O(1)

Restl. Eintragungen: O(maxRank(n))

Update Minimum-Zeiger: O(maxRank(n))

Gesamtkosten: O(#links) + O(maxRank(n))

Page 42: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

42

Laufzeitanalyse

Laufzeit von decreasekey():

Schlüssel neu setzen: O(1)

cut: O(1)

Cascading cuts: #cuts · O(1)

Markieren: O(1)

Gesamtkosten: O(#cuts)

Page 43: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

43

Laufzeitanalyse

Laufzeit von delete():

• Falls der entfernte Knoten der Minimalknoten ist, sind die Kosten gleich wie bei

deletemin: O(#links) + O(maxRank(n))

• Ansonsten sind sie ähnlich wie bei decreasekey:

cut: O(1)

Cascading cuts: #cuts · O(1)

Markieren: O(1)

remove: O(1)

Gesamtkosten: O(#cuts)

Page 44: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

44

Amortisierte Analyse

Beobachtungen:

Bei deletemin beeinflusst die Zahl der link-Operationen die tatsächliche Laufzeit.

Bei decreasekey und delete ist es die Zahl der cascading cuts.

Idee: Spare dafür Guthaben an (Bankkonto-Paradigma)!

Annahme: Die Kosten pro link und pro cut seien jeweils 1€.

(1) Sorge dafür, dass für jeden Wurzelknoten immer 1€ Guthaben vorhanden ist,

mit dem sich die link-Operation bezahlen lässt, wenn dieser Knoten an einen

anderen angehängt wird.

(2) Sorge dafür, dass für jeden markierten Knoten, der nicht in der Wurzelliste ist,

immer 2€ Guthaben vorhanden sind. Damit kann man bei „cascading cuts“

das Abtrennen (cut) dieses Knotens bezahlen und hat noch 1€ übrig für (1).

Page 45: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

45

Beispiel

Page 46: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

46

Guthaben ansparen

Wann müssen wir etwas dazu bezahlen?

Neue Wurzelknoten können entstehen bei:

– insert: gib dem neu eingefügten Wurzelknoten noch 1€ dazu.

– decreasekey: bezahle 1€ für den abgetrennten Knoten dazu.

– remove: bezahle für jeden Sohn des entfernten Knotens 1€ dazu,

insgesamt also bis zu maxRank(n) €.

Markierte Knoten können nur am Ende von decreasekey und delete entstehen:

– Bezahle beim Markieren zusätzlich 2€ für den markierten Knoten.

Page 47: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

47

Amortisierte Kosten von insert

Erstellen des Knotens: O(1)

Einfügen in Wurzelliste: O(1) + O(1)

Amortisierte Gesamtkosten: O(1)

Page 48: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

48

Amortisierte Kosten von deletemin

remove: O(1) + O(maxRank(n))

Erstellen des Rang-Arrays: O(maxRank(n))

link-Operationen: #links · O(1) wird vom Guthaben bezahlt!

Restl. Eintragungen: O(maxRank(n))

Update Minimum-Zeiger: O(maxRank(n))

Amortisierte Gesamtkosten: O(maxRank(n))

Page 49: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

49

Amortisierte Kosten von decreasekey

Schlüsselwert neu setzen: O(1)

cut: O(1)

Cascading cuts: #cuts · O(1) wird vom Guthaben bezahlt!

Markieren: O(1) + 2 · O(1)

Amortisierte Gesamtkosten: O(1)

Page 50: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

50

Amortisierte Kosten von delete

• Falls der entfernte Knoten der Minimalknoten ist, sind die Kosten dieselben wie bei

deletemin: O(maxRank(n))

• Ansonsten:

cut: O(1)

Cascading cuts: #cuts · O(1) wird vom Guthaben bezahlt!

Markieren: O(1) + 2 · O(1)

remove: O(1) + O(maxRank(n))

Amortisierte Gesamtkosten: O(maxRank(n))

Page 51: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

51

Amortisierte Analyse

Amortisierte Kosten

• Insert: O(1)

• Accessmin: O(1)

• Deletemin: O(maxRank(n))

• Decreasekey: O(1)

• Delete: O(maxRank(n))

• Meld: O(1)

Noch zu zeigen: maxRank(n) = O(log n). D.h. der maximale Rang eines Knotens in

einem Fibonacci-Heap ist logarithmisch in der Größe n des Fibonacci-Heaps.

Page 52: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

52

Berechnung von maxRank(n)

Erinnerung: Fibonacci-Zahlen (Übungsblatt 4, Aufgabe 1; Kapitel 10)

F0 = 0

F1 = 1

Fk+2 = Fk+1 + Fk für k ≥ 0

Die Folge der Fibonacci-Zahlen wächst exponentiell mit Fk+2 ≥ 1.618k

Es gilt außerdem: Fk+2 =

(Beweis durch vollständige Induktion über k.)

k

iiF

1

1

Page 53: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

53

Berechnung von maxRank(n)

Lemma 1:

Sei N ein Knoten in einem Fibonacci-Heap und k = N.rank. Betrachte die Söhne

C1, ..., Ck von N in der Reihenfolge, in der sie (mit link) zu N hinzugefügt wurden.

Dann gilt:

(1) C1.rank ≥ 0

(2) Ci.rank ≥ i - 2 für i = 2, ..., k

Beweis: (1) klar

(2) Als Si zum Sohn von N wurde, waren C1, ..., Ci-1 schon Söhne von N,

d.h. es war N.rank ≥ i-1. Da durch link immer Knoten mit gleichem Rang

verbunden werden, war beim Einfügen also auch Ci.rank ≥ i-1. Seither kann

Ci höchstens einen Sohn verloren haben (wegen cascading cuts), daher

muss gelten: Ci.rank ≥ i - 2

Page 54: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

54

Berechnung von maxRank(n)

Lemma 2:

Sei N ein Knoten in einem Fibonacci-Heap und k = N.rank.

Sei size(N) = die Zahl der Knoten im Teilbaum mit Wurzel N.

Dann gilt: size(N) ≥ Fk+2 ≥ 1.618k

D.h. ein Knoten mit k Söhnen hat mind. Fk+2 Nachkommen (inkl. sich selbst).

Beweis: Sei Sk = min {size(N) | N mit N.rank = k}, d.h. die kleinstmögliche Größe

eines Baums mit Wurzelrang k. (Klar: S0 = 1 und S1 = 2.)

Seien wieder C1, ..., Ck die Söhne von N in der Reihenfolge, in der sie zu N

hinzugefügt wurden.

Es ist size(N) ≥ Sk ≥

Page 55: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

55

Berechnung von maxRank(n)

Satz:

Der maximale Rang maxRank(n) eines beliebigen Knotens in einem

Fibonacci-Heap mit n Knoten ist beschränkt durch O(log n).

Beweis: Sei N ein Knoten eines Fibonacci-Heaps mit n Knoten und sei k = N.rank.

Es ist n ≥ size(N) ≥ 1.618k (nach Lemma 2)

Daher istk ≤ log1.618(n) = O(log n)

Page 56: 1 Vorlesung Informatik 2 Algorithmen und Datenstrukturen (16 – Fibonacci-Heaps) T. Lauer

56

Zusammenfassung

Lineare Liste (Min-)Heap Fibonacci-Heap

insert: O(1) O(log n) O(1)

accessmin: O(1) O(1) O(1)

deletemin: O(n) O(log n) O(log n)*

decreasekey: O(1) O(log n) O(1)*

delete: O(n) O(log n) O(log n)*

meld: O(1) O(m log(n+m)) O(1)

*Amortisierte Kosten