IT) Programm heute. Sommersemester Dr. Tobias Lasser

Notizen Algorithmen und Datenstrukturen (f¨ur ET/IT) Sommersemester 2016 Dr. Tobias Lasser Computer Aided Medical Procedures Technische Universit¨ at...
3 downloads 2 Views 622KB Size
Notizen

Algorithmen und Datenstrukturen (f¨ur ET/IT) Sommersemester 2016 Dr. Tobias Lasser Computer Aided Medical Procedures Technische Universit¨ at M¨ unchen

Programm heute

Notizen

7 Fortgeschrittene Datenstrukturen

8 Such-Algorithmen

Lineare Suche Bin¨are Suche Bin¨are Suchb¨aume Balancierte Suchb¨aume Suchen mit Hashtabellen Suchen in Zeichenketten

2

W¨orterb¨ucher

Notizen

W¨orterbuch Ein W¨ orterbuch (auch genannt Dictionary oder Assoziatives Array) speichert eine Menge von Elementen M. Jedes Element e ∈ M wird durch einen Schl¨ ussel key (e) eindeutig identifiziert. Unterst¨ utzte Operationen sind: • search(key k): finde e ∈ M mit key (e) = k • insert(Element e): erweitere M um e • erase(key k): entferne e aus M, wobei key (e) = k

Beispiele: • Telefonbuch • Element: Name, Adresse und Telefonnummer • Schl¨ ussel: Name

• Compiler-Symboltabelle • Element: Bezeichner und Typ-/Speicher-Informationen • Schl¨ ussel: Bezeichner 3

Such-Algorithmen f¨ur W¨orterb¨ucher

Notizen

Sei M W¨ orterbuch mit |M| = n. • M als verkettete Liste mit linearer Suche • search O(n), insert O(1), erase O(n) • M als sortierte verkettete Liste mit bin¨ arer Suche • search O(log n), insert O(n), erase O(log n) • M als AVL-Suchbaum • search O(log n), insert O(log n), erase O(log n) • M als Hashtabelle • search O(1), insert O(1), erase O(1)

im Mittel!

• Worst case: search O(n), insert O(1), erase O(n)

4

Adresstabellen

Notizen

Sei M W¨ orterbuch.  • Setze U := key (e) : e ∈ M die Menge aller Schl¨ ussel • Annahme: key (e1 ) 6= key (e2 ) f¨ ur alle e1 6= e2 , e1 , e2 ∈ M

W¨orterbuch mit Adresstabelle: • sequentielle Liste T der L¨ ange |U| Schlüsselmenge U

4 1

6 3 2

Adresstabelle T

2

8 7 5

3

5

7

5

Operationen auf Adresstabellen

Notizen

Adresstabelle T mit L¨ange |U|. • Input: Tabelle T , Schl¨ ussel k

Output: Element mit Schl¨ ussel k search(T , k): return T [k]; • Input: Tabelle T , Element e

insert(T , e): T [key (e)] = e; • Input: Tabelle T , Schl¨ ussel k

erase(T , k): T [k] = null; Alle Operationen: Laufzeit O(1) Speicherkomplexit¨at: O(|U|) →

Problem falls U groß! 6

Reduktion von Adresstabellen mittels Hashfunktion

Notizen

• Beobachtung: Menge K der tats¨ achlich benutzten Schl¨ ussel

aus U oft klein Schlüsselmenge U

4 1

6 3

Menge K der tatsächlich benutzten Schlüssel

8

2

Adresstabelle T

7 5

2

3

5

7

• Idee: wende Hashfunktion h auf key (e) an, um Adresstabelle

auf |K | Elemente zu reduzieren



Hashtabelle 7

Hashtabellen

Notizen

W¨orterbuch mit Hashtabelle: • sequentielle Liste T mit L¨ ange m := |K | • Hashfunktion h : U → {0, . . . , m − 1} Schlüsselmenge U

4 1

6 3

Menge K der tatsächlich benutzten Schlüssel

2

h Hashtabelle T

2

5

h 3

8 7

h

h 5

7

8

Operationen auf Hashtabellen

Notizen

Hashtabelle T mit L¨ange m und Hashfunktion h. • Input: Tabelle T , Schl¨ ussel k

Output: Element mit Schl¨ ussel k search(T , k): return T [h(k)]; • Input: Tabelle T , Element e

insert(T , e): T [h(key (e))] = e; • Input: Tabelle T , Schl¨ ussel k

erase(T , k): T [h(k)] = null; Alle Operationen: Laufzeit O(1) Speicherkomplexit¨at: O(m)

(sofern h auch O(1)) 9

Kollisionen bei Hashtabellen

Notizen

• Problem: falls h nicht injektiv → Kollision! • h ist nie injektiv da |K | < |U| Schlüsselmenge U

4 1

6 3

8 9

2

h

7 5

h

h

h

h Kollision!

Hashtabelle T

2

3

5

7

• Offene Fragen: • Strategie zur Kollisionsaufl¨ osung • Wahl von h 10

Verkettung zur Kollisionsaufl¨osung

Notizen

Schlüsselmenge U

4 1

• jeder Slot in T enth¨ alt

6 3

statt Element Referenz auf verkettete Liste

-1

-2

2

9 5

8 7

• bei Kollision: f¨ uge

Element am Anfang der Liste ein → O(1)

h

h

h

h

h

Hashtabelle T

• search und erase m¨ ussen

nun die Liste durchlaufen → O(1) gef¨ahrdet!

-1

3

5

2

9 7

-2

11

Analyse von Hashing mit Verkettung

Notizen

Sei T Hashtabelle mit m Slots und n gespeicherten Elementen. • Belegungsfaktor α = n/m • mittlere Anzahl von Elementen in verketteten Listen • es kann gezeigt werden:

Anzahl der Listendurchl¨aufe ist O(1+α) • Annahme: es ist n = cm mit c Konstante, dann

α = n/m = O(m)/m = O(1) • Komplexit¨ at von search und erase: • im Mittel: O(1) • worst case: O(n)

12

Hashfunktionen

Notizen

Sei U Menge aller Schl¨ ussel, T Hashtabelle mit m Eintr¨agen. h : U → {0, . . . , m − 1}

• Anforderungen an Hashfunktion: • einfache Auswertung O(1) • m¨ oglichst wenige Kollisionen • viele Ans¨ atze, zum Beispiel: • Divisionsmethode • Multiplikationsmethode • universelles Hashing • Vereinbarung: U = N0 zur Vereinfachung • Strings z.B. via ASCII Code auf Zahlen abbilden

13

Divisionsmethode

Notizen

Divisionsmethode Sei U = N0 die Schl¨ usselmenge, sei T Hashtabelle mit m Eintr¨agen. Die Divisionsmethode w¨ahlt die Hashfunktion folgendermaßen: h : U → {0, . . . , m − 1},

h(k) = k mod m.

• Beispiel: m = 12, k = 100, dann ist h(k) = 4. • Problem: geschickte Wahl von m • eher schlecht ist m = 2p (wertet nur die unteresten p Bits von k aus) • eher gut ist oft eine Primzahl, nicht nahe an Zweierpotenz • Beispiel: erwartete Anzahl von Eintr¨ agen in Hashtabelle: 2000, gew¨ unschter Belegungsfaktor 3 → m = 701 geeignete Primzahl 14

Multiplikationsmethode

Notizen

Multiplikationsmethode Sei U = N0 die Schl¨ usselmenge, sei T Hashtabelle mit m Eintr¨agen. Die Multiplikationsmethode w¨ahlt die Hashfunktion folgendermaßen: h : U → {0, . . . , m − 1},

h(k) = bm(kA mod 1)c,

wobei A ∈ (0, 1) Konstante. √

• Vorschlag von Knuth: A ≈ 21 ( 5 − 1) • typische Wahl: m = 2p • Beispiel: m = 214 = 16384, A = 2654435769/232 , und

k = 123456, dann ist h(k) = 67.

15

Universelles Hashing

Notizen

• Problem: f¨ ur jede feste Hashfunktion gibt es

Eingabesequenzen, die worst-case Laufzeit O(n) verursachen • L¨ osung:

Universelles Hashing Sei U = N0 die Schl¨ usselmenge, sei T Hashtabelle mit m Eintr¨agen. Sei H eine endliche Menge von Hashfunktionen:  H = h : U → {0, . . . , m − 1} | h Hashfunktion . H heißt universell, falls f¨ ur jedes Schl¨ usselpaar k, l ∈ U, k 6= l, die Anzahl der Hashfunktionen h mit h(k) = h(l) durch |H|/m nach oben beschr¨ankt ist. • Idee: w¨ ahle zuf¨allig ein h ∈ H • Resultat: Hashing mit Verkettung liefert im Mittel O(1)

Laufzeit der W¨ orterbuch-Operationen 16

Kollisionsaufl¨osung mit offener Adressierung

Notizen

• Idee: statt Verkettung bei Kollision, suche systematisch

n¨achsten freien Platz in Hashtabelle → Sondieren Schlüsselmenge U

4 1

6 3

8

9 2

h Hashtabelle T

2

h 3

7

5

h 5

h

h Kollision! 7

9 Sondieren

• Probleme: • L¨ oschen von Elementen (erase) sehr problematisch • Falls Hashtabelle T voll, kein insert mehr m¨ oglich 17

Offene Adressierung

Notizen

Sei U Schl¨ usselmenge, T Hashtabelle mit m Eintr¨agen. • erweitere Hashfunktion zu

h : U × {0, . . . , m − 1} → {0, . . . , m − 1} • fordere, daß Sondierungssequenz

 h(k, 0), h(k, 1), . . . , h(k, m − 1) eine Permutation von (0, . . . , m − 1) ist → jeder Slot in T ist m¨ ogliches Ziel f¨ ur Schl¨ ussel k • viele m¨ ogliche Sondierungssequenzen, zum Beispiel: • lineares Sondieren • quadratisches Sondieren • doppeltes Hashing 18

Hashing: Ausblick

Notizen

¨ • nachtr¨ agliche Anderung der Tabellengr¨oße aufwendig • erfordert neue Tabelle und neue Hashfunktion • u ¨bertragen aller Elemente (und Berechnung neuer Hashfunktion) n¨ otig • ist U statisch, so ist perfektes Hashing m¨ oglich • auch im worst-case sind alle Operationen O(1) • umgesetzt durch zwei Ebenen von universellem Hashing • Zeitgewinn erkauft durch zus¨ atzlichen Speicherbedarf von O(n)

19

Programm heute

Notizen

7 Fortgeschrittene Datenstrukturen

8 Such-Algorithmen

Lineare Suche Bin¨are Suche Bin¨are Suchb¨aume Balancierte Suchb¨aume Suchen mit Hashtabellen Suchen in Zeichenketten

20

Suchen in Zeichenketten

Notizen

• Problem: find Teilwort in (langem) anderen Wort • auch genannt: String-Matching • Beispiele: • Suche Text in Textverarbeitung / Web-Browser • Suche Text in Dateien auf Festplatte (z.B. Spotlight, Windows Search) • Suche Text im Internet (z.B. Google) • Maß der Effizienz: Anzahl der Vergleiche zwischen Buchstaben

der Worte

21

Brute-Force Suche D A S 1 1 3

S

I

S T E

Notizen

I N S

I N N L O S E R T E X T

I N N S

I N N S

1 2 4 4

I N N S

I N N S

I N N

... S

I N N

16 Vergleiche

22

Notationen

Notizen

• Zu durchsuchender Text: • text[0..n − 1] • L¨ ange n • gesuchtes Muster = Pattern: • pat[0..m − 1] • L¨ ange m • Problem: finde Position i, so daß pat == text[i..i + m − 1]

23

Brute-Force Algorithmus

Notizen

Input: zu durchsuchender Text text L¨ange n, gesuchtes Muster pat L¨ange m Output: Index i von Match (oder -1 falls nicht gefunden) bruteForceSearch(text, pat): for i = 0 to n − m { j = 0; while ( (j < m) && (pat[j] == text[i + j]) ) j = j + 1; if (j ≥ m) return i; // f¨ undig geworden } return -1; // nichts gefunden

• Komplexit¨ at: O((n − m)m) = O(nm)

24

Knuth-Morris-Pratt Algorithmus

Notizen

Knuth-Morris-Pratt Algorithmus (kurz: KMP) • Idee: verbessere Brute-Force Algorithmus durch Ausnutzung

der bereits gelesenen Information bei einem Mismatch • Mismatch an Stelle j von pat impliziert

pat[0..j − 1] == text[i..i + j − 1]

text: D A S

I

pat:

I N N

S

S T E

I N S

I N N L O S E R T E X T

• Vorverarbeitungsschritt: analysiere vor Suche das Muster pat,

¨ speichere m¨ ogliche Uberspringungen in Feld shift

25

Alphabet und W¨orter

Notizen

W¨orter Ein Alphabet Σ ist eine endliche Menge von Symbolen. Ein Wort w der L¨ange n u ¨ber Σ ist eine endliche Folge von Symbolen w = w1 · · · wn ,

wi ∈ Σ, i = 1, . . . , n.

Beispiel: • Alphabet Σ = { a,...,z, A,...,Z } • W¨ orter: Daten, Algorithmen, aabb • keine W¨ orter: ¨ uber, t35t

• Alphabet Σ = { 0,...,9,A,B,C,D,E,F } • W¨ orter: 09FF, ABC, A3E • keine W¨ orter: 1f, 1gH

Das leere Wort wird mit ε bezeichnet. 26

Pr¨afix und Suffix von einem Wort

Notizen

Pr¨afix, Suffix Sei w = w1 · · · wn Wort der L¨ange n u ¨ber einem Alphabet Σ. 0 • Das Wort w heißt Pr¨ afix von w , falls w 0 = w1 · · · wl f¨ ur 0 ≤ l ≤ n. • Das Wort w 0 heißt Suffix von w , falls w 0 = wl · · · wn f¨ ur

1 ≤ l ≤ n + 1. Beispiele f¨ ur Wort w = Algorithmen: • Pr¨ afixe von w sind: A, Alg, Algorit, Algorithmen • Suffixe von w sind: n, men, gorithmen, Algorithmen

27

Rand von einem Wort

Notizen

Rand Sei w Wort u ¨ber einem Alphabet Σ. Ein Wort r heißt Rand von w , falls r sowohl Pr¨afix als auch Suffix von w ist. Ein Rand r von w heißt eigentlicher Rand, wenn r 6= w und wenn es außer w selbst keinen l¨angeren Rand gibt. Der eigentliche Rand von w wird mit ∂(w ) bezeichnet. Beispiel: Wort w = aabaabaa hat folgende R¨ander: • ε • a • aa • aabaa

← eigentlicher Rand

• aabaabaa = w 28

¨ Uberspringen beim Suchen

Notizen

text: pat: shift

• Idee: verschiebe Pattern so, daß im bereits gepr¨ uften Bereich

¨ wieder Ubereinstimmung herrscht

• dazu m¨ ussen Pr¨afix und Suffix dieses Bereichs u ¨bereinstimmen

→ eigentlicher Rand

29

Shift-Tabelle

Notizen

Shift-Tabelle Sei pat = s0 · · · sm−1 Wort der L¨ange m. Die Shift-Tabelle von pat gibt die L¨ange des eigentlichen Randes des Pr¨afixes der L¨ange j von pat an. Sie hat folgende Gestalt: ( −1 f¨ ur j = 0 shift[j] = ∂(s0 · · · sj−1 ) f¨ ur j ≥ 1 wobei j = 0, . . . , m − 1. • Ist das Pr¨ afix der L¨ange j gematcht, und an Stelle j ein

Mismatch, so ist der Shift j − shift[j] > 0 korrekt

30

KMP Algorithmus: Beispiel I

Notizen

text:

A B C A B A B A B C A A B A B

pat:

A B C A A B A B C A A B A B C A A B A B C A A B

j

0

1

2

3

4

5

shift[j]

-1

0

0

0

1

1

31

KMP Algorithmus

Notizen

Input: zu durchsuchender Text text L¨ange n, gesuchtes Muster pat L¨ange m Output: Index i von Match (oder -1 falls nicht gefunden) KMPSearch(text, pat): initShift(pat); // Initialisierung shift Tabelle, siehe sp¨ater i = 0; j = 0; while (i ≤ n − m) { while (text[i + j] == pat[j]) { j = j + 1; if (j == m) return i; // f¨ undig geworden } i = i + (j − shift[j]); // j − shift[j] ist immer > 0 j = max(0, shift[j]); } return -1; // war wohl nix 32

KMP Algorithmus: Beispiel II i=

0

3

5

Notizen

7

text:

A B C A B A B A B C A A B A B

pat:

A B C A A B

j=

0 1 2 3 4 A B C A A B j=

0 1 2 A B C A A B j=

0 1 2 A B C A A B j=

0 1 2 3 4 5

j

0

1

2

3

4

5

shift[j]

-1

0

0

0

1

1 33

Shift Tabelle Beispiel I

Notizen

j 1

shift[j] A B C A A B

0

A B C A A B 2

A B C A A B

0

A B C A A B 3

A B C A A B

0

A B C A A B 4

A B C A A B

1

A B C A A B 5

A B C A A B

1

A B C A A B

34

KMP Algorithmus: Shift Tabelle

Notizen

Input: Muster pat der L¨ange m initShift(pat): shift[0] = −1; shift[1] = 0; i = 0; for j = 2 to m { // hier ist: i == shift[j − 1] while (i ≥ 0 && pat[i] 6= pat[j − 1]) i = shift[i]; i = i + 1; shift[j] = i; }

35

KMP Algorithmus: Komplexit¨at

Notizen

Komplexit¨at von KMP Algorithmus: • KMPSearch: • erfolglose Vergleiche (¨ außere while-Schleife): maximal

n − m + 1 Vergleiche • erfolgreiche Vergleiche (innere while-Schleife): ingesamt

maximal n Vergleiche • insgesamt: maximal 2n − m + 1 Vergleiche

• initShift: • erfolgreiche Vergleiche (for-Schleife): maximal m − 1 Vergleiche • erfolglose Vergleiche (while-Schleife): maximal m Vergleiche • insgesamt: maximal 2m − 1 Vergleiche • insgesamt: maximal 2n + m Vergleiche, also O(n + m) • Platzbedarf: O(m)

36

Ausblick: Suchen in Zeichenketten

Notizen

• Brute-Force Algorithmus • Komplexit¨ at: O(mn) • Knuth-Morris-Pratt Algorithmus • Komplexit¨ at: O(m + n) • Rabin-Karp Algorithmus: Suchen mit Hash-Funktion • Komplexit¨ at im Mittel: O(m + n) • Komplexit¨ at worst-case: O(mn) • Boyer-Moore Algorithmus: Suchen r¨ uckw¨arts • Komplexit¨ at: O(n) • Komplexit¨ at best-case: O(n/m) • Regul¨ are Ausdr¨ ucke mit endlichen Automaten • Suche nach ¨ ahnlichen Zeichenketten

37

Zusammenfassung

Notizen

7 Fortgeschrittene Datenstrukturen

8 Such-Algorithmen

Lineare Suche Bin¨are Suche Bin¨are Suchb¨aume Balancierte Suchb¨aume Suchen mit Hashtabellen Suchen in Zeichenketten

38