Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für...

127
Amortisierte Analyse und Fibonacci Heaps

Transcript of Amortisierte Analyse und Fibonacci Heaps. 2 Amortisierte Analyse - Modell Worst-Case-Laufzeiten für...

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)