Beruflich Dokumente
Kultur Dokumente
im WS 08/09
1
.
2
Inhaltsverzeichnis
1 Analyse von Algorithmen 6
1.1 Effizienz (insbesondere Laufzeit) von Algorithmen . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.1 Experimentelle Analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.2 Theoretische Analyse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.1.3 Pseudo- Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1.4 Registermaschine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
1.1.5 Laufzeit von Algorithmen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.1.6 Asymptotisches Laufzeit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.1.7 Rekursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
1.1.8 Rekursion auf der RAM . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16
1.2 Datenstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.2.1 Beispiel Stapel (Stack) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
1.2.2 “Indirekte” Anwendung von Stapeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1.3 Dynamisierung Array- basierter Datenstrukturen . . . . . . . . . . . . . . . . . . . . . . . . . 21
2 Datenabstraktion 24
2.1 Geheimnisprinzip . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2.2 Abstrakte Datentypen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2.1 Explizite Schnittstellenbeschreibung in Java . . . . . . . . . . . . . . . . . . . . . . . . 25
3
3.7.1 Implementierung des ADT Wörterbuch . . . . . . . . . . . . . . . . . . . . . . . . . . 44
3.7.2 Implementierung durch Hashing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.7.3 Hashcodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45
3.7.3.1 Analyse der mittleren Laufzeit von Hashing mit Verkettung . . . . . . . . . . 47
3.7.4 Zufallsexperiment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49
3.7.5 Universelle Hashfunktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
3.8 ADT Geordnetes Wörterbuch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.8.1 Implementierung ADT Geordnetes Wörterbuch . . . . . . . . . . . . . . . . . . . . . 53
3.8.2 Skip Liste: . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.8.2.1 Suche in einer Skip- Liste(find, succ, pred) . . . . . . . . . . . . . . . . . . . 54
3.8.2.2 Bestimmung der Si (mod r)
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.8.2.3 Löschen von z ∈ S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.8.2.4 Einfügen von z ∈ S . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 54
3.8.3 Balancierte Mehrweg- Bäume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.9 (2,4)- Bäume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.9.1 (a,b)- Bäume (a, b ∈ N, b + 1 ≥ 2a) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.9.2 Amortisierte Rebalancierungskosten in (2,5)- Bäumen . . . . . . . . . . . . . . . . . . 61
3.10 Implementierung von geordneten Wörterbüchern für Zeichenketten . . . . . . . . . . . . . . . 62
3.11 Wörterbücher für Strings- Trie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
3.11.1 Suffixbaum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
3.12 Suffix- Bäume TRIE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
3.13 Sequence- Alignment Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.13.1 Kosten eines Alignments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
3.13.2 Alignment von Zeichenketten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
3.13.2.1 Berechnung von OPT(m,n) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69
4
5 Minimal aufspannenden Bäumen (MST) 92
5.1 Berechnung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
5.2 Generischer MST- Algorithmus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 92
5.3 Begriffe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93
5
16. Oktober 2008
Frage nach
(Funktion die einer Eingabe die Laufzeit des Algorithmus darauf zuordnet)
• Implementierung
• Messung der Laufzeit auf vielen, “typischen” Eingaben
Problematisch!
• dabei betrachten wir den schlechtesten Fall für alle Eingaben fester Länge (“worst case”- Analyse)
6
1.1.3 Pseudo- Code
Bsp.
ArrayMax (A, n)
Input: Feld A [1, ..., n] von n ganzen Zahlen
max
Output: 1≤i≤n A [i]
currentMax ← A [1]
for i = 2 to n
if current Max < A [i] then currentMax = A [i]
return currentMax
Im Detail:
“Verboten”:
ArrayMax+ (A, n)
max
return 1≤i≤n A [i]
1.1.4 Registermaschine
7
• Rechenkern = arithm. Operationen (+, -, ·, /)
• Kontrollflussoperationen (JMP, bedingte Sprünge)
• all diese Operatoren können in einem Takt bearbeitet werden
– linear organisierter Speicher mit whalfreiem Zugriff
∗ jede Zelle kann eine ganze Zahl speichern
∗ auf jede Zelle kann in einem Takt (durch Angabe der Adresse) zugegriffen werden
∗ der Speicher ist unbegrenzt
Pseudo Code ist O.K. falls jede primtive Operation durch ≤ 10 RAM- Anweisungen ausgeführt werden kann.
Def:
A Algorithmus (RAM- Programm)
I Eingabe für A
TA (I) = Anzahl der RAM Operationen die A auf Eingabe I macht “Rechenzeit von A uf I”
TA (n) = max I,Groesse
max
von I=n TA (I) “worst- case Rechenzeit von A”
Algorithm d o u b l e ( x )
Input x ∈ N
Output 2x
y <− x
y <− y + x
return y
(Pseudocode)
8
Beispiel (II) ohne Addition:
Algorithm d o u b l e ( x )
Input x ∈ N
Output 2x
z <− x
y <− x
f o r i =1 t o z do
y <− y + 1
return y
(Pseudocode)
TA (x) − ”3 + 2x
Typischerweise analyisieren wir Algorithmen im Pseudocode (Laufzeit ≈Anzahl der Pseudocodezeilen)
Das ist zulässig, solange der verwendete Pseudo- Code die Eigenschaft hat, dass jede Code- Zeile durch
konstant viele RAM- Operationen realisiert wrrden können.
• “moderate” Änderungen des Maschinenmodells ändern die Laufzeit nur um einen konstanten Faktor.
• die asymptotische Laufzeit ignoriert konstante Faktoren und Terme niederer Ordnung.
Bsp.:
TA (n) = 1, 75n3 + (0, 4 log2 n) = Θ(n3 )
1. f (n) = O(g(n))
2. f ∈ O(g)
BSP :
9
O-Notation HOWTO
1.)
!d
f (n) = i=0 ai ni mit ai ≥ 0
f (n) = O(nd )
2.)
Wir sagen ”2n = O(n)” statt ”2n = O(n2 )”
3.)
Wir sagen ”2n = O(n)” statt ”2n = O(3n − 6)”
4.)
Die Analogie O=
ˆ ≤, Ω=
ˆ ≥, θ=
ˆ =
klappt oft (aber Vorsicht: nicht immer)
5.)
nα = O(nβ ) ∀ α ≤ β
6.)
(log n)α = O(nβ ) ∀α, β > 0
Beispiel:
Algorithm PrefixAverage (X, n)
Input X[0], . . . , X[n − 1], n
!
Output A[0], . . . , A[n − 1] mit A[i] = 1
i+1 j≤i A[j]
A<−l e e r e s Feld mit n Elementen //1−mal d u r c h l a u f e n
f o r i = 0 t o n−1 do //n−mal d u r c h l a u f e n
sum <− 0 //n−mal d u r c h l a u f e n
f o r j = 0 t o i do / / ( i +1 mal d u r c h l a u f e n )
sum <− sum + X[ j ] //im i −t e n D u r c h l a u f d e r ä u ß e r e n S c h l e i f e
A[ i ] <− ( sum ) / ( i +1) //n−mal d u r c h l a u f e n
return A //1−mal d u r c h l a u f e n
Gesamtkosten:
n−1
&
O(1) + O(n) + O( (i + 1))
" #$ % " #$ %
i=0
1&7 2&6,3 " #$ %
4&5
Laufzeit O(n)
10
1.1.7 Rekursion
Beispiel:
Potenzieren x, n ∈ N
p(x, n) := xn = x
" · .#$
. . · x%
n−mal
Laufzeit:
'
O(1) n=0
T (n) =
T (n − 1) + O(1) n>0
Lösung (n > 0) mit C > 0
T (n) ≤ T (n − 1) + C ≤ T (n − 2) + 2 · C ≤ T (n − 3) + 3 · C
per Induktion: T(n) ≤ T(n − k) + k · C
∀k ≤ 1 für k = n: T (n) ≤ T (0) + n · C
Beweis:
x · P ow(x, n − 1)
x∗Pow( x , n−1)=x∗x∗Pow( x , n−2)
=x∗x∗x∗Pow( x , n−3)
=x ∗ ( n−mal ) ∗ x∗Pow( x , 0 ) //Pow( x ,0)=1
Algorithm PowFast(x,n)
i f n=0 r e t u r n 1
i f n=2k then
z <− PowFast ( x , 1 / 2 ) // n i c h t s o ! S y n t a k t i s c h a b e r k o r r e k t
return z∗z
i f n=2k+1 then
z <− PowFast ( x , ( n −1)/2)
r e t u r n z ∗ z ∗x
11
Laufzeitanalyse
Beschränken auf n = 2r für r ≥ 0
'
O(1) n=1
T (n) = ,n-
T 2 + O(1) n>1
S(r) := T(2r )
'
O(1) r=1
S(r) =
S(r − 1) + O(1) r>0
wie in (2:)
S(r) = O(r) = T (2r )
also
T (n) = O(log n)
12
28.Oktober 2008
1.1.7.1 Rekursionsbäume
Bsp.: PowFast
Fibonacci Zahlen
Bsp: Fibonacci- Zahlen
F(0)=F(1)=1
F(n)=F(n-1)+F(n-2), n ≥ 2
Definition:
13
• Kinder von Knoten v sind die (rek.) Aufrufe von A die v tätigt (mit den jeweiligen Argumenten)
Die Rechenzeit von A auf x lässt sich bestimmen, indem man die in den Knoten des Berechnugsbam von A
auf x anfallende Arbeit aufsummiert.
Bsp: Mergesort
Analyse
14
Gesamtkosten:
n n n n n n
c · n + c( ) + c( ) + c( ) + c( ) + c( ) + c( ) + . . .
"#$%
" 2 #$ 2 % " 4 4 #$ 4 4%
W urzel
Kinder d. W urzel Enkel der W urzel
= c · (n + n2 ) + n2 ) + ( n4 + n
4 + n
4 + n4 ) + . . .)
= c(n + n + n + n + . . .)
= c · n (1 + 1 + 1 + . . . + 1) = c · n· Höhe des Baumes = c · n · log n
" #$ %
#Rekursionsstuf en
15
≥ 2(2(2 · F (n − 6)))
≥ 2i · F (n − 2i) (per Induktion)
Damit (i = u2 )
n √
F (n) = 2 2 = ( 2)n
Alternativen
Iteration:
Ind.
f$n = M · f$n−1 = M · M · f$n−2 = M · M · M · f$n−3 = M · . . . · M · f$n−i (i ≥ 1)
" #$ %
i−mal
= M · f$n−i
i
i=n−1
= M n−1 · f$1
Kann in O(log n) Zeit durch schnelle (Matrix-) Exponentiation berechnet werden.
Algorithm min ( )
x <− 5
subroutine1 (x)
Algorithm s u b r o u t i n e 1 ( i )
k <− i +1
subroutine2 (k)
Algorithm s u b r o u t i n e ( k )
y <− 6
16
30. Oktober 2008
1.2 Datenstrukturen
Schema zur Organisation von Daten, so dass gewisse Operationen auf / Manipulationen von Daten effektiv
durchführbar sind.
Manipulation von von Objekten erfolgt nach dem LIFO (last in- first out) Prinzip (hier: “Objekte”=int)
d.h. wir benötigen die Operationen
Implementierung:
17
Java- Implementierung:
c l a s s i n t ArrayStack {
int F [ ] ;
i n t top ;
i n t M;
i n t ArrayStack ( i n t m) {
M = m;
top = −1;
F = new i n t M[ ] ;
}
hier:
• Platzbedarf Θ(M )
• Θ(1) Zeit für push & pop
Probleme:
18
• Einfügen und Löschen am Anfang der einfach verketteten Liste ist einfach (Θ(1) Zeit )
Beispiel: Gegeben
x2 wird von x3 verdeckt, x4 wird von x5 verdeckt. Wäre ein x6 größer als x5 und kleiner als x3, wäre auch
x5 verdeckt.
Span berechnen:
Feld X[0],...,X[1] von n Zahlen
Berechne für alle 0 ≤ i ≤ n − 1
S[i] = max. Anzahl von aufeinanderfolgenden Elementen unmittelbar vor X[i] die kleiner als X[i] sind.
Algorithm Span (X, n )
S <− Neues Feld mit n E i n t r ä g e n
| f o r i = 0 t o n−1 do
| S [ i ] <− 0
| | f o r j = 0 t o i do
| | i f X[ i −j ] " k l e i n e r g l e i c h " X[ i ] do
| | S [ i ]++
| | e l s e break ;
i
n−1
&&
Θ( 1) = Θ(n2 )
i=0 j=0
19
04. November 2008
Besser mittels Hilfsfunktion
• am Index i
entferne alle Elemente von der Spitze des Stapels die ≤ X[i] sind und zähle span(X[i]) je um eins hoch
lege X[i] auf Stapel
f o r i =0 t o n−1 do
w h i l e ( ! isEmpty (A)&&((X[ top (A)]) <= X[ i ] ) ) do // e n t f e r n e a l l e Elemente
pop (A) // aus A d i e k l e i n e r a l s X[ i ] s i n d
Analyse:
n push − Operationen
≤n pop − Operationen
≤ 2n isEmpty − Operationen
Stack mit einfach verketteten Listen ⇒ Θ(n) Gesamtlaufzeit.
20
1.3 Dynamisierung Array- basierter Datenstrukturen
Ziel:
• Wir haben zu jedem Zeitpunkt ein Array in dem alle Elemente des Stapels abgespeichert sind.
• Wenn Platz in diesem Array nicht mehr ausreicht, legen wir ein neues Array doppelter Größer an und
kopieren das alte Feld in den Anfang des neuen Feldes.
Probleme dabei:
21
Begründung:
1. Eine pop- Op benötigt nur Θ(1) Zeit. D.h. alle pop- Op’s in einer Folge von n push/pop- Op’s benötigt
O(n) Zeit.
2. Betrachte Folge von n push- Op’s.
'
O(k) k = 2i
Die k-te push- Operation benötigt Zeit Tk =
O(1) sonst
Gesamtzeit für n push- Operationen
n $log2 n%
& &
Tk = O(n) + T2i
k=0 i=0
$log2 n%
&
= O(n) + O(2i )
i=0
= O(n) + O(n)
n
&
Tk = O(n)
k=0
Definition (amortisiert):
Gegeben sie eine Datenstruktur, für die eine Folge von n Operationen insgesamt T(n) Zeit benötigt.
T (n)
Dann nennen wir n die amortisierten Kosten pro Operation.
22
06. November 2008
• Eine Folge F von Operationen verursacht damit Gesamtkosten cF
(Ziel: zeige, dass cF = O(n) falls |F | = n)
• Wir werden zeigen: Falls wir jeder Operation 2$ “mitgeben”, können wir am Schluss die Kosten cF
begleichen.
Buchhaltervorschrift
– kein Kopieren : bezahle Kosten (1$) und lege 1$ auf das DS Sparbuch
– mit Kopieren: bezahle Kosten (# Elemente im Stack) von meinen 2$ auf Sparbuch
2. es gilt cF = 2$ · |F |
• eine push- Op veranlasst, das im Fall mit M Einträgen verdoppelt wird, hat zur Folge, dass danach
mind. M Operationen ausgeführt werden können, die nur 1$ kosten.
• der nächste auffallende Verdopplung kostet 2M $.
Problem: Der Platzbedarf der DS hängt nicht von der Anzahl der Elemente (tatsächlich von der maximalen
Stackgröße) ab, die in der DS gespeichert worden, sondern von der Anzahl der durchgeführten Operationen.
23
2 Datenabstraktion
2.1 Geheimnisprinzip
Kenntnis der Spezifikationen eines Moduls, Datentyp, Systems ist notwendige und hinreichende Voraussetzung
für deren konkrete Benutzung.
Datenabstraktion ist die Anwendung des Geheimnisprinzips auf die Darstellung komplexer Datenstrukturen:
• Das Klassenkonzept untersützt die Zusammenfassung von Daten und dem sie manipulierenden Opera-
tionen (in einer syntaktischen Form).
• In Java kann das Verberigen der internen Repräsentation durch Sichtbarkeitsmodifikatoren erreicht
werden.
– public : überall
– protected : innerhalb des eigenen Pakets und in den Unterklassen
– private : nur innerhalb der umschließenden Klasse
– default : innerhalb des Pakets
Object pop ( ) . . .
}
24
11. November 2008
Definition ADT :
Ein ADT ist eine Menge von Objekten mit einer Menge von Operationen auf diesen Objekten.
alternativ:
Ein Typ, dessen Objekte nur über die Operationen seiner Schnittstelle manipuliert werden können.
Beispiel: Stack
Operationen :
push : ( x , S ) −> S
pop : ( S ) −> S
Objekte
Folgen (von Elementen)
↑ nach dem LIFO- Prinzip
Reale Welt
“reelle” Objekte mit “rellen” Operatoren
↓ Modellierung
↓ Implementierung
Datenstruktur, Methoden
“Probleme”
25
9, 1, 2, 5, 7, 5,
push_left push_right
pop_left pop_right
Im Programm:
( 1 ) F e s t l e g u n g a u f e i n e k o n k r e t e Implementierung
(2) e v t l . andere
S t a c k I n t e r f a c e s = new Stack ( ) ;
S t a c k I n t e r f a c e s = new S t a c k I n t e r f a c e ( ) ;
Pflichten:
Rechte:
Bemerkung:
26
13. November 2008
PQ H;
f o r i = 1 t o n do
H. i n s e r t (A[ i ] ) ;
f o r i = 1 t o n do
p r i n t H. f i n d m i n ( ) ;
H. d e l e t e m i n ( ) ;
27
3.1.1 Implementierung des ADT PWS (für U = N)
(a)
Implementierung der PWS als einfach verkettete Liste
l·n=m
Tfindmin = O(l)
Tinsert = O(l)
Tdeletemin = O(l + m)
Damit:
√
Gesamtlaufzeit : (Optimal für l = m = n)
√
O(n · l + n · m + n) = O(n · n)
(c) Heaps
Ein heapgeordneter Baum für eine Menge S ⊂ U ist ein Baum auf den Elementen von S, wobei gilt:
u Kind von v ⇒ u ≥ v
28
Bsp.:
29
insbesondere:
interface PrioritätsWarteSchlange {
void i n s e r t ( Object o ) ;
Object findmin ( ) ;
void deletemin ( ) ;
}
30
18. November 2008
* findmin trivial
* deletemin setzt die Wurzel auf ”∞” und lässt sie “absinken” bis zu einem Blatt und entfernt dieses
* insert ausgehend von einer “freien Position” (abhängig von Details der Baumstruktur)
füge neues Objekt ein und lass es “aufsteigen”
wir betrachten:
• binär
• heap- geordnete Bäume, wo die Tiefe von Blättern sich max im 1 unterscheidet
• alle bis auf einen inneren Knoten genau zwei Kinder haben
Fakt:
Diemaximale Tiefe eines binären Heaos mit n Elementen ist O(log n)
31
• wir stellen binäre Heaps so dar, dass die letzte Ebene des Baumes von links nach rechts aufgefüllt ist
• wir “merken” uns das “rechteste” Blatt der letzten Ebene & das erste freie Blatt
32
Laufzeit:
33
20. November 2008
triviale Implementierung
i n t e r f a c e VPWS {
void i n s e r t ( Object o ) ;
void d e l e t e m i n ( ) ;
Object f i n d m i n ( ) ;
void meld (VPWS P ) ;
}
i n t e r f a c e PWS {
void i n s e r t ( Object o ) ;
void d e l e t e m i n ( ) ;
Object f i n d m i n ( ) ;
void d e l e t e m i n ( ) {
P. deletemin ( ) ;
}
34
Vererbung (Einschluss- Polymorphie) in Java
(Polymorphie = Vielgestaltigkeit)
Klasse (bzw. Schnittstelle) Y wird als Erweiterung der Klasse X vereinbart und erbt damit die Eigenschaften
von X.
Syntax:
c l a s s X { Text von X }
Umgesetzt:
i n t e r f a c e VPWS extends PWS {
void meld ( . . . ) ;
}
bzw.
c l a s s VBinaerHeap extends BinaerHeap implements VWPS {
void meld . . .
}
35
3.4 neue Implementierung als Binomialheaps
Binomialbäume:
Bsp:
Es gilt:
Ein Binomialheap mit n Elementen S ist ein Wald von Binomialbäumen in denen die Elemente von S heap-
geordnet gespeichert sind. Jeder Bi kommt dabei höchstens 1x vor. Das gilt immer !
Bsp:
S = {7, 5, 1, 4, 13, 6} n = 6 = 22 + 21 ⇒ B1 und B2
36
Die (Wurzeln) der Binomilabäume sind in einer Liste verkettet, sortiert nach ihrem Grad.
(a) meld
• zu jedem Zeitpunkt stellen wir sicher, dass es im Resultat nur einen Baum pro Grad gibt
• es gibt jeweils maximal einen Baum C der aus dem vorherigen Schritt als Übertrag kommt
• sei A der aktuelle Binomialbaum von P
sei B der aktuelle Binomialbaum von Q
37
25. November 2008
verschmelzen
n=4
8 + 4 + 2 = 23 + 22 + 21
• findmin(P)
• insert(P,x)
• deletemin(P)
– Finde Bi in der Wurzelliste der Minimum speichert (in seiner Wurzel), entferne Bi aus der Wurzel-
liste, entferne Wurzel von Bi (resultiert in {B0 , . . . , Bi−1 }) und erzeugen damit neuen Binärheap.
Verschmelzen den neuen & den alten Heap.
O(log |P |) Zeit
Bsp.:
38
mögliche Lösung
Schnittstellenmethoden zum Einfügen von Objekten liefern einen “Zeiger” auf den Eintrag der Objekte in der
DS.
z.B.:
c l a s s PWSEintrag {
int Prioritaet ;
Object E i n t r a g ;
int Position ;
}
3.6 Bäume
mathematischer Kontext Informatik Kontext
Kreisfreier zusammenhängender Graph gerichteter Graph T = (V, E)
typischerweise gibt es eine (totale Ordnung) Wurzel w ∈ V
auf den Kindern eines Knotens. (u, v) ∈ E
v heißt Kind (Nachfolger) von u
u heißt Erziehungsberechtigter (Vorgänger) von v
ADT Knoten
• speichert Objekte
• Manipulation/Zugriff
void setInfo (Object o);
Object getInfo();
Knoten getRoot ( ) ;
Knoten g e t P a r e n t ( Knoten k ) ;
boolean a L e a f ( Knoten k ) ;
Knoten g e t C h i l d ( Knoten k , int i ) ;
int g e t D e g r e e ( Knoten k ) ;
39
27. November 2008
Implementierung von Bäumen
Bsp. k=3
h=0 30 = 1
h=1 30 + 3 · 30 = n0 + 3n0 = 4
h=2 4 + 3 · 3 = 13
h=3 13 + 9 · 3 = 40
h
& q n+1 − 1
qi =
i=0
q−1
40
Algorithmen auf Bäumen
inorder: besuche erst den linken Teilbaum unter der Wurzel, dann die Wurzel, dann ihren rechten
Teilbaum
preorder: besuche zuerst die Wurzel, dann dann links, dann rechts
T = (V, E)
in : V → N inorder Traversierung
h : V → N Höhenfunktion
'
V → R2
ϕ=
∪ → (in(u), h(u))
z.B. 12345+3456.
41
3.6.1.1 Darstellung als Ausdrucksbaums z.B.: ((2 + 5) − (7 + 12))
42
02. Dezember 2008
3.6.2 weitere Anwendungen: Spielbäume
TicTacToe
Beginnt der Kreis- Spieler in der Mitte, hat der Kreuz- Spieler acht verschiedene Möglichkeiten sein Kreuz
zu setzen.
Dann hat der Kreis- Spieler sieben Möglichkeiten. ...
Nehme als Root das leere Spielfeld. Der erste Nachfolger sind neun Knoten, alle Möglichkeiten für die erste
Belegung. Die Nachfolger dieser Knoten sind jeweils die acht Möglichkeiten, ein Kreuz zu setzen. usw.
Es gibt besondere Knoten, bei denen das Spiel zu Ende ist. Dieser Knoten ist ein Blatt. Entweder, das Spiel
wird gewonnen oder es gibt ein Remis.
Zunächst werden alle Nachfolger der Wurzel erzeugt, erfüllen sie die Anforderung? Nun werden die Kinder
erzeugt, usw.
⇒ Breitensuche
1. Wurzel (r)
2. Kinder der Wurzel (seien diese w1 , w2 , w3 )
3. Kinder der Knoten aus 2. ; erst die Kinder von w1 , dann die Kinder von w2 , dann die Kinder von w3
4. Deren Kinder. Nach Methodik von 3.
43
3.7 ADT Wörterbuch (Dictionary)
find(k,S) bestimme, ob k ∈ S
insert(k,S) füge k zu S hinzu
Bemerkung:
Vielfache Anwendungen!
1. Verkettete Liste
Platzbedarf θ(|S|)
Laufzeit:
insert θ(1) ggf. θ(|S|)
find θ(|S|)
delete θ(1) falls falls Zeiger in die Liste zeigt
sonst θ(|S|)
2. Hashing (Streuspeicherung)
44
04. Dezember 2008
3.7.2 Implementierung durch Hashing
U Universum
S⊂U
h1 : U → N
h2 : N → [1, . . . N ]
h2 (n) = 1 + (n mod 4)
3.7.3 Hashcodes
!∗
1. Zeichenketten s = s1 . . . sk ∈
(a) Länge
!0 ! !
(b) h! (s) = h1 (si )| | {σ0 , . . . , σl }
'!
→N
wobei 0
h1 =
σi 0→ i
z.B.: ASCII
s = AFFE
!
| | = 256, h1 (A) = 65 , h2 (F ) = 70 , h3 (E) = 69 , h1 (s) = (((65 · 256 + 70) · 256) + 70) · 256 + 69
2. Floatingpoint- Zahlen
Kompressionsverfahren
Idee: h2 soll S “möglichst geleichmäßig” auf [1, . . . N ] aufteilen. Typischerweise ist N eine Primzahl
Bsp.:
1. h2 (x) = 1 + (x mod N )
U Universum
|U | = u
S ⊂ U, |S| = n
45
Hashfunktion in Tabelle T der Größe N. (Hashfunktion ist fest)
Hashtabelle mit N Einträgen
h : U → [0, . . . , N − 1]
n- elementige Teilmengen von U sollen verwaltet werden.
Analyse:
hängt ab von
Falls h in O(n) Zeit ausgewertet werden kann, benötigen alle Operationen θ(1 + |Cs (k)|) Zeit.
46
3.7.3.1 Analyse der mittleren Laufzeit von Hashing mit Verkettung
1 1
P r(S = V ) = pv = . /=
u |W |
n
W = {S ⊂ U | |S| = n}
Für k ∈ U fest betrachten wir Cs (k) Zufallsvariable und interessieren uns für
E [CS (K)] =
& 1
pv |Cv (k)| =
|W |
v∈W
!
v∈W [CS (K)]
Beweis:
'
& & 1 y∈S
[CS (K)] = 1= iS (y) mit iS (y) =
y∈S, h(k)=h(y) y∈U, h(k)=h(y)
0 sonst
Damit
1 &
E [CS (K)] = · [CV (K)]
|W |
V ∈W
1 & &
= · · v(y)
|W |
V ∈W y∈U, h(k)=h(y)
pv
$%"#
& & 1
= · v(y)
|W |
V ∈W y∈U, h(k)=h(y)
47
,u−1-
n
E[iS (y)] = 1 · P r(iS (y) = 1) + 0 · P r(is (y) = 0) = P r(y ∈ S) = n−1
, n- =
u
u
(*)
48
09. Dezember 2008
3.7.4 Zufallsexperiment
,U -
S∈ n wird zufällig (unter Gleichverteilung gewählt)
Analyse Zufallsvariable (für x ∈ U )
|CS (x)| = |{y ∈ S|h(x) = h(y)}| (s.o.)
Fortsetzung von (*)
& n
=⇒ E [CS (x)] =
u
y∈U, h(k)=h(y)
n &
= · 1
u
y∈U, h(k)=h(y)
n
= · |CS (x)| = |{y ∈ S|h(x) = h(y)}|
u
Def.:
(a) mit N = θ(n) erhalten wir θ(1) (erwartete) Zugriffszeit und θ(n) Speicher.
(unter den bekannten Annahmen)
(b) Falls n nicht bekannt ist, kann durch Verdoppeln, bzw. Halbieren der Tabellengröße (inkl. Umko-
pieren) θ(1) amortisierte erwartete Laufzeit bei θ(n) Platz erreicht werden.
49
Alternative: Universelles Hashing
Idee: Wählen h beim Aufbau der Struktur (unter Gleichverteilung) aus einer Menge von “guten” Hashfunk-
tionen H.
Analyse:
&
E [|Cx (h)|] = E δxy (h)
y∈S
&
= [δxy (h)]
y∈S
&
= (P r (h(x) = h(y)))
y∈S
! #
|{h ∈ H|h(x) = h(y)}| 1
mit P r(h(x) = h(y)) = =
" $
|H| N
& 1 n
E [|Cx (h)|] ≤ =
N N
y∈S
Def.:
U
Eine Menge H ⊂ {0, . . . , N − 1} von Hashfunktionen heißt universell, falls ∀x, y ∈ U mit x 5= y
|H|
|{h ∈ H|h(x) = h(y)}| ≤
N
Damit:
Die erwartete Zugriffszeit für Hashing mit Verkettung bei zufälliger Wahl von h aus einer universellen Familie
von H- Funktionen bei3der Verkettung einer (jeder!) (festen) n- elementigen Teilmenge S ⊂ U in einer Tabelle
n4
mit N Einträgen ist θ 1 bei θ(n + N + |h| ) Speicher.
N "#$%
Platzbedarf, um h zu codieren
50
3.7.5 Universelle Hashfunktionen
{0,...,u−1}
1. {0, . . . , N − 1} ist universell, aber nicht platsparend repräsentierbar bzw. effizient auswertbar.
2. Angenommen, x ∈ U kann in eindeutiger Weise als (r + 1)- Tupel x = (x1 , . . . , xr ) mit 0 ≤ xi < t ∀i
und eine Primzahl t. (z.B. t=257 und x wird byteweise gelesen).
a
$ %" #
r+1
Für (a0 , . . . , ar ) ∈ {0, . . . t − 1} definieren wir die Hashfunktion
9 :
r+1
Dann ist H = ha |a ∈ {0, . . . , N − 1} universell.
Bemerkung:
(a) Zum Abspeichern von h(a0 ,...,ar ) wird θ(r) Platz benötigt.
(b) Zum Berechnen von h(a0 ,...,ar ) (x0 , . . . xr ) wird θ(r) Zeit benötigt.
51
11. Dezember 2008
Fortsetzung “Universelle Hashfunktion”:
U = {0, . . . , u − 1} u = N r+1
N Primzahl (Größe der Hashtabelle)
x ∈ U ⇔ (x0 , . . . , xr ) mit 0 ≤ xi ≤ N
r+1
Zu (a0 , . . . , ar+1 ) ∈ {0. . . . , N − 1} definieren wir
'
U → {0. . . . , N − 1}
h2 = !r
x = (x0 , . . . , xr ) 0→ i=0 ai xi mod N
9 :
r+1
Dann ist H = h0 |a ∈ {a0 , . . . N − 1} universell.
Bemerkung:
r
& r
&
ai xi = ai yi (mod N)
i=0 i=0
a0 (x0 − y0 ) = a0 x0 − a0 y0
&r
= ai (yi − xi ) (mod N)
i=0
Bei gegebenen x und y gibt jede Wahl von a1 , . . . ar auf der rechten Seite eine feste Zahl C. Da N prim ist
und x0 5= y0 gibt es genau eine Möglichkeit, a0 zu wählen, um die Gleichnug zu erfüllen.
−1
a0 = C · (x0 − y0 ) (mod N)
% '
Es gibt genau N r Möglichkeiten a1 , . . . ar zu wählen.
|H|
& (
Damit |{ha |ha (x) = h(y)}| = N =
r
N
52
3.8 ADT Geordnetes Wörterbuch
Ziel: Verwaltung einer Teilmenge S von Elementen aus einem total geordneten Universum U ( wir werden
die Ordnung mit ≤ bezeichnen) unter dem Operation
find(x) bestimme, ob x ∈ S
insert(x) setze S ← S ∪ {x}
delete(x) setze S ← S\{x}
min bestimme min S
max bestimme max S
succ(x) bestimme das kleinste Element S, mit der Eigenschaft: min {y ∈ S|y ≥ x}
pred(x) bestimme das größte Element S, mit der Eigenschaft: max {y ∈ S|y ≤ x}
Bemerkung:
Wir nehmen an, dass die Ordunungsrelation in O(1) Zeit entschieden werden kann.
1. Suchbäume (später)
2. Geordnete nach ≤ verkettete Liste
3. Skip- Listen
Ist ähnlich zu verketten Listen. Die Daten werden in Containern abgelegt. Jeder Container enthält einen
Schlüssel und einen Zeiger auf den nächsten Container. Es können jedoch auch Zeiger auf andere Container
enthalten sein, welche nicht direkt nachfolgen. Demnach können auch Schlüssel übersprungen werden. Die
Zeiger werden von 0 bis h durchnummeriert, wobei h die Höhe ist; h ist um 1 kleiner als die Anzahl der
Zeiger, die ein Container enthält.
53
3.8.2.1 Suche in einer Skip- Liste (find, succ, pred) Suche nach q ∈ U
3.8.2.3 Löschen von z ∈ S Lösche z aus allen Li mit z ∈ Si (inklusive der vertikalen Zeiger)
– j = #Münzwürfe -1
– unterteile ∆i bei z
– verkette die Vorkommen von z in aufeinanderfolgenden Stufen vertikal
54
16. Dezember 2008
Die Größe der DS ( sowie die Zugriffszeiten) hängen von den zufälligen Entscheidungen ab, die der Algorith-
mus trifft.
Wie lange dauert es, nach einem Element zu suchen? Da gibt es mehrere Größen.
“vertikale” Höhe, i.e. r, die Anzahl der Stufen
1
Für c > 2 ist Pr(r > c · log2 n) ≤ c−1
n
Sei x ∈ S und k ∈ N
1
P r(x ist in mehr als k Stufen) =
2k ;
P r(es gibt mehr k Stufen) = P r( x ist in mehr als k Stufen)
x∈S
&
≤ P r(x ist in mehr als k Stufen)
x∈S
|S|
=
2k
n
=
2k
mit k = c · log2 n
n
≤
2c·log2 n
n
=
nc
1
= c−1
n
Die erwartete Zeit zum Löschen eines, über einem Zeiger definierten Elements, ist θ(1) (falls alle Listen
doppelt verkettet sind).
Man kann zeigen, dass die erwartete Suchzeit θ(logn ) ist.
55
3.8.3 Balancierte Mehrweg- Bäume
In einem Mehrweg Suchbaum, der eine Menge S über einem Universum U (mit totaler Ordnung ≤ ) speichert,
ist jeder innere Knoten v mit d ≥ 2 Kindern mit d − 1 Schlüsseln.
k1 (v) < . . . < kd−1 (v) aus U markiert. Das i-te Kind speichert nur Elemente, die
• ≤ ki (v)
sind.
Die Elemente aus S werden in den Blättern gespeichert.
56
18. Dezember 2008
. /
1
log2 n = log4 n ≤ h ≤ log2 n
2
Beispiel 2- Baum:
h=3 8 + 4 + 2 + 1 = 15 ⇒ 2h+1 − 1 Knoten
57
Access (x,T)
Input: x ∈ U , Suchbaum T für S ⊂ U
Output: Blatt y ∈ S mit y = min { z ∈ S| z ≥ x}
begin
v ← Wurzel von T
while v ist kein Blatt
do
Bestimme 1 ≤ i ≤ deg(v) mit Ki−1 (v) < x ≤ Ki (v)
Die Prozedur Access terminiert in einem (2,4)- Baum der Höhe h in O(h) Schritten.
Bemerkung:
In einem Mehrwegsuchbaum T der Höhe h terminineiert die Prozedur in O(h · max · deg v) Schritten.
v∈T
Mittels Access kann in einem (2,4)- Baum, der n Elemente speichert, find/succ in O(logn ) realisiert werden.
58
Einfügen:
Die 11 wird eingefügt, nun ist der Baum jedoch nicht mehr balanciert und erfüllt das Kriterium nicht mehr:
Passe den Key oben an. 11 nach oben, es ist größer als alles aus dem linken Teilbaum. Somit ist der Baum
wieder balanciert.
Nun wird ein Knoten, bzw. ein Blatt entfernt. Doch was nun? Zwei Kinder sind Pflicht!
59
Einfügen in (2,4)- Baum
Mit dieser Prozedur kann in einem (2,4)- Baum mit n Elementen in O(log n) Zeit ein neues Element eingefügt
werden.
Löschen eines Knotens v aus (2,4)- Baum
Sei p Mutterknoten von v
(a) Falls ein Nachbarknoten von p mindestens drei Kinder hat, stehle ein Kind.
(b) Falls alle Nachbarn von p genau zwei Kinder haben, verschmelzen wir p mit einem dieser Nachbarn
q zu einem Knoten mit drei Kindern und setzen das Löschen rekursiv bis zur Wurzel fort.
An der Wurzel einfach: Entferne alte Wurzel und mache ihr einziges Kind zur neuen Wurzel.
60
06. Januar 2008
• Mehreg- Suchbäume
• alle Blätter haben die gleiche Tiefe
• der Grad jedes inneren Knotens ist ≥ a und ≤ b
n
Es gilt: logb n ≤ Tiefe eines (a,b)- Baumes ≤ 1 + loga
2
Anwendungen:
• Datenstruktur im Externspeicher
(1972, Bayer & McGreight, B- Bäume, b=2a-1 )
b ≈ Blockgröße des Externspeichers
• “klassisch”: (2,3)- Bäume, aber bei (2,4)- Bäumen sind die amortisierten Kosten für das Löschen eines
Blattes O(1)
(tatsächlich: amortisierte Rebalancierungskosten sind O(1))
• (2,4)- Bäume “=” Rot- Schwarz- Bäume
Rebalancierungskosten:
Es gilt, wenn wir in einem Anfangs leeren (2,5)- Baum eine Folge von n Einfügungen/Löschoperationen
durchführen, dann sind die gesamten Rebalancierungskosten ≤ 2n
(d.h. die amortisierten R.- Kosten sind ≤ 2)
Wir zeigen das mittels der Buchhaltermethode:
61
Einfügen:
1. falls keine Rebalancierung, speichere (ggf.) 1€ bei dem betroffenen Knoten. Fertig.
62
08. Januar 2009
T = T [1 . . . n] ∈ Σ∗
M = M [1 . . . m] ∈ Σ∗
Finde:
alle Positionen 1 ≤ i ≤ n in denen M in T vorkommt, d.h.
M [1] = T [i]
M [2] = T [i + 1]
.. .. .. (∗)
. . .
M [m] = T [i + m − 1]
Sei T = mississippi und M = is
M kommt in T an Position 2&5 vor.
Naiv:
Teste, ob die Eigenschaft (∗) für i = 1, 2, . . . , n − m + 1 gilt.
Laufzeit: mθ(m · (n − m))
Beobachtung:
M kommt an Position i in T vor, genau dann, wenn M Präfix von T [i, . . . , n] ist.
" #$ %
i-te Suffix von T
Mit anderen Worten: Um alle Vorkommen von M in T zu bestimmen, müssen alle Suffixe von T gefunden
werden, die mit M anfangen.
Speichere alle Suffixe von T in einen komprimierten Trie: O(n) Platzbedarf.
63
Bsp.:
T = mississippi$
S(T ) = {mississippi$, ississippi$, ssissippi$, . . . , ppi$, pi$, i$, $}
|S(T )| = 12
&
|ω| = 78
ω∈S(T )
n · (n + 1) , -
im Allgemeinen gilt: = θ n2
2
Unkomprimierter Trie:
Komprimierter Trie:
64
Dies ist ein Baum mit n Blättern, alle inneren Knoten haben einen Grad > 1. D.h. es gibt insgesamt θ(n)
Knoten/Kanten.
Ein Komprimierter Trie kann in O(n) Zeit aufgebaut werden.
3.11.1 Suffixbaum
Suche nach M in T=
ˆ Suche nach den Einträgen im Suffixbaum, die M als Präfix haben.
Die Laufzeit ist O(m + # Positionen, an denen M in T auftaucht) .
65
13. Januar 2009
alternative: Suffixarray
T = abcab$ = T1
bcab$ = T2
cab$ = T3
ab$ = T4
b$ = T5
66
3.13 Sequence- Alignment Problem
o c u r a n c e o c _ u r a n c e
.. .. .. .. .. .. .. .. .. .. ..
. . . . . . . . . . .
o c c u r a n c e o c c u r a n c e
X = x1 . . . xm
und Y = y1 . . . yn
Eine Folge M von Paaren von Indizes aus {1, . . . , m} × {1 . . . n} bei der kein Index zweimal vorkommt heißt
ein Matching.
Bsp.:
x1 x2 x3 ... xm
.. .. ..
. . .
y1 y2 y3 ... yn
Parameter
1. δ > 0 (Lückenkosten)
Für jede Position von X oder Y die nicht zugeordnet ist, zahlen wir δ
!
2. für p, q ∈∈ gibt es Fehlerkosten αp,q > 0
Falls (i, j) ∈ M zahlen wir αxi ,yj
? k @
&
cost(M) = αxil ,yjl + (m + n − 2k) · δ
l=1
" #$ %
Fehlerkosten
! #
" $
Die Fehlerwerte werden durch die Anwendung vorgegeben (z.B. δ = 1)
Alignment Problem
x1 x2 ... xm−1 xm
1.
y1 y2 ... yn−1 yn
67
OPT(i,j): Kosten des besten Alignments von Xi = x1 . . . xi und Yj = y1 . . . yj
(Wir wollen OPT(m,n))
αxi.yj + OPT(i − 1, j − 1)
mit (1)&(2): OPT(i, j) = δ + OPT(i − 1, j)
δ + OPT(i, j − 1)
68
15. Januar 2009
3.13.2 Alignment von Zeichenketten
X = x1 ... ... xm
& ..
∗9 : . + αxm yn
↓
Y = y1 y2 ... yn
αxi.yj + OPT(i − 1, j − 1)
i, j ≥ 1
OPT(i, j) = δ + OPT(i − 1, j)
" #$ %
(∗)
Kosten des besten (billigsten) Alignments von x1 ...xi und y1 ...yi
δ + OPT(i, j − 1)
OPT(0, j) = j · δ (1 ≤ j ≤ n)
OPT(i, 0) = i · δ (1 ≤ i ≤ m)
wir suchen: OPT(m, n)
j-1 x x
j x ←;↑
69
Zeilenweises Ausfüllen der Tabelle
Algorithmus A l i g n (X,Y)
Eingabe X = x1 . . . xm, Y = y1 . . . yn
Ausgabe Kosten d e s g ü n s t i g s t e n Alignment von X und Y
f o r i = 0 t o m do OPT( i , 0 ) = i ∗ d e l t a
f o r j = 0 t o n do OPT( 0 , j ) = i ∗ d e l t a
f o r j = 1 t o n do
f o r i = 1 t o m do
OPT( i , j ) = min {OPT( i −1, j −1)+alpha_ { x i y j } , OPT( i −1, j )+ d e l t a , OPT( i , j −1)+ d e l t a }
r e t u r n OPT(m, n )
Definiere gerichteten, gewichteten Graphen GXY auf Knotenmenge, Kanten vertikal, horizontal: δ, diagonal:
αxi ,yj bei manchen zum Verdeutlichen, einen Weg verdeutlichen
70
——-
GXY = {(i, j) |0 ≤ i ≤ m, 0 ≤ j ≤ n}
mit Kanten
δ
(i, j) → (i, j + 1) ∀ 0 ≤ i ≤ m, 0 ≤ j ≤ n
δ
(i, j) → (i + 1, j) ∀ 0 ≤ i ≤ m, 0 ≤ j ≤ n
αxi ,yj
(i, j) → (i, j) ∀ 1 ≤ i ≤ m, 1 ≤ j ≤ n
f (i, j) seien die Kosten eines kürzesten Weges in GXY von (0,0) nach (i,j).
Dann gilt für alle i,j (i, j) = OPT(i, j)
71
20. Januar 2009
Ein gerichteter Graph G = (V, E) besteht aus einer Menge V von Knoten und einer Menge E ⊂ V × V von
Kanten zwischen den Knoten.
u∈V v∈V
72
Die Kosten π sind:
m−1
&
ω(π) = ω(vi , vi+1 )
i=1
Falls es zu allen u, v ∈ V einen Weg von u nach v gibt, so heißt G stark zusammenhängend (bzw. zusammen-
hängend, falls G ungerichtet ist)
LU = {v1 , v2 , v3 }
LW = {U, U # }
Platzbedarf: O(|E| + |V |)
2. Adjazenzmatrixdarstellung
|V | ×| V | -Matrix A = (aij )1≤i,j≤n
V = {1,' . . . , n} n = |V |
1 (i, j) ∈ E
aij =
0 (i, j) ∈ /E
73
Dieser Graph wird durch die folgende
Tabelle beschrieben:
1 2 3 4
1 0 1 1 0
2 0 0 1 0
3 0 0 0 1
4 0 0 0 0
2
Platzbedarf: O(|V | ).
74
4.3 Der ADT Graph
benötigte Operationen:
(E für Edges, V für Vertices)
(1) Knoten(): liefert Liste der Knoten des Graphen
(2) Kanten(): liefert Liste der Kanten des Graphen
(3) adjazenzListe(u): liefert die Liste aller zu u adjazenten Knoten
(4) loescheKante(u,v): entferne die Kante (u,v) aus E
(5) erzeugeKante(u,v): füge die Kante (u,v) zu E hinzu
(6) loescheKnoten(u): entferne den Knoten u aus V
(7) erzeugeKnoten(u): füge den Knoten u zu V hinzu
(8) gewicht(u,v): liefere ω(u,v)
(9) setzeGewicht(u,v,ω # ) setze ω(u, v) := ω #
(10) istKante(u,v): liefere 1, falls (u, v) ∈ E , 0 sonst
(11) knotenInfo(u): liefere die zu u assoziierte Information (als Object)
(12) kantenInfo(u,v): liefere die zu (u,v) assoziierte Information (als Object)
(13) setzeKnotenInfo(u,o): setze die zu u assoziierte Information zu o
(14) setzeKantenInfo(u,v,o): setze die zu (u,v) assoziierte Information zu o
Laufzeiten:
Operation A-Liste A-Matrix
(1) O(|V |) O(|V |)
2
(2) O(|E|) O(|V | )
(3) O(1)
(4)
(5)
(6)
(7)
(8)
(9)
(10)
(11)
(12)
(13)
(14)
75
22. Januar 2009
4.4 Graphenalgorithmen
Gegeben:
G = (V, E) gerichteter Graph mit V = {1, . . . , n}
Gewichtsfunktion ω : E → R+
Gesucht:
Abstandsfunktion δ : V × V → R+ mit δ(i, j) = Länge des kürzesten Weges von i nach j
76
Für i, j, k ∈ {1, . . . , n} sei
di,j = Länge des kürzesten Weges von i nach j, deren Zwischenknoten alle aus der Menge {1, . . . , k}
sind.
(0)
Für k = 0: dij = ω(i, j)
Für k > 0:
Sei ein Weg von i nach j, ≤ k, der Weg sei π .
Nun gibt es zwei Möglichkeiten:
1. k liegt auf π :
Es gibt zwei Teilwege: Der Weg von i nach k, für diesen gilt: ≤ k − 1 , von k nach j gilt : ≤ k − 1
(k−1) (k−1)
Länge = dik + dkj
2. k liegt nicht auf π :
Es gibt keinen Teilweg, bzw. der einzige “Teilweg” ist weiterhin der Weg von i nach j, für diesen gilt:
≤k−1
(k−1)
Länge von π = dij
also:
3 4
(k) (k−1) (k−1) (k−1)
dij = min dik + dkj , dij
77
kleiner Einschub vom Autor:
Graph:
k: Matrix
di,j : Eintrag der Matrix
Sei D(0) :
i\j 1 2 3 4
1 0 1 4 ∞
2 1 0 1 4
3 4 1 0 1
4 ∞ 4 1 0
3 4
(1) (0) (0) (0)
dij = min dij , dik + dkj
(1)
Dij ist dann:
i\j 1 2 3 4
1 0 1 4 ∞
2 1 0 1 4
3 4 1 0 1
4 ∞ 4 1 0
3 4
(2) (1) (1) (1)
dij = min dij , dik + dkj
i\j 1 2 3 4
1 0 1 2 5
2 1 0 1 4
3 2 1 0 1
4 5 4 1 0
Mache weiter bis D(4)
78
Für k < 0 :
(k)
Bottom - Up : Berechnung der dij
for i = 1 to n
for j=1 to n
(0)
dij ← ω(i, j)
for k=1 to n
for i=1 to n
for j=1 to n3 4
(k) (k−1) (k−1) (k−1)
dij = min dik + dkj , dij
return d(n)
79
Analyse: Laufzeit
Da der Algorithmus drei ineinander verschachtelte for-Schleifen beinhaltet, ist die Laufzeit O(n3 ).
Der Platzbedarf ist ebenfalls O(n3 ), da ein 3-dimensionales Array verwendet wird, welches alle möglichen
Werte speichert.
, , 2- -
O n als Platzbedarf ist möglich
All-pairs-shortest-path problem
80
27. Januar 2009
4.4.1.3 All-pairs Shortest Path Problem .
Diesmal:
(m)
dij = Länge des kürzesten Weges von i nach j der höchstens m Kanten enthält.
V = {1, . . . , n} ω(i, j) ≥ 0
3 4
(k) (k−1) (k−1) (k−1)
dij = min dij , dik + dkj
All-pairs-shortest-path problem
'
+∞ i 5= j
dij =
0 i=j
für
. 3 4 / 3 4
(m) (m−1) (m−1) (m−1)
m>0: dij = min min dik + ω(k, j) , dij = min dik + ω(k, j)
1≤k≤n 1≤k≤n
(n−1)
Es gilt: δ(i.j) = dij
(n) (n+1) (n+2) (n+r) (n−1)
insbesondere dij = dij = dij = dij = dij ∀r ≥ 0
3 4
(m)
D(m) = dij n × n- Matrix für m = 0, 1, 2, . . .
1≤i,j≤n
W = (ω (i, j))1≤i,j≤n n × n- Matrix, wobei wir annehmen, dass ω(i, j) = ∞ falls (i, j) ∈
/E
3 4
(0)
D(0) = dij wie oben.
i,j
81
Berechnung von δ mittels Nächster:
Initialisere D(0)
for n=1 to n-1 , -
D(m) = Nächster D(m−1) , ω
return D(n−1)
Laufzeit: O(n4 )
C = A · B d.h.
&n
cij = aik · bkj
k=1
mit
· →⊕
+ → min
(n)
cij → dij
(n−1)
aik → dik
bkj → ω(k, j)
cij = min (aik + bkj ) (∗)
1≤k≤n
3 4
(n) (n−1)
dij = min dik , ω(k, j)
1≤k≤n
D(n) = D(n−1) = W
Der obige Algorithmus bezeichnet D(0) , D(1) = D(0) =W, D(2) = D(0) =W =W D(1) = W D(3) = W =W =W
Die Matrixmultiplikation ist assoziativ ⇒ W 3 . . .
D(n−1) = W (n−1)
Statt iterativ, können wir D(n−1) aus W auch durch schnelle Exponentiation berechnen:
Bsp.:
,
-2
W8 = W4
3, - 2 42
= W2
82
D(2) = W 2 = Nächster (W, W )
3 4
D(4) = W 4 = Nächster D(2) , D(2)
3 4
D(8) = W 8 = Nächster D(8) , D(8)
Fazit:
, -
log n + 1 Aufrufe der Prozedur Nächster. Gesamtlaufzeit: O n3 · log n
Die folgenden Algorithmen speichern für jeden Knoten i ∈ V einen Wert di , der als Abschätzung für δ(i)
dient. Dabei ist stets di = δ(i) und es gibt in G stets einen Weg von s nach i der Länge di . Am Ende wird
di = δ(i) für alle i ∈ V sein (das ist natürlich zu zeigen).
83
29. Januar 2009
Beweis zu (2):
Sei v der erste Knoten, bei dem der Aufruf RELAX(u,v) dazu führt, dass dv < δ(v) gilt.
dv = du + ω(u, v)
"#$%
≤δ(v)
Also muss auch du < δ(u) vor RELAX(u,v) gelten. Dies ist ein Widerspruch zur Annahme, dass v der erste
Knoten ist, bei dem (∗) passiert.
1. RELAX(s, 1) → d1 = δ(1)
2. RELAX(3, 7)
3. RELAX(2, 4)
4. RELAX(1, 2) → d2 = δ(2)
5. RELAX(2, 3) → d3 = δ(3)
6. RELAX(3, 4) → d4 = δ(4)
84
1. 4. 5. 6.
s→1 1→2 2→3 3→4
R(5, 7)
R(1, 2)
R(0, 4)
R(2, 3) |E| Relaxierungen
R(3, 4)
(|V | − 1) -mal
R(7, 2)
R(s, 5)
R(s, 1)
(5)
Für einen kürzesten Weg s → v1 → v2 → . . . → vk gilt:
Jede Folge von Relaxierungen, die die Teilfogen (RELAX (s, v1 ) , RELAX (v1 , v2 ) , . . . , RELAX (vk−1 , vk )) ent-
hält, führt dazu, dass dvi = δ(vi ) für 1 ≤ i ≤ k . (Folgt aus (4) mit Induktion)
85
03. Februar 2009
Java- Einschub
Typen in Java
• Java ist eine streng typisierte Sprache
Definition:
Ein Typ oder ein Datentyp ist im Tupel eine Objektmenge mit auf dieser Menge definierten Operationen.
Typumwandlung
Definition:
Typumwandlung ist das Überführen eines Typs A in einen Typ B
Identische Überführung
Beispiel:
86
int i = 1234567890;
float f = i;
System . out . p r i n t l n ( i − f ) ;
// w a n d e l t i i n f l o a t um, b e i d e g l e i c h w e i t e n t f e r n t ; e r g i b t 0
Begrenzende Typumwandlung
Von einer weiteren Typumwandlung einer Referenz A in eine Referenz B wird gesprochen, wenn
• A ist eine Klasse und B ein Interface, welches von A implementiert wird.
Beispiel:
I n t e g e r i = new I n t e g e r ( 4 2 ) ;
Number n = i ; // Number a l l g e m e i n e r a l s I n t e g e r
Von einer begrenzenden Typumwandlung einer Referenz A in eine Referenz B wird genau dann gesprochen,
wenn
87
• A und B sind Klassen und B ist eine Unterklasse von A.
• A und sind B Interfaces und B ist ein Unterface von A.
• B eine Klasse ist und A ein Interface, welches von B implementiert wird.
Beispiel:
Number n = new I n t e g e r ( 4 2 ) ;
Integer i = ( Integer ) n ;
88
10. Februar 2009
4.4.1.7 Der Algorithmus von Dijkstra (Zur Berechnung kürzester Wege)
for i ∈ V
d[i] = +∞
d[s] = 0
Initialisiere PWS Q mit V , geordnet nach d Werten
89
B := ∅
while Q 5= ∅
u := ExtractMin(Q)
B := B ∪ {u}
for all (u, v) ∈ E
RELAX(u, v)
return d[];
Korrektheit:
Wir zeigen: Wenn die Anweisung “B := B ∪ {u}” ausgeführt wird, dann ist d[u] = δ(u).
Beweis durch Widerspruch:
Leicht zu sehen: d[s] = δ(s) = 0, wenn s (als Erster) in B aufgenommen wird.
Sei u der erste Knoten, den der Alg. in B aufnimmt, wobei d[u] > δ(u) ist (klar s 5= u) (∗)
1. δ(x) = d[x]
(weil u der erste Knoten ist, dessen d- Wert ungleich δ wird, wenn er rot wird.)
2. δ(y) = d[y]
(wegen 1. und der Realisierung von x → y bei der Aufnahme von x in B)
Damit:
d[y] = δ(y)
≤ δ(u) y liegt vor u auf p, alle Kantengewichte ≥ 0
≤ d[u] gilt immer
Da u = ExtractMin(Q) und y ∈ Q
d[y] ≥ d[u]
90
Also d[y] = δ(y) ≤ δ(u) ≤ d[u] ≤ d[y]
damit d[y] = δ(y) = δ(u) = d[u] Widerspruch zur Annahme (∗)
91
12. Februar 2009
5.1 Berechnung
Gegeben: Ungerichteter , gewichteter Graph G = (V, E) (zusammenhängend)
ω : E → R>0
Gesucht: M ⊂ E mit der Eigenschaft, dass
Beobachtung: M kann keine Kreise haben (mit anderen Worten: (V, M ) ist ein Baum)
M: ω(M ) = 1 + 2 + 4 + 3 + 5 = 15
Die Algorithmen halten eine Menge A ⊆ E aufrecht, die die Eigenschaft hat, dass es einen MST (V, M ) gibt
mit A ⊂ M .
Falls e = {u, v} ∈ E die Eigenschaft hat, dass A ∪ {u, v} auch in einem MST von g enthalten ist, nennen wir
e sicher für A.
Setze A = ∅
Solange es eine Kante e gibt, die sicher für A ist,
füge e zu A hinzu
return A
Korrektheit: klar
92
5.3 Begriffe
B
1. Ein Schnitt G = (V, E) ist eie Zerlegung V = S (V \S)
2. e = {u, v} kreuzt Schnitt S, falls u ∈ S und v ∈ V \S
3. A ⊂ E respektiert Schnitt S gdw. kein e ∈ A S kreuzt
93
Index
A Graph, Gewicht, 72
ADT, Baum, 39 Graph, Grundbegriffe, 72
ADT, Definition, 25 Graph, k. Wege, Abstandsfunktion, 76
ADT, Knoten, 39 Graph, k. Wege, Algorithmus, Bellman- Ford, 85
Algorithmus, Amalyse, 6 Graph, k. Wege, Algorithmus, Dijkstra, 89
Algorithmus, Effizienz, 6 Graph, k. Wege, Eigenschaften, 76
Alignment, Alignment Problem, 67 Graph, k. Wege, Floyd Warshall, Berechnung, 78
Alignment, Kosten, 67 Graph, k. Wege, Floyd Warshall, Formel, 77
Alignment, Sequence Alignment Problem, 67 Graph, k. Wege, Floyd Warshall, Laufzeit, 80
Alignment, Zeichenketten, 69 Graph, k. Wege, Relaxation, 83
Graph, k. Wege, Relaxation, Eigenschaften, 83
B Graph, k. Wege, Startknoten, 83
Baum, (2,4), 57, 61 Graph, Kosten, 72
Baum, (2,4), Einfügen, 60 Graph, Kosten, einfach, 73
Baum, (2,4), Löschen, 60 Graph, Kreis, 73
Baum, (a,b), 61 Graph, kürzeste Wege, 76
Baum, Anwendung, Spielbaum, 43 Graph, Operationen, 75
Baum, Ausdrucks-, 42 Graph, stark zusammenhängend, 73
Baum, Binomial -, 36 Graph, ungerichtet, 72
Baum, Breitensuche, 43 Graph, Weg, 72
Baum, Einfügen, 59
Baum, heapgeordnet, Eigenschaften, 30 H
Baum, heapgeordnet, Implementierung, 31 Hashfunktion, faire, 49
Baum, Höhe, 57 Hashfunktion, universell, 51
Baum, Implementierung, 40 Hashing, Codes, 45
Baum, k-när, 40 Hashing, Implementierung, 45
Baum, minimal aufspannend, 92 Hashing, Laufzeit, 46
Baum, minimal aufspannend, Berechnung, 92 Hashing, universell, 50
Baum, minimal aufspannend, kreuzen, 93 Hashing, Verkettung, 45
Baum, minimal aufspannend, respektieren, 93 Heap, 31
Baum, minimal aufspannend, Schnitt, 93 Heap, binär, 31
Baum, Rekursions-, 13 Heap, binär, Implementierungen, 32
Baum, Suffix-, 65 Heap, Binomial-, 36
Baum, Tiefensuche, 43 Heap, Operationen, Implementierung, 38
Baum, Traversierung, 41
Baum, Traversierung, inorder, 41 I
Baum, Traversierung, inorder, Anwendung, 41 Interface, ADT Baum, 39
Baum, Traversierung, postorder, 41 Interface, Deklaration, 26
Baum, Traversierung, preorder, 41 Interface, Implementierung, 26
Interface, Pflichten, 26
D Interface, Rechte, 26
Datenabstraktion, Vorteile, 25
J
G Java, Polymorphie, 35
Geheimnisprinzip, 24 Java, Typen, 86
Graph, Adjazenzliste, 73 Java, Typen, Definitition, 86
Graph, Adjazenzmatrixdarstellung, 73 Java, Typumwandlung, 86
Graph, Endpunkt, 72 Java, Typumwandlung, begrenzt, 87
Graph, gerichtet, 72 Java, Typumwandlung, weitend, 86
Graph, gerichtet, Illustration, 72
94
K
Kante, sicher, 92
Kosten, Alignment, 67
Kosten, amortisierte, 22
Kosten, Graph, 72
Kosten, Rebalancierung, 61
L
Laufzeit, asymptotisch, 9
Lokalisieren, 38
N
Notation, UP-, 42
O
O- Notation, 10
P
Patternmatching, String, 63
PWS, ADT, 27
PWS, Folge unsortierter Listen, 28
PWS, Heap, 28
PWS, Motivation, 27
PWS, PQSort, 27
PWS, verkettete Liste, 28
PWS, VPWS, Operationen, 37
R
Registermaschine, 7
Rekursion, 11
S
Skip Liste, 53
Skip Liste, Suchen, 54
Sortieren - Heapsort, Laufzeit, 33
Sortieren - Mergesort, 14
Stack, 17
Stack, Implementierung, 18
Stack, Operationen, 17
Suffixarray, 66
T
Trie, 63
Trie, komprimiert, 64
Trie, Suffixarray, 66
Trie, Suffixbaum, 66
Trie, unkomprimiert, 64
W
Wörterbuch, geordnet, 53
Wörterbuch, geordnet, Implementierung, 53
Wörterbuch, Implementierung, 44
Wörterbuch, Implementierung, Hashing, 45
Wörterbuch, Operationen, 44
95