127
Amortisierte Analyse und Fibonacci Heaps

Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

Embed Size (px)

Citation preview

Page 1: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

Amortisierte Analyse und

Fibonacci Heaps

Page 2: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

2

Amortisierte Analyse - Modell

• Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit häufig ungeeignet

• Idee: Statt Einzeloperationen, betrachte Sequenz von Operationen Op1-Opn

• Die Datenstruktur durchläuft dabei die Zustände S0…Sn

• Die Laufzeiten für die Operationen sind T1…Tn

• Die Gesamtzeit beträgt somit T = i Ti

• Die Abschätzung bezieht sich auf die Sequenz, gibt aber durchschnittliche Kosten für die Einzeloperationen an!

Page 3: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

3

Amortisierte Analyse

• Begriff der Amortisierung stammt aus der BWL:Eine teure Investition zahlt sich über längere Sicht hin aus und wird über die gesamte Zeit der Wirksamkeit der Investition amortisiert.

• Auf Algorithmen zum ersten Mal Anfang der 80er Jahre angewandt [Brown, Huddleston, Mehlhorn, Sleator, Tarjan u.a.]

• Abgrenzung zur Average-Case-Analyse– Keine Wahrscheinlichkeiten notwendig!

– Ergebnis: durchschnittliche Laufzeit jeder Operation im schlimmsten Fall! Leistungsgarantie!

Page 4: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

4

Beispiel: Binärzähler

• Sequenz: Zählen für k = 0…N

• Operation: Inkrementieren

• Kosten: Ändern einer Ziffer

(0!1 oder 1!0)

• Betrachte

– Kosten pro Operation Tk+1

(# invertierte Bits für k ! k + 1)

– Gesamtkosten T

k bin(k)0 0000001 0000012 0000103 0000114 0001005 0001016 0001107 0001118 0010009 001001

10 00101011 00101112 00110013 00110114 00111015 00111116 010000

Page 5: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

5

Beispiel: Binärzähler

• Beobachtung1 · Tk · 1 + d log k e

• Worst-Case-AbschätzungTk = 1 + d log k e

T = N ¢ (1+ d log N e)

k bin(k) Tk

0 000000 01 000001 12 000010 23 000011 14 000100 35 000101 16 000110 17 000111 28 001000 49 001001 1

10 001010 211 001011 212 001100 313 001101 114 001110 215 001111 116 010000 5

Page 6: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

6

Beispiel: Binärzähler

• Beobachtung1 · Tk · 1 + d log k e

• Worst-Case-AbschätzungTk = 1 + d log k e

T = N ¢ (1+ d log N e)

• Weitere Beobachtung Tk · 2 k

k bin(k) Tk Tk

0 000000 0 01 000001 1 12 000010 2 33 000011 1 44 000100 3 75 000101 1 86 000110 1 97 000111 2 118 001000 4 159 001001 1 16

10 001010 2 1811 001011 2 2012 001100 3 2313 001101 1 2414 001110 2 2615 001111 1 2716 010000 5 32

Page 7: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

7

Beispiel: Binärzähler

Page 8: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

8

Beispiel: Binärzähler

Page 9: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

9

Binärzähler: Analyse

k bin(k) Tk Tk

0 000000 0 01 000001 1 12 000010 2 33 000011 1 44 000100 3 75 000101 1 86 000110 1 97 000111 2 118 001000 4 159 001001 1 16

10 001010 2 1811 001011 2 2012 001100 3 2313 001101 1 2414 001110 2 2615 001111 1 2716 010000 5 32

Page 10: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

10

Binärzähler: Analyse

• B[0] wird jeden Schritt invertiert

k bin(k) Tk Tk

0 000000 0 01 000001 1 12 000010 2 33 000011 1 44 000100 3 75 000101 1 86 000110 1 97 000111 2 118 001000 4 159 001001 1 16

10 001010 2 1811 001011 2 2012 001100 3 2313 001101 1 2414 001110 2 2615 001111 1 2716 010000 5 32

Page 11: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

11

Binärzähler: Analyse

• B[0] wird jeden Schritt invertiert

• B[1] wird jeden zweiten Schritt invertiert

• B[k] wird alle 2k Schritte invertiert

k bin(k) Tk Tk

0 000000 0 01 000001 1 12 000010 2 33 000011 1 44 000100 3 75 000101 1 86 000110 1 97 000111 2 118 001000 4 159 001001 1 16

10 001010 2 1811 001011 2 2012 001100 3 2313 001101 1 2414 001110 2 2615 001111 1 2716 010000 5 32

Page 12: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

12

Binärzähler: Analyse

• Addition über die Zeilen der Tabelle lieferte uns

• Addition über die Spalten hingegen

• Laufzeit für das Zählen von k = 0…N: O(N)• Amortisierte Laufzeit für Inkrement: O(N)/N = O(1)

Page 13: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

13

Aggregatmethode

• Berechne die Gesamtkosten für eine Sequenz von Operationen

• Division der Gesamtkosten durch die Zahl der Operationen liefert amortisierte Kosten pro Operation

Dieses Vorgehen heißt Aggregatmethode und ist die einfachste Technik der amortisierten Analyse. Die zweite wichtige Technik ist die Bankkonto-Methode (siehe 5. Übungsblatt!)

Page 14: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

14

Potenzialmethode

• Idee: Operationen können potenzielle Energie erzeugen/verbrauchen

• Die Funktion ordnet jedem Zustand Si unserer Datenstruktur ein Potenzial (Si) zu

• Die amortisierten Kosten ai der Operation Opi hängen von den tatsächlichen Kosten ci und dem Potenzial ab

• Die Gesamtkosten der N Operationen sind damit

Page 15: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

15

Potenzialfunktionen

• „Billige Operationen“ erhöhen das Potenzial über ihre eigenen Kosten hinaus:

ai > ci

• „Teure Operationen“ verringern das Potenzial, bezahlen also einen Teil der Operation mit dem was die vorhergehenden billigen Operationen an „Potenzieller Energie“ angesammelt haben:

ai < ci

• Für (SN) ¸ (S0) sind die amortisierten Kosten der N Operationen eine obere Schranke für die tatsächlichen Kosten

Page 16: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

16

Potenzialverlauf

iN

Page 17: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

17

Binärzähler mit der Potenzialmethode

Definiere das Potenzial als Anzahl der gesetzten Bits im derzeitigen Zählerstand:

(Si) = i = #1 2 bin(i)

Der Zählerstand sei i und der Übergang zu i+1 soll ti Bits zurücksetzen (1! 0). Ferner wird maximal ein weiteres Bit gesetzt

) ci = ti + 1

Für die Potenzialänderung gilt dann:

i - i-1 · i-1 - ti + 1 - i-1 = 1- ti

Damit gilt für die amortisierten Kosten:

ai = ci + 1 - i-1 · (ti+1) + (1– ti) = 2 ) O(1)

Page 18: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

18

Amortisierte Analyse von Heaps

Operation Binärer Heap Binomial-Heap

insert O(log N) O(log N)

find_min O(1) O(1)

delete_min O(log N) O(log N)

decrease_key O(log N) O(log N)

create O(N) O(N)

merge O(N) O(log N)

Page 19: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

19

Amortisierte Analyse von Heaps

Operation Binärer Heap Binomial-Heap Fibonacci-Heap

insert O(log N) O(log N) ?

find_min O(1) O(1) ?

delete_min O(log N) O(log N) ?

decrease_key O(log N) O(log N) ?

create O(N) O(N) ?

merge O(N) O(log N) ?

Page 20: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

20

Fibonacci-Heaps

Def.: Ein Fibonacci-Heap ist eine Datenstruktur, die

einen Wald von Bäumen mit Heapeigenschaft

besitzt. Jeder der Knoten (außer den Wurzeln) trägt

ein zusätzliches Markierungsbit mark. Das Element

min zeigt auf die kleinste Wurzel des Walds. Die

Wurzeln sind doppelt zyklisch verkettet, ebenso die

Kinder eines jeden Knotens.

Page 21: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

21

Fibonacci-Heaps

Def.: Ein Fibonacci-Heap ist eine Datenstruktur, die einen Wald von Bäumen mit

Heapeigenschaft besitzt. Jeder der Knoten (außer den Wurzeln) trägt ein

zusätzliches Markierungsbit mark. Das Element min zeigt auf die kleinste Wurzel

des Walds. Die Wurzeln sind doppelt zyklisch verkettet, ebenso die Kinder eines

jeden Knotens.

=

Page 22: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

22

Fibonacci-Heaps

Def.: Ein Fibonacci-Heap ist eine Datenstruktur, die einen Wald von Bäumen mit

Heapeigenschaft besitzt. Jeder der Knoten (außer den Wurzeln) trägt ein

zusätzliches Markierungsbit mark. Das Element min zeigt auf die kleinste Wurzel

des Walds. Die Wurzeln sind doppelt zyklisch verkettet, ebenso die Kinder eines

jeden Knotens.

Page 23: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

23

Fibonacci-Heaps

Def.: Ein Fibonacci-Heap ist eine Datenstruktur, die einen Wald von Bäumen mit

Heapeigenschaft besitzt. Jeder der Knoten (außer den Wurzeln) trägt ein

zusätzliches Markierungsbit mark. Das Element min zeigt auf die kleinste Wurzel

des Walds. Die Wurzeln sind doppelt zyklisch verkettet, ebenso die Kinder eines

jeden Knotens.

min

Page 24: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

24

Fibonacci-Heaps

Def.: Ein Fibonacci-Heap ist eine Datenstruktur, die einen Wald von Bäumen mit

Heapeigenschaft besitzt. Jeder der Knoten (außer den Wurzeln) trägt ein

zusätzliches Markierungsbit mark. Das Element min zeigt auf die kleinste Wurzel

des Walds. Die Wurzeln sind doppelt zyklisch verkettet, ebenso die Kinder eines

jeden Knotens.

3 12 23 24 8

8827 52 11

99 77

5 9

22

min

Page 25: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

25

Fibonacci-Heaps

Def.: Ein Fibonacci-Heap ist eine Datenstruktur, die einen Wald von Bäumen mit

Heapeigenschaft besitzt. Jeder der Knoten (außer den Wurzeln) trägt ein

zusätzliches Markierungsbit mark. Das Element min zeigt auf die kleinste Wurzel

des Walds. Die Wurzeln sind doppelt zyklisch verkettet, ebenso die Kinder eines

jeden Knotens.

3 12 23 24 8

8827 52 11

99 77

5 9

22

min

Page 26: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

26

Fibonacci-Heaps

Def.: Ein Fibonacci-Heap ist eine Datenstruktur, die einen Wald von Bäumen mit

Heapeigenschaft besitzt. Jeder der Knoten (außer den Wurzeln) trägt ein

zusätzliches Markierungsbit mark. Das Element min zeigt auf die kleinste Wurzel

des Walds. Die Wurzeln sind doppelt zyklisch verkettet, ebenso die Kinder eines

jeden Knotens.

3 12 23 24 8

8827 52 11

99 77

5 9

22

min

mark = true

mark = false

Page 27: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

27

FibonacciHeap – Interfacetemplate <typename Key, typename Inf>class FibonacciHeap{ public: typedef std::pair<Key, Inf> Item; typedef FibonacciNode* NodePtr; const Item& find_min() const; void delete_min(); void insert(const Item& item);

void create(const std::vector<Item>& array); void merge(FibonacciHeap& heap); void decrease_key(NodePtr item, const Key& key);

Page 28: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

28

FibonacciHeap – Interface protected: // Hilfsmethoden void consolidate(); void cut(NodePtr node); void cascading_cut(NodePtr node); void link(NodePtr root, NodePtr child); void insert_into_rootlist(NodePtr node); void erase_from_rootlist(NodePtr node); unsigned int max_deg() const; // max. Grad der Wurzeln

// Attribute int number_of_nodes; // Gesamtzahl Knoten NodePtr min; // Minmale Wurzel // min ist auch der Anfang der Wurzelliste!};

Page 29: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

29

FibonacciNode – Interfacetemplate <typename Key, typename Inf>class FibonacciNode{ public: typedef FibonacciNode* NodePtr;

const Key& key() const { return key; } Key& key() { return key; } // Accessoren für Attribute […] unsigned int degree() const; // Grad = Anzahl Kinder void remove_child(NodePtr child); // Entferne Kind aus Liste protected: Key key; // Der Schlüssel Inf inf; // Die Information NodePtr left; // Linker Geschwisterknoten NodePtr right; // Rechter Geschwisterknoten NodePtr parent; // Elterknoten NodePtr first_child; // Erster Kinderknoten bool mark; // Markierung};

23 24

8827 52

99 77

Page 30: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

30

find_min, merge im Fibonacci-Heap

• merge – Vereinige die Wurzellisten

– min(H) = min(min(H1), min(H2))

) O(1)• find_min: O(1)

3 12 23 24 8

8827 52 11

99 77

5 9

22

min

5 2 14

7817 429 7

min

Page 31: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

31

insert im Fibonacci-Heaps

3 12 23 24 8

8827 52 11

99 77

5 9

22

min

1

Knoten wird neben dem Minimum in der Wurzelliste eingefügt, der Zeiger auf das Minimum gegebenenfalls angepasst

) O(1)

Page 32: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

32

insert im Fibonacci-Heaps

3 12 23 24 8

8827 52 11

99 77

5 9

22

min

1

Knoten wird neben dem Minimum in der Wurzelliste eingefügt, der Zeiger auf das Minimum gegebenenfalls angepasst

) O(1)

Page 33: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

33

2314

8827 52

99 77

min

delete_min im Fibonacci-Heapvoid delete_min(){ NodePtr node = min(); if (node == 0) throw “Empty heap!“;

Für jedes Kind child von node: child.parent = 0; insert_into_rootlist(child);

erase_from_rootlist(node); if (node->right == node) { min() = 0; } else { min() = node->right; consolidate(); } delete node; number_of_nodes--;}

Page 34: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

34

delete_min im Fibonacci-Heapvoid delete_min(){ NodePtr node = min(); if (node == 0) throw “Empty heap!“;

Für jedes Kind child von node: child.parent = 0; insert_into_rootlist(child); erase_from_rootlist(node); if (node->right == node) { min() = 0; } else { min() = node->right; consolidate(); } delete node; number_of_nodes--;}

2314

min

27

99

88 52

77

Page 35: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

35

delete_min im Fibonacci-Heapvoid delete_min(){ NodePtr node = min(); if (node == 0) throw “Empty heap!“;

Für jedes Kind child von node: child.parent = 0; insert_into_rootlist(child); erase_from_rootlist(node); if (node->right == node) { min() = 0; } else { min() = node->right; consolidate(); } delete node; number_of_nodes--;}

23

min

27

99

8852

77

14

Page 36: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

36

delete_min im Fibonacci-Heapvoid delete_min(){ NodePtr node = min(); if (node == 0) throw “Empty heap!“;

Für jedes Kind child von node: child.parent = 0; insert_into_rootlist(child); erase_from_rootlist(node); if (node->right == node) { min() = 0; } else { min() = node->right; consolidate(); } delete node; number_of_nodes--;}

23

min

27

99

8852

77

14

Page 37: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

37

consolidate im Fibonacci-Heap

• insert und delete_min erhöhen die Anzahl der

Bäume

• Gelegentlich muss die Zahl der Bäume reduziert

werden ) consolidate

• Idee: Verschmelze Bäume gleichen Grads in der

Wurzel bis nur noch Bäume mit unterschiedlichem

Grad übrig bleiben. Erhalte dabei die

Heapeigenschaft.

Page 38: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

38

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0; // Löscht Wurzelliste!

23

min

27

99

8852

77

A 0 0 0 0 0 0 0 0

d 0 x y

Page 39: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

39

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0 0 0

d 0 x y

Page 40: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

40

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0 0 0

d 1 x y

Page 41: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

41

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0 0 0

d 1 x y

Page 42: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

42

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0 0 0

d 1 x y

Page 43: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

43

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0 0

d 1 x y

Page 44: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

44

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0 0

d 1 x y

Page 45: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

45

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0 0

d 0 x y

Page 46: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

46

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0 0

d 0 x y

Page 47: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

47

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0

d 0 x y

Page 48: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

48

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0

d 0 x y

Page 49: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

49

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0

d 1 x y

Page 50: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

50

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0

d 1 x y

Page 51: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

51

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0

d 1 x y

Page 52: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

52

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0

d 1 x y

Page 53: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

53

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

8852

77

A 0 0 0 0 0 0

d 1 x yvoid link(NodePtr root, NodePtr child){ remove_from_root_list(child); root.insert_child(child); child->mark() = false;}

Page 54: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

54

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 1 x yvoid link(NodePtr root, NodePtr child){ remove_from_rootlist(child); root.insert_child(child); child->mark() = false;}

Page 55: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

55

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 1 x yvoid link(NodePtr root, NodePtr child){ remove_from_rootlist(child); root.insert_child(child); child->mark() = false;}

Page 56: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

56

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 1 x y

Page 57: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

57

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0 0

d 1 x y

Page 58: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

58

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0 0

d 2 x y

Page 59: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

59

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 2 x y

Page 60: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

60

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 2 x y

Page 61: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

61

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 0 x y

Page 62: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

62

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 0 x y

Page 63: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

63

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 0 x y

Page 64: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

64

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 0 x y

Page 65: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

65

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

99

88

52

77

A 0 0 0 0 0 0

d 0 x y

Page 66: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

66

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

9988

52

77

A 0 0 0 0 0 0

d 0 x y

Page 67: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

67

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

9988

52

77

A 0 0 0 0 0 0 0

d 1 x y

Page 68: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

68

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

9988

52

77

A 0 0 0 0 0 0 0

d 1 x y

Page 69: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

69

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

9988

52

77

A 0 0 0 0 0 0

d 1 x y

Page 70: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

70

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

9988

52

77

A 0 0 0 0 0 0

d 1 x y

Page 71: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

71

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

9988

52

77

A 0 0 0 0 0 0

d 1 x y

Page 72: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

72

consolidate im Fibonacci-Heapvoid consolidate(){ vector<NodePtr> A(max_deg() + 1); NodePtr v, x, y; Für alle Knoten v aus root_list: { x = v; int d = x->degree(); while (A[d] != 0) { y = A[d]; if (x->key() > y->key()) std::swap(x, y) link(x, y); A[d] = 0; d++; } A[d] = x; } min() = 0;

23

min

27

9988

52

77

A 0 0 0 0 0 0

d 1 x y

Page 73: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

73

consolidate im Fibonacci-Heapvoid consolidate(){ […]

for (i = 0; i < A.size(); i++) { if (A[i] != 0) { insert_into_rootlist(A[i]); if (min() == 0 || A[i]->key() < min()->key()) { min() = A[i]; } } }

23

min

27

9988

52

77

A 0 0 0 0 0 0

d 1 x y

Page 74: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

74

Potenzialfunktion zur amortisierten Analyse

• Der Fibonacci-Heap H enthalte N Knoten

• M sei die Anzahl markierter Knoten (mark = true)

• T sei die Anzahl der Bäume in der Wurzelliste

• Es existiere ein maximaler Grad D aller Knoten

• Wir wählen die Potenzialfunktion als

(H) = T(H) + 2 M(H)

• hat folgende Eigenschaften– Für einen leeren Heap ist = 0

– Für zwei Heaps H1 und H2 gilt

(H1 [ H2) = (H1) + (H2)

Page 75: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

75

Amortisierte Analyse von insert

insert: neuer Knoten wird neben dem Minimum in der Wurzelliste eingefügt, der Zeiger auf das Minimum gegebenenfalls angepasst

Analyse:–# Bäume erhöht sich: Ti+1 = Ti + 1

–# Markierungen konstant: Mi+1 = Mi

) = i+1 - i = (Ti +1 + 2 Mi) – (Ti – 2 Mi) = 1

Worst-Case-Laufzeit und amortisierte Laufzeit O(1)

Page 76: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

76

Analyse von delete_minvoid delete_min(){ NodePtr node = min(); if (node == 0) throw “Empty heap!“;

Für jedes Kind child von node: // max. O(D) Kinder! child.parent = 0; insert_into_rootlist(child); erase_from_rootlist(node); // Ti+i = Ti + D - 1

if (node->right == node) { min() = 0; } else { min() = node->right; consolidate(); } delete node; number_of_nodes--;}

Page 77: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

77

Analyse von delete_minvoid delete_min(){ NodePtr node = min(); if (node == 0) throw “Empty heap!“;

Für jedes Kind child von node: // max. O(D) Kinder! child.parent = 0; insert_into_rootlist(child); erase_from_rootlist(node); // Ti+i = Ti + D - 1

if (node->right == node) { min() = 0; } else { min() = node->right; consolidate(); // Analyse von consolidate? } delete node; number_of_nodes--;}

Page 78: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

78

Analyse von consolidatevector<NodePtr> A(max_deg() + 1); // O(Di)Für alle Knoten v aus root_list: // O(Ti) […] while (A[d] != 0) { […] d++; } A[d] = x; min() = 0; // Ti+1 = 0?for (i = 0; i < A.size(); i++) // O(Di){ if (A[i] != 0) { insert_into_rootlist(A[i]); // Ti+1 · Di + 1 […] }}

Page 79: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

79

Analyse von delete_minvoid delete_min(){ NodePtr node = min(); if (node == 0) throw “Empty heap!“;

Für jedes Kind child von node: // O(Di) child.parent = 0; insert_into_rootlist(child); erase_from_rootlist(node); // Ti+i = Ti + Di - 1

if (node->right == node) { min() = 0; } else { min() = node->right; consolidate(); // O(Ti + Di) } delete node; number_of_nodes--;}

Page 80: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

80

Analyse von delete_minDie tatsächlichen Kosten ci für delete_min sind

ci = O(Di + Ti)

Für das Potenzial vor der Ausführung von delete_min gilt:

i = Ti + 2 Mi

Nach der Ausführung bleiben maximal Ti+1 = Di +1 Wurzeln übrig. Ferner werden keine Knoten neu markiert, d.h. Mi+1 = Mi. Daher gilt für i+1:

i+1 = Ti+1 + 2 Mi+1 = Di + 1 + 2 Mi

Die amortisierten Kosten ai betragen somit

ai = ci + i+1 - i

= O(Di + Ti) + Di + 1 + 2 Mi – Ti – 2 Mi

= O(Di + Ti) + Di + 1 – Ti = O(Di) + O(Ti) – Ti

= O(Di)

Der letzte Schritt ist möglich, da sich stets so skalieren lässt, dass die in O(Ti) versteckten Konstanten kompensiert werden und O(Ti) – Ti verschwindet.

Page 81: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

81

Bestimmung des maximalen Grades D

||x|| sei die Anzahl der Knoten im Unterbaum von Knoten x inklusive x.

grad(x) sei der Grad (Anzahl der Kinder) von Knoten x.

Lemma 1:

Sei x irgendein Knoten in einem Fibonacci-Heap mit Grad k. Seien y1, y2, …, yk die Kinder von x in der Reihenfolge in der sie hinzugefügt wurden. Dann gilt:

grad(y1) ¸ 0 und grad(yi) ¸ i – 2 8 i = 2, 3, …, kBeweis:

grad(y1) ¸ 0 ist trivial. Als yi ein Kind von x wurde, waren y1, …, yi-1 bereits Kinder, d.h. grad(x) war (i – 1). consolidate wird yi nur zu einem Kind von x machen, wenn grad(x) = grad(yi). Da yi seit dem einfügen höchstens ein Kind verloren, nicht aber dazugewonnen, haben kann, gilt also: grad(yi) ¸ i – 2.

Page 82: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

82

Fibonacci

Ein Problem im „Liber Abaci“ des Leonardo von Pisa (genannt Fibonacci) lautet:

„Jemand setzt ein Paar Kaninchen in einen Garten, der auf allen Seiten von einer Mauer umgeben ist, um herauszufinden, wie viele Kaninchen innerhalb eines Jahre geboren werden. Wenn angenommen wird, dass jeden Monat jedes Paar ein weiteres Paar erzeugt, und dass Kaninchen zwei Monate nach ihrer Geburt geschlechtsreif sind, wie viele Paare Kaninchen werden dann jedes Jahr geboren?“

Page 83: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

83

Die Fibonacci-Zahlen

Lemma 2:

Für alle k 2 N gilt

Beweis:

Induktion über k.

k = 0: 1 + F_0 = 1 + 0 = F_2

Mit der Behauptung Fk+1= 1 + i=0k-1 Fi erhält man für Fk+2

Page 84: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

84

Bestimmung des maximalen Grades DLemma 3:

Sei x irgendein Knoten in einem Fibonacci-Heap und grad(x) = k. Dann gilt:

Beweis:

Sei sk der minimale Wert ||z|| eines Knotens z mit grad(z) = k. Offensichtlich gilt s0 = 1, s1 = 2, s2 = 3. Ebenso ist sk nicht größer als ||x|| und die sk wachsen monoton mit k.

Ferner seien y1, y2,…yk die Kinder von x in der Reihenfolge in der sie eingefügt wurden. Um eine untere Schranke für ||x|| zu berechnen, zählen wir eine Eins für x selbst und für y1 und wenden dann Lemma 1 an:

Lemma 1:

grad(y1) ¸ 0 und grad(yi) ¸ i – 2 8 i = 2, 3, …, k

Page 85: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

85

Bestimmung des maximalen Grades DMit vollständiger Induktion über k lässt sich zeigen, dass sk ¸ Fk+2 für alle k:

k = 0: s0 = 1 ¸ 0 = F0

k = 1: s1 = 2 ¸ 1 = F1

Mit der Induktionsbehauptung gilt:

Ferner glauben wir (ohne Beweis), dass Fk+2 ¸ n.

Korollar:Der maximale Grad D(N) eines jeden Knotens in einem Fibonacci-Heap mit N Knoten ist O(log N).Beweis: Sie x ein Knoten des Heaps und grad(x) = k. Nach Lemma 3 gilt:

N ¸ ||x|| ¸ k

Durch Logarithmieren erhält man:

log N ¸ k

Page 86: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

86

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

46 30

21

52

39

38

41

node key 15

Page 87: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

87

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

46 30

21

52

39

38

41

node key 15

Page 88: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

88

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15 30

21

52

39

38

41

node key 15

Page 89: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

89

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15 30

21

52

39

38

41

node key 15

Page 90: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

90

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15 30

21

52

39

38

41

node key 15

Page 91: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

91

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15 30

21

52

39

38

41

node key 15

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

Page 92: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

92

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15 30

21

52

39

38

41

node key 15

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

Page 93: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

93

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15 30

21

52

39

38

41

node key 15

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

Page 94: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

94

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15

30

21

52

39

38

41

node key 15

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

Page 95: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

95

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15

30

21

52

39

38

41

node key 15

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

Page 96: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

96

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15

30

21

52

39

38

41

node key 15

Page 97: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

97

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15

30

21

52

39

38

41

node key 15

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

Page 98: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

98

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15

30

21

52

39

38

41

node key 15

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

Page 99: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

99

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15

30

21

52

39

38

41

node key 15

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

Page 100: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

100

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15

30

21

52

39

38

41

node key 15

Page 101: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

101

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15

30

21

52

39

38

41

node key 5

Page 102: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

102

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

35

15

30

21

52

39

38

41

node key 5

Page 103: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

103

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

5

15

30

21

52

39

38

41

node key 5

Page 104: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

104

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

5

15

30

21

52

39

38

41

node key 5

Page 105: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

105

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

5

15

30

21

52

39

38

41

node key 5

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

Page 106: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

106

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

5

15

30

21

52

39

38

41

node key 5

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

Page 107: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

107

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

5

15

30

21

52

39

38

41

node key 5

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

Page 108: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

108

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

15

30

21

52

39

38

41

node key 5

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

5

Page 109: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

109

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

15

30

21

52

39

38

41

node key 5

void cut(NodePtr node){ if (node->parent() == 0) throw “Cannot cut root!“; // Entferne Knoten aus Elterknoten node->parent()->remove_child(node); node->parent() = 0; // Füge in Wurzelliste ein insert_into_rootlist(node); // Entferne mögliche Markierung node->mark() = false;}

5

Page 110: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

110

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

Page 111: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

111

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

Page 112: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

112

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

26

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

Page 113: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

113

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26

Page 114: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

114

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26

Page 115: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

115

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26

Page 116: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

116

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26

Page 117: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

117

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26

Page 118: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

118

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

1724 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26

Page 119: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

119

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

17 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26

24

Page 120: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

120

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

17 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26 24

Page 121: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

121

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

17 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26 24

Page 122: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

122

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

17 23

15

30

21

52

39

38

41

node key 5

5

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; } else { cut(node); cascading_cut(node->parent()); }}

26 24

Page 123: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

123

decrease_key im Fibonacci-Heap

void decrease_key(NodePtr node, const Key& key){ if (node.key() < key) throw “No decrease!“; // Konsistenzcheck node.key() = key; // Neuen Schlüssel zuweisen

NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { // Heapeigenschaft verletzt! cut(node); cascading_cut(p); } if (key < min()) min() = node; // Minimum anpassen}

min

7 18

17 23

15

30

21

52

39

38

41

node key 5

5 26 24

Page 124: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

124

Analyse von decrease_keyvoid decrease_key(NodePtr node, const Key& key){ […] NodePtr p = node->parent(); if (node->parent() != 0 && node->parent->key() > key) { cut(node); // O(1) cascading_cut(p); // ??? } if (key < min()) min() = node;}

void cut(NodePtr node){ […] node->parent()->remove_child(node); // O(1) […] insert_into_rootlist(node); // O(1), T erhöht node->mark() = false; // evtl. M erniedrigt}

Page 125: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

125

Analyse von cascading_cut

void cascading_cut(NodePtr node){ if (node->parent() == 0) return; if (node->mark() == false) { node->mark() = true; // M um eins erhöht! } else { cut(node); // O(1), T erhöht // evtl. M erniedrigt cascading_cut(node->parent()); // Rekursion! }}

Unter der Annahme von r rekursiven Aufrufen von cascading_cut ist die tatsächliche Arbeit in cascading_cut O(r).Jeder Aufruf von cascading_cut, mit Ausnahme des letzten, entfernt einen markierten Knoten und fügt ihn in die Wurzelliste ein. Dabei werden die Markierungen von (r – 1) Knoten entfernt und eventuell ein weiterer Knoten markiert.

Page 126: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

126

Analyse von decrease_key

• Tatsächliche Arbeit in decrease_key O(1) + O(r)

• Potenzialänderung– r Bäume erzeugt: Ti+1 = Ti + r

– max. (2 – r ) Markierungen erzeugt: Mi+1 = Mi – r + 2

) = r + 2 (2 – r) = 4 + r

• Amortisierte Kosten:ai = ci + = O(r) + 4 – r = O(1)

• Die letzte Umformung folgt wieder aus der Skalierbarkeit des Potenzials

Page 127: Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für Einzeloperationen für die Abschätzung der Gesamtlaufzeit

127

Amortisierte Analyse von Heaps

Operation Binärer Heap Binomial-HeapFibonacci-Heap

(amortisiert)

insert O(log N) O(log N) O(1)

find_min O(1) O(1) O(1)

delete_min O(log N) O(log N) O(log N)

Decrease_key O(log N) O(log N) O(1)

create O(N) O(N) O(N)

merge O(N) O(log N) O(1)