Algorithmen und Datenstrukturen II

Syntax und Semantik Java: Der Einstieg Imperative Programmierung in Java Algorithmen zur exakten Suche in Texten Objektori Algorithmen und Datenstruk...
Author: Paul Peters
0 downloads 1 Views 578KB Size
Syntax und Semantik Java: Der Einstieg Imperative Programmierung in Java Algorithmen zur exakten Suche in Texten Objektori

Algorithmen und Datenstrukturen II Alexander Sczyrba AG Praktische Informatik Technische Fakult¨ at Universit¨ at Bielefeld

Vorlesung Sommer 2008

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Teil VIII Hashing

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Einf¨uhrendes Beispiel

Ein Pizza-Lieferservice in Bielefeld speichert die Daten seiner Kunden: Name, Vorname, Adresse und Telefonnummer. Wenn ein Kunde seine Bestellung telefonisch aufgibt, um dann mit der Pizza beliefert zu werden, dann muss er seine Telefonnummer angeben, da er u ¨ber diese Nummer eindeutig identifiziert werden kann. Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Telefonnummer 00000000 00000001 00000002 ... 99999997 99999998 99999999

Alexander Sczyrba A&D II, Vorlesung 2008

Name M¨ uller Schmidt Schultz ... Meier Neumann Schr¨oder

Strategien zur Behandlung von Kollisionen

Vorname Heinz Werner Hans ... Franz Herbert Georg

PLZ 33615 33615 33602 ... 33609 33612 33647

Klasse Hashtable

Straße Unistraße 15 Gr¨ unweg 1 Arndtstraße 12 ... Kirchweg 4 J¨agerallee 15 M¨ uhlweg 2

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Bielefeld hat ca. 300.000 Einwohner, dann gibt es vielleicht 200.000 Telefonnummern. Davon bestellt jeder f¨ unfte eine Pizza – bleiben 40.000 potentielle Eintr¨age, verteilt auf mehrere Pizza-Lieferservices. Optimistisch gesch¨atzt wird unsere Pizzeria also ca. 10.000 Kunden haben.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Da stellt sich folgende Frage: Wir wissen doch gar nicht, welche Telefonnummern bestellen werden – wie sollen denn dann die Zeilen benannt werden? Unsere Aufgabe ist es, alle 100 Millionen Telefonnummern (denn jede einzelne k¨onnte ja theoretisch bestellen) so abzubilden, dass sie in eine 10.000 Zeilen große Tabelle passen.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Modulo

Hierzu machen wir uns jetzt eine mathematische Operation zunutze, die Modulo-Operation:

x mod y

liefert als Ergebnis den Rest der ganzzahligen Division x/y .

Beispielsweise ergibt 117 mod 20 = 17, da 117 = 5 · 20 + 17.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Hash-Funktion Beispiel h(Telefonnummer) = Telefonnummer mod Tabellenl¨ange

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Hash-Funktion Beispiel h(Telefonnummer) = Telefonnummer mod Tabellenl¨ange oder allgemein: Beispiel h(k) = k mod m mit h f¨ ur Hashfunktion, k f¨ ur key und m f¨ ur Tabellenl¨ange. Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Kollisionen

Wir benutzen also diese Hashfunktion, um jedem Schl¨ ussel einen Index (hier eine Zahl zwischen 0 und 9999) in einer verkleinerten Tabelle (der sogenannten Hashtabelle) zuzuordnen und damit eine Menge Platz zu sparen. Leider kann es allerdings passieren, dass in ung¨ unstigen F¨allen zwei oder mehr Schl¨ ussel (Telefonnummern) auf denselben Index in der Hashtabelle abgebildet werden, Beispiel z.B. ist 01063852 mod 10000 = 08153852 mod 10000 = 3852.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Allgemeine Definitionen

Formal gesehen ist Hashing ein abstrakter Datentyp, der die Operationen insert, delete und search auf (dynamischen) Mengen effizient unterst¨ utzt.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Direkte Adressierung

Hashing ist im Durchschnitt sehr effizient – unter vern¨ unftigen Bedingungen werden obige Operationen in O(1) Zeit ausgef¨ uhrt (im worst-case kann search O(n) Zeit ben¨otigen). Wenn die Menge U aller Schl¨ ussel relativ klein ist, k¨onnen wir sie injektiv auf ein Feld abbilden; dies nennt man direkte Adressierung

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Direkte Adressierung 0

U (Universum der Schl"ussel)

0

9

6

2

7

4 1

1

3 4

K (Aktuelle Schl"ussel)

2

5

3

6

5 7

8

8 9

T

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Hashing Ist die Menge U aller Schl¨ ussel aber sehr groß (wie im obigen Beispiel des Pizza-Services), so k¨onnen wir nicht mehr direkt adressieren. Unter der Voraussetzung, dass die Menge K aller Schl¨ ussel, die tats¨achlich gespeichert werden, relativ klein ist gegen¨ uber U, kann man die Sch¨ ussel effizient in einer Hashtabelle abspeichern. Dazu verwendet man allgemein eine Hashfunktion Definition h : U → {0, 1, . . . , m − 1}, die Schl¨ ussel abbildet auf Werte zwischen 0 und m − 1 (dabei ist m die Gr¨ oße der Hashtabelle). Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Hashing 0

U

h(k1)

(Universum der Schl"ussel)

h(k4)

k1

K (Aktuelle Schl"ussel)

h(k2) = h(k5)

k4 k2 h(k3)

k5 k3

m−1

T

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Typische Hashfunktion

Eine typische Hashfunktion h f¨ ur U = N ist Beispiel h(k) = k mod m.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Kollisionen

da Hashfunktionen nicht injektiv sind, tritt das Problem der Kollision auf: zwei Schl¨ usseln wird der gleiche Platz in der Hashtabelle zugewiesen. Kollisionen sind nat¨ urlich unvermeidbar, jedoch wird eine “gute”Hashfunktion h die Anzahl der Kollisionen gering halten. D.h. h muss die Schl¨ ussel gleichm¨aßig auf die Hashtabelle verteilen. Außerdem sollte h einfach zu berechnen sein.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Strategien zur Behandlung von Kollisionen

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Direkte Verkettung

k4

k4 k2 k2

k5

k5

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

worst-case Laufzeiten

insert: O(1) (neues Element vor die Liste h¨angen) search: O(n) (n = L¨ange der Liste) delete: O(1) (vorausgesetzt, man verwendet doppelt verkettete Listen und hat das Element schon gefunden)

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Open Hashing

Beim Open Hashing werden alle Eintr¨age in der Hashtabelle gehalten. Ist eine Komponente der Tabelle schon belegt, so wird ein freier Platz f¨ ur einen weiteren Eintrag gesucht.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Open Hashing, lineare Verschiebung

k4 k2 k5

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Lineare Verschiebung

Falls h(k) bereits durch einen anderen Schl¨ ussel besetzt ist, wird versucht, k in den Adressen h(k) + 1, h(k) + 2, . . . unterzubringen Pr¨aziser gesagt, wird folgende Hashfunktion verwendet:  h0 (k, i) = h(k) + i mod m mit i = 0, 1, 2, . . . , m − 1.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Hash-Insert mit linearer Verschiebung

Hash-Insert(T , k) 1 i ←0 2 repeat 3 j ← h0 (k, i) 4 if T [j] = NIL then 5 T [j] ← k 6 return j 7 i ←i +1 8 until i = m 9 error “hash table overflow”

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Hash-Search mit linearer Verschiebung

Hash-Search(T , k) 1 i ←0 2 repeat 3 j ← h0 (k, i) 4 if T [j] = k then 5 return j 6 i ←i +1 7 until T [j] = NIL or i = m 8 error NIL

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Quadratische Verschiebung

Es wird die Hashfunktion h0 (k, i) = (h(k) + c1 i + c2 i 2 ) mod m

mit i = 0, 1, 2, . . . , m − 1

verwendet. Dabei sind c1 , c2 ∈ N und c2 6= 0 geeignete Konstanten (s. Cormen et al. [2]).

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Double Hashing

Die Hashfunktion h0 wird definiert durch h0 (k, i) = (h1 (k) + i · h2 (k)) mod m

mit i = 0, 1, 2, . . . , m − 1,

wobei h1 und h2 Hashfunktionen sind. Die Verschiebung wird dabei durch eine zweite Hashfunktion realisiert. D.h. es wird zweimal, also doppelt, gehasht.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Beispiel lineare Verschiebung

0 1

0 1

0

insert 11

2

-

1 2

0 1 11

0

insert 10

-

1 2

3

3

3

4

4

4

Alexander Sczyrba A&D II, Vorlesung 2008

0 1 11 10

0

delete 1

-

1 2 3

0 d 11 10

search 10

-

4

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Man erkennt: Gel¨oschte Felder m¨ ussen markiert werden, so dass ein Suchalgorithmus nicht abbricht, obwohl das Element doch in der Liste gewesen w¨are. Nat¨ urlich kann in die gel¨ oschten Felder wieder etwas eingef¨ ugt werden. Dieses Problem muss in der obigen Implementierung zus¨atzlich ber¨ ucksichtigt werden.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Ladefaktor

n Der Ladefaktor α f¨ ur eine Hashtabelle T ist definiert als m , wobei n die Anzahl der gespeicherten Schl¨ ussel und m die Kapazit¨at der Tabelle sind.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Ladefaktor

n Der Ladefaktor α f¨ ur eine Hashtabelle T ist definiert als m , wobei n die Anzahl der gespeicherten Schl¨ ussel und m die Kapazit¨at der Tabelle sind. Theoretische Untersuchungen und praktische Messungen haben ergeben, dass der Ladefaktor einer Hashtabelle den Wert 0.8 nicht u ¨berschreiten sollte (d.h. die Hashtabelle darf h¨ ochstens zu 80% gef¨ ullt werden). Ist der Ladefaktor ≤ 0.8, so treten beim Suchen im Durchschnitt ≤ 3 Kollisionen auf. Bei einem h¨oheren Ladefaktor steigt die Zahl der Kollisionen rasch an.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Die Klasse Hashtable in Java

Die Klasse java.util.Hashtable implementiert alle Methoden der abstrakten Klasse java.util.Dictionary (vgl. Aufgabe ??). Außerdem enth¨alt Hashtable noch folgende Methoden

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

public synchronized boolean containsKey(Object key) Es wird true zur¨ uckgegeben gdw. die Hashtabelle ein Element unter key verzeichnet hat.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

public synchronized boolean containsKey(Object key) Es wird true zur¨ uckgegeben gdw. die Hashtabelle ein Element unter key verzeichnet hat. public synchronized boolean contains(Object element) Gdw. das angegebene element ein Element der Hashtabelle ist, wird true zur¨ uckgegeben. Diese Operation ist teurer als die containsKey-Methode, da Hashtabellen nur beim Suchen nach Schl¨ usseln effizient sind.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

public synchronized boolean containsKey(Object key) Es wird true zur¨ uckgegeben gdw. die Hashtabelle ein Element unter key verzeichnet hat. public synchronized boolean contains(Object element) Gdw. das angegebene element ein Element der Hashtabelle ist, wird true zur¨ uckgegeben. Diese Operation ist teurer als die containsKey-Methode, da Hashtabellen nur beim Suchen nach Schl¨ usseln effizient sind. public synchronized void clear() Alle Schl¨ ussel in der Hashtabelle werden gel¨ oscht. Wenn es keine Referenzen mehr auf die Elemente gibt, werden sie vom Garbage-Collector aus dem Speicher entfernt.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

public synchronized boolean containsKey(Object key) Es wird true zur¨ uckgegeben gdw. die Hashtabelle ein Element unter key verzeichnet hat. public synchronized boolean contains(Object element) Gdw. das angegebene element ein Element der Hashtabelle ist, wird true zur¨ uckgegeben. Diese Operation ist teurer als die containsKey-Methode, da Hashtabellen nur beim Suchen nach Schl¨ usseln effizient sind. public synchronized void clear() Alle Schl¨ ussel in der Hashtabelle werden gel¨ oscht. Wenn es keine Referenzen mehr auf die Elemente gibt, werden sie vom Garbage-Collector aus dem Speicher entfernt. public synchronized Object clone() Es wird ein Klon der Hashtabelle erzeugt. Die Elemente und Schl¨ ussel selbst werden aber nicht geklont.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Konstruktoren der Klasse Hashtable public Hashtable() Es wird eine neue, leere Hashtabelle mit einer voreingestellten Anfangskapazit¨ at von 11 und einem Ladefaktor von 0.75 erzeugt.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Konstruktoren der Klasse Hashtable public Hashtable() Es wird eine neue, leere Hashtabelle mit einer voreingestellten Anfangskapazit¨ at von 11 und einem Ladefaktor von 0.75 erzeugt. public Hashtable(int initialCapacity) Eine neue, leere Hashtabelle mit der Anfangskapazit¨ at initialCapacity und dem Ladefaktor 0.75 wird generiert.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Konstruktoren der Klasse Hashtable public Hashtable() Es wird eine neue, leere Hashtabelle mit einer voreingestellten Anfangskapazit¨ at von 11 und einem Ladefaktor von 0.75 erzeugt. public Hashtable(int initialCapacity) Eine neue, leere Hashtabelle mit der Anfangskapazit¨ at initialCapacity und dem Ladefaktor 0.75 wird generiert. public Hashtable(int initialCapacity, float loadFactor) Es wird eine neue, leere Hastabelle erzeugt, die eine Anfangskapazit¨ at der Gr¨ oße initialCapacity und einen Ladefaktor von loadFactor besitzt. Der Ladefaktor ist eine Zahl zwischen 0.0 und 1.0 und definiert den Beginn eines rehashings der Tabelle in eine gr¨ oßere.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Beispiel (Name-Wert-Paare) class Pair { private String name; private Object value; public Pair(String name, Object value) { this.name = name; this.value = value; } public String name() { return name; } public Object value() { return value; } public Object value(Object newValue) { Object oldValue = value; value = newValue; return oldValue; } }

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Interface Dic

Beispiel interface Dic { void add(Pair newPair); Pair find(String pairName); Pair delete(String pairName); }

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

Beispiel (Implementierung von Dic) import java.util.Hashtable; class DicImpl implements Dic { protected Hashtable pairTable = new Hashtable(); public void add(Pair newPair) { pairTable.put(newPair.name(), newPair); } public Pair find(String name) { return (Pair) pairTable.get(name); } public Pair delete(String name) { return (Pair) pairTable.remove(name); } }

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld

Einf¨ uhrendes Beispiel

Allgemeine Definitionen

Strategien zur Behandlung von Kollisionen

Klasse Hashtable

K. Arnold, J. Gosling: JavaTM - Die Programmiersprache. Addison-Wesley, 1996. T.H. Cormen, C.E. Leierson, R.L. Rivest: Introduction to Algorithms. MIT Press, 1990. D. Flanagan: Java in a Nutshell. O’Reilly & Associates Inc., 1996. F. Jobst: Programmieren in Java. Hanser Verlag, 1996. H. Klaeren: Vom Problem zum Programm. 2.Auflage, B.G. Teubner Verlag, 1991. K. Echtle, M. Goedicke: Lehrbuch der Programmierung mit Java. dpunkt-Verlag, 2000.

Alexander Sczyrba A&D II, Vorlesung 2008

Universit¨ at Bielefeld