Heaps und Arrays. Ein Heap lässt sich sehr gut in einem Array speichern: Es gilt. Vater. Kinder. Array Indizes [0] [1] [2] [3] [4] [5] [6]

Ähnliche Dokumente
Informatik II Vorlesung am D-BAUG der ETH Zürich

Informatik II Prüfungsvorbereitungskurs

Informatik II Prüfungsvorbereitungskurs

9. Natürliche Suchbäume

18. Natürliche Suchbäume

Übung Algorithmen und Datenstrukturen

Suchen und Sortieren Sortieren. Heaps

18. Natürliche Suchbäume

elementare Datenstrukturen

Informatik II Vorlesung am D-BAUG der ETH Zürich

Fallstudie: Online-Statistik

Informatik II, SS 2018

Algorithmen und Datenstrukturen (für ET/IT)

Übung Algorithmen und Datenstrukturen

Lernmodul 7 Algorithmus von Dijkstra

17. Hashing. Hash Tabellen, Geburtstagsparadoxon, Hashfunktionen, Kollisionsauflösung durch Verketten, offenes Hashing, Sondieren

Vorlesung Informatik 2 Algorithmen und Datenstrukturen

7. Sortieren Lernziele. 7. Sortieren

Bipartites Matching. Gegeben: Ein bipartiter, ungerichteter Graph (V 1, V 2, E). Gesucht: Ein Matching (Paarung) maximaler Kardinalität.

Algorithmen und Datenstrukturen. Algorithmen und Datenstrukturen. B6.1 Einführung. B6.2 Symboltabellen. B6.3 Einfache Implementationen

Bäume. Text. Prof. Dr. Margarita Esponda SS 2012 O4 O5 O6 O ALP2-Vorlesung, M. Esponda

Gliederung. 5. Compiler. 6. Sortieren und Suchen. 7. Graphen

8. A & D - Heapsort. Werden sehen, wie wir durch geschicktes Organsieren von Daten effiziente Algorithmen entwerfen können.

Informatik II, SS 2014

Vorlesung Datenstrukturen

B6.1 Introduction. Algorithmen und Datenstrukturen. Algorithmen und Datenstrukturen. B6.1 Introduction. B6.3 Analyse. B6.4 Ordnungsbasierte Methoden

17. Hashing. Motivation. Naive Ideen. Bessere Idee? k(s) = s i b i

Informatik II, SS 2016

Informatik II. Giuseppe Accaputo, Felix Friedrich, Patrick Gruntz, Tobias Klenze, Max Rossmannek, David Sidler, Thilo Weghorn FS 2017

Anwendungsbeispiel MinHeap

Heapsort, Quicksort, Mergesort. 8. Sortieren II

Datenstrukturen. Mariano Zelke. Sommersemester 2012

14. Sortieren II Heapsort. Heapsort. [Max-]Heap 7. Heapsort, Quicksort, Mergesort. Binärer Baum mit folgenden Eigenschaften

5.5 Prioritätswarteschlangen

Sortieren II / HeapSort Heaps

Grundlagen: Algorithmen und Datenstrukturen

EINI LW. Einführung in die Informatik für Naturwissenschaftler und Ingenieure. Vorlesung 2 SWS WS 11/12

Informatik II Übung 2. Pascal Schärli

Datenstrukturen. einfach verkettete Liste

Datenstrukturen Teil 2. Bäume. Definition. Definition. Definition. Bäume sind verallgemeinerte Listen. Sie sind weiter spezielle Graphen

13. Bäume: effektives Suchen und Sortieren

Algorithmen & Datenstrukturen 2 Praktikum 1

13. Bäume: effektives Suchen und Sortieren

Programm heute. Algorithmen und Datenstrukturen (für ET/IT) Suchen. Lineare Suche. Such-Algorithmen. Sommersemester Dr.

Komplexität eines Algorithmus, Grössenordnung, Landau-Symbole, Beispiel einer Komplexitätsberechnung (Mergesort) 7. KOMPLEXITÄT

Suchen und Sortieren Sortieren. Heaps

Dynamische Datenstrukturen

8. Sortieren II. 8.1 Heapsort. Heapsort. [Max-]Heap 6. Heapsort, Quicksort, Mergesort. Binärer Baum mit folgenden Eigenschaften

Heapsort, Quicksort, Mergesort. 8. Sortieren II

Copyright, Page 1 of 7 Heapsort

Binäre Suchbäume. Mengen, Funktionalität, Binäre Suchbäume, Heaps, Treaps

Datenstrukturen & Algorithmen

Vorlesung Datenstrukturen

Informatik II, SS 2014

Dr. Lars Hildebrand Fakultät für Informatik Technische Universität Dortmund

EINI LW/WiMa. Einführung in die Informatik für Naturwissenschaftler und Ingenieure Vorlesung 2 SWS WS 16/17

Algorithmen und Datenstrukturen. Bäume. M. Herpers, Y. Jung, P. Klingebiel

Übung 4: Die generische Klasse AvlBaum in Java 1

Algorithmen und Datenstrukturen Heapsort

Informatik II, SS 2014

Abstract Data Structures

Wiederholung. Bäume sind zyklenfrei. Rekursive Definition: Baum = Wurzelknoten + disjunkte Menge von Kindbäumen.

Aufbau eines "B-Baums" der Ordnung 3, Teil 1

Abstract Data Structures

- k Maximalwerte aus Menge mit n >> k Elementen (Rangfolgebestimmung von Suchmaschinen!) Die typische Operationen:

7. Dynamische Datenstrukturen Bäume. Informatik II für Verkehrsingenieure

Graphalgorithmen II. Sebastian Ehrenfels Sebastian Ehrenfels Graphalgorithmen II / 44

Informatik II, SS 2016

Datenstrukturen. Mariano Zelke. Sommersemester 2012

Datenstrukturen und Algorithmen D-INFK. Musterlösung 1

Aufgaben, Hilfestellungen und Musterlösungen zum Modul 5 Druckversion

Rechtsbelehrung. Java und OOP Das Buch Christian Silberbauer 144

Vorlesung Informatik 2 Algorithmen und Datenstrukturen

Algorithmen und Datenstrukturen 11

Was ist ein assoziativer Speicher?

TU München, Fakultät für Informatik Lehrstuhl III: Datenbanksysteme Prof. Alfons Kemper, Ph.D.

Kap. 3 Sortieren. 7. VO DAP2 SS Mai Vorlesung am Do 7.5. entfällt wegen FVV um 14 Uhr HeapSort ff 3.1.

Heapsort. 1. Erstelle aus dem gegebenen Array einen Max-Heap (DownHeap) 2. Tausche erstes und letztes Element des Arrays

Grundzüge von Algorithmen und Datenstrukturen, WS 15/16: Lösungshinweise zum 13. Übungsblatt

Vorlesung Datenstrukturen

Auswählen nach Rang (Selektion)

Vorlesung Datenstrukturen

5. Vorrangwarteschlangen (priority queues)

Was bisher geschah ADT Menge mit Operationen: Suche nach einem Element Einfügen eines Elementes Löschen eines Elementes Realisierung durch

Algorithmen I - Tutorium 28 Nr. 9

Teil 1: Suchen. M.O.Franz, Oktober 2007 Algorithmen und Datenstrukturen - Suchen 1-1

Datenstrukturen und Algorithmen D-INFK

Kapitel 12: Induktive

Algorithmen & Datenstrukturen Midterm Test 2

! 1. Rekursive Algorithmen.! 2. Rekursive (dynamische) Datenstrukturen. II.3.2 Rekursive Datenstrukturen - 1 -

Grundlagen der Informatik. Prof. Dr. Stefan Enderle NTA Isny

Datenstrukturen und Algorithmen Beispiellösung zu Heimübungsblatt 7. Abbildung 1: Das Array A als Baum (vgl. Foliensatz 16, Folie 3)

Grundlagen der Algorithmen und Datenstrukturen Kapitel 6

Transkript:

Heaps

Heaps Ein (Min-)Heap ist ein Binärbaum, welcher die (Min-)Heap-Eigenschaft hat: Schlüssel eines Kindes ist immer grösser als der des Vaters. [Max-Heap: Kinder-Schlüssel immer kleiner als Vater-Schlüssel] bis auf die letzte Ebene vollständig ist höchstens eine Lücke in der letzten Ebene hat, welche rechts liegen muss 5 7 9 1 10 22 2 17 14 11 8 2

Heaps und Arrays Ein Heap lässt sich sehr gut in einem Array speichern: [0] [1] [2] Es gilt Vater i = (i 1)/2, Kinder i = {2i + 1, 2i + 2 [] [4] [5] [7] [8] [9] [10] [11] Vater [6] Array Indizes 0 1 2 4 5 6 7 8 9 10 11 Kinder

Einfügen Füge ein neues Element k an der ersten freien Stelle ein. Verletzt Heap-Eigenschaft potentiell. 9 5 7 1 10 8 Stelle Heap-Eigenschaft wieder her durch sukzessives Aufsteigen von k. Worst-Case Komplexität O(log n) 22 2 17 14 11 4 5 4 9 1 7 22 2 17 14 11 10 8 4

Datenstruktur ArrayHeap public class ArrayHeap { float[] data; int used; // Array zum Speichern der Daten // Anzahl belegte Knoten ArrayHeap () { data = new float[16]; used = 0; void Grow(){ // Binäres Vergrössern von data, wenn nötig... 5

Insert public void Insert(double value){ if (used == data.length) Grow(); int current = used; int parent = (current-1)/2; while (current > 0 && value < data[parent]) { data[current] = data[parent]; current = parent; parent = (current-1)/2; data[current] = value; 9 used++; Check(0); // Debugging check Vater von current 5 7 1 10 22 2 17 14 11 4 8 6

GetMin Das kleinste Element ist immer an der Wurzel im Baum. Somit kann es sehr schnell ausgelesen werden (O(1)). Wie verhält es sich aber mit Auslesen und Entfernen? Wiederholtes Entfernen der Wurzel ergibt Schlüssel in aufsteigender Reihenfolge: das kann z.b. auch zum Sortieren verwendet werden (Heap-Sort Algorithmus). 7

Minimum entfernen Ersetze die Wurzel durch den letzten Knoten Lasse die Wurzel nach unten sinken, um die Invariante wiederherzustellen 11 5 7 9 1 10 22 2 17 14 11 5 8 Worst-Case Komplexität O(log n) 11 9 7 1 10 8 22 2 17 14 8

Absinken: Welche Richtung? // return child with smaller value. // If larger child index (2*current+2) is not in range, return smaller index private int BestChild(int current) { if (2*current+2 >= used data[2*current+1] < data[2*current+2]) return 2*current+1; // take left branch else return 2*current+2; // right branch x x y 5 7 y 7 5 9

Wurzel Extrahieren public double ExtractRoot() { double min = data[0]; double value = data[used-1]; int current = 0; int next = BestChild(current); while(next < used &&!(value < data[next])) { data[current] = data[next]; current=next; next = BestChild(current); data[current] = value; used--; return min; 11 5 7 9 1 10 22 2 17 14 11 8 10

Verwendungsbeispiel Heap Können wir das schnelle Auslesen, Extrahieren und Einfügen von Minimum (bzw. Maximum) im Heap für einen online-algorithums des Median nutzen? Beobachtung: Der Median bildet sich aus Minimum der oberen Hälfte der Daten und / oder Maximum der unteren Hälfte der Daten. Untere n/2 Punkte Obere n n/2 Punkte 11

Online Median Verwende Max-Heap H max und Min-Heap H min. Bezeichne Anzahl Elemente jeweils mit H max und H min Einfügen neuen Wertes v in H_max, wenn v max H max H_min, sonst Rebalancieren der beiden Heaps Falls H_max > n/2, dann extrahiere Wurzel von H_max und füge den Wert bei H_min ein. Falls H_max < n/2, dann extrahiere Wurzel von H_min und füge den Wert bei H_max ein. Gesamt worst-case Komplexität O(log n) 12

Berechnung Median Berechnung Median Wenn n ungerade, dann median = min(h_min) Wenn n gerade, dann median = max H max + min H min 2 worst-case Komplexität O(1) 1

Hash-Tabellen möglichst einfach 5/6/2015 14

Datensatz class Friend{ String name; String telephone; Friend(String Name, String Tel) { name = Name; telephone = Telephone; 5/6/2015 15

Telefonbuch class MyFriends{ Friend[] data; int friends; MyFriends(int maxfriends) { data = new Friend[maxFriends]; friends = 0; void Add(String name, String telephone){ data[friends] = new Friend(name, telephone); friends ++; Friend GetFriend(String name){ for (int i = 0; i<friends; ++i) if (data[i].name.equals(name)) return data[i]; return null; Schlecht: oft lange Suchzeiten O(data.length) 5/6/2015 16

Besseres Telefonbuch class MyFriends{ Friend[] data; MyFriends(int maxfriends) { data = new Friend[maxFriends]; void Add(String name, String telephone){ int index = Hash(name); while(data[index]!= null) index = (index + 1) % data.length; Friend GetTelephone(String name){ int index = Hash(name); while(data[index]!= null &!data[index].name.equals(name)) index = (index + 1) % data.length; return data[index]; Magie 5/6/2015 17

Anwendungsbeispiel: Friends friends = new Friends(10); friends.add("hannes", "01/007"); friends.add("niklas", "01/008"); friends.add("katrin", "01/009"); friends.add("tobias", "02/800"); friends.add("florian", "02/801");... System.out.println(friends.GetFriend("Tobias").telephone); "02/800" 5/6/2015 18

Magie enttarnt! int Hash(String name){ int value = 0; for (int i = 0; i < name.length(); ++i){ char c = name.getcharat(i); value = value * 1 + (int)c; if (value<0) value = -value; return value % data.length; c (int) c value H 72 72 a 97 229 n 110 7209 n 110 2241689 e 101 69492460 s 115-2140700921 5/6/2015 19

Warum funktioniert die Hastabelle? Das Resultat von Hash(name) ist für sehr viele Namen unterschiedlich. name value value % 100 Hannes 2140700921 21 1 Niklas 1961629266 66 6 Katrin 205460759 59 9 Tobias 178458426 6 6 Florian 898707565 65 5 value % 10 Die Einschränkung auf die Array-Grösse macht sog. Kollisionen wahrscheinlicher. Diese werden aber behandelt, indem noch lokal nachgeprüft (sondiert) wird. 5/6/2015 20

Sondieren class MyFriends{ Friend[] data; MyFriends(int maxfriends) { data = new Friend[maxFriends]; void Add(String name, String telephone){ int index = Hash(name); while(data[index]!= null) index = (index + 1) % data.length; name value value % 10 Hannes 2140700921 1 Niklas 1961629266 6 Katrin 205460759 9 Tobias 178458426 6 Florian 898707565 5 Lineares Sondieren Friend GetTelephone(String name){ int index = Hash(name); while(data[index]!= null &&!data[index].name.equals(name)) index = (index + 1) % data.length; return data[index]; Lineares Sondieren 5/6/2015 21 index data 0 null 1 (Hannes) 2 null null 4 null 5 (Florian) 6 (Niklas) 7 (Tobias) 8 null 9 Katrin

Zusammengefasst Hash-Tabellen funktionieren, wenn eine gute Hash-Funktion vorhanden ist, welche verschiedene Werte möglichst auf verschiedene Array-Indizes abbildet. Darüber hinaus muss der Indexbereich (das Array) gross genug sein, damit Kollisionen unwahrscheinlich werden. Sind Kollisionen hinreichend unwahrscheilich, so findet man Elemente in der Hashtabelle in O(1)! Es lässt sich noch viel sagen über: Löschen von Einträgen, Andere Sondiermethoden, dynamische Hash-Tabellen, Hash-Funktionen, Kollisionswahrscheinlichkeiten etc., aber wir wollen hier nur das Prinzip verstehen. 5/6/2015 22

Generische Hashtabellen in Java Wir kennen bereits java.util.vector: Klasse für dynamisches, selbstwachsendes Array. Neu: Klasse für HashTabelle java.util.hashmap HashMap<String, Integer> map; // Abbildung String Integer map.put("abc",); map.put("xyz",100); int i = map.get("abc"); // i =! int j = map.get("xyz"); // i = 100! Kann zwischen allen Objekte abbilden! Also, z.b. auch Node Integer 5/6/2015 2

Shortest Paths 5/6/2015 24

Fallstudie Dijkstra s Shortest Path Gegeben: Gerichteter Graph (V, E) mit Knotenmenge V und Kantenmenge E, bei dem jeder Kante e E eine Länge l e 0 zugeordnet ist. Problem: Finde zu Startpunkt S V und Endpunkt E V den kürzesten Pfad entlang der Kanten im Graph. S a d c 6 2 e g E 4 1 2 b f 25

Shortest Path: Animation S a d c 6 65 2 e 97 z E 10 4 b 4 1 2 f 7 26

Implementation Grundsätzlich wird die Menge der Knoten unterteilt in a. Knoten, die schon als Teil eines minimalen Pfades erkannt wurden (M) b. Knoten, die nicht in M enthalten sind, jedoch von M aus direkt (über eine Kante) erreichbar sind (R) und c. Knoten die noch nie berücksichtigt wurden (U: = V \ (M R)) S a 4 M b d c 6 2 1 2 R e f g E U 27

Algorithmus Ein Knoten K aus R mit minimaler Pfadlänge in R kann nicht mit kürzerer Pfadlänge über einen anderen Knoten in R erreicht werden. Daher kann er zu M hinzugenommen werden. Dabei vergrössert sich R potentiell um die Nachbarschaft von K und die Pfadlänge aller von K aus direkt erreichbaren Knoten muss angepasst werden. Daher bietet sich die Datenstruktur Heap für R an! S a M 4 b d c 6 2 1 2 R (a,0), (a-d,), (a-b,4) +(b-c,5) Beim Anpassen der Nachbarn von K sind potentiell auch Elemente von R betroffen. Nie jedoch Elemente aus M oder gar U e f g E U 28

Algorithmus [Initial gilt: Pfadlänge (K) = für alle Knoten im Graph] Setze Pfadlänge(S) = 0; Starte mit M = {S; Setze K = S; Solange ein neuer Knoten K hinzukommt und dieser nicht der Zielknoten ist Für jeden Nachbarknoten N von K Berechne die Pfadlänge x nach N über K. Ist Pfadlänge N =, so nimm N zu R hinzu. Ist x < Pfadlänge N <, so setze Pfadlänge N = x und passe R an den neuen Wert an. Wähle als neuen Knoten K den Knoten mit kleinster Pfadlänge in R 29

Modellierung Graph = Menge von Knoten Knoten mit ausgehenden Kanten und zuletzt ermittelter Pfadlänge (für den Algorithmus) Kanten mit Länge und Zielknoten MinHeap R mit schnellem Zugriff auf kürzesten Pfad S a M 4 b d c 6 2 1 2 R e f g E U 5/6/2015 0

Kanten und Knoten public class Edge { private Node to; private int length; Edge (Node t, int l) { to = t; length = l; // Getters and Setters omitted for brevity public class Node { private Vector<Edge> out; private String name; private int pathlen; private Node pathparent; Node(String n) { out = new Vector<Edge>(); pathparent = null; pathlen = Integer.MAX_VALUE; name = n; // Getters and Setters omitted for brevity d 5/6/2015 1

Graph public class Graph { private Vector<Node> nodes; private HashMap<String,Node> nodebyname; Graph(){ nodes = new Vector<Node>(); nodebyname = new HashMap<String,Node>(); public void AddNode(String s){ public Node FindNode(String s){ public void AddEdge(String from, String to, int length) { Vector<Node> ShortestPath(Node S, Node E) {; 5/6/2015 2

Min-Heap R public class Heap {... // Vergleich zweier Knoten = Vergleich der aktuellen Pfadlängen private boolean Smaller(Node l, Node r) { return l.getpathlen() < r.getpathlen(); public void Insert(Node n) {... public Node ExtractRoot() {... Was ist damit: "Ist x < Pfadlänge N <, so setze Pfadlänge N = x und passe R an den neuen Wert an."? neue Methode DecreaseKey! 5/6/2015

Schnelles Finden von Nodes im Heap? public class Heap {... HashMap <Node, Integer> map; neu: Hash-Tabelle Node Index! // Damit die Hashtabelle immer konsistent bleibt, muss nun // an allen Stellen im Code, wo vorher data[x] = y stand, // Set(x,y) stehen: private void Set(int index, Node value){ data[index] = value; map.put(value, index); 4

Heap: DecreaseKey public class Heap {... Hier brauchen wir die Hashtabelle! public void DecreaseKey(Node n) { int current = map.get(n); int parent = (current-1)/2; // aufsteigen while (current > 0 && Smaller(n, data[parent])) { 5 7 Set(current, data[parent]); current = parent; parent = (current-1)/2; 9 1 2 8 Set(current, n); 22 2 17 14 11 5

Alle Bausteine sind da. Implementation des Shortest Path Algorithmus in der Übung. 5/6/2015 6

Appendix: Animation auf Folie 26 expandiert Durchprobieren aller Pfade zu ineffizient Dijkstra s Idee: Aufbau der kürzesten Pfade bis Ziel gefunden S a 4 b d c 6 2 1 2 e f g E Starte bei S, (Knoten, Pfadlänge) : (a,0) Kürzester Weg von (a,0) Zusätzliche Kante +(a-d,) S a 4 b d c 6 2 1 2 e f g E 7

Algorithmus Idee 8 d e g f b a c S E 6 4 1 2 2 (a,0), (a-d,) +(a-b,4) d e g f b a c S E 6 4 1 2 2 (a,0), (a-d,), (a-b,4) +(b-c,5) d e g f b a c S E 6 4 1 2 2 (a,0), (a-d,), (a-b,4), (b-c,5) +(c-e,7) d e g f b a c S E 6 4 1 2 2 (a,0), (a-d,), (a-b,4), (b-c,5), (c-e,7), + (c-f,7)

Algorithmus Idee Algorithmus terminiert, wenn Ziel erreicht S a 4 b d c 6 2 1 2 e f E g (a,0), (a-d,), (a-b,4), (b-c,5), (c-e,7), (c-f,7) + (e-g,10) Weg finden: über Vorgänger zurücklaufen S a 4 b d c 6 2 1 2 e f E g 9