Algorithmen und Datenstrukturen

Werbung
Was bisher geschah
I
Algorithmen
I
Spezifikation
I
asymptotische Laufzeit
I
rekursive Algorithmen
I
Divide-and-Conquer-Algorithmen
I
Dynamische Programmierung
93
Entwurfsebenen
Mathematik:
Algorithmik:
Programmierung:
Funktion
↓
Algorithmus
↓
(Unter-)Programm
Methode
Abstrakter Datentyp
↓
Algebra
(Konkreter Datentyp)
↓
Datenstruktur
↓
Datentyp
Klasse
94
Motivation ADT
Aufgabe: Verwaltung einer Menge ganzer Zahlen, so das festgestellt
werden kann, ob eine Zahl darin enthalten ist und Zahlen hinzugefügt
und entfernt werden können.
Spezifikation des Datentyps NSet muss enthalten:
I
I
N
N
Wertebereiche (Sorten): , Mengen ⊆ , Wahrheitswerte (Bool)
Operationen: finden, hinzufügen, entfernen
Operationen mit Typdeklaration (Signatur)
N
N
contains :
Menge × →
add, remove : Menge × →
isempty :
Menge →
emptyset :
I
Bool
Menge
Bool
Menge
Bedeutung der Operationen
t falls x ∈ M
contains(M, x) =
f sonst
add(M, x)
=
M ∪ {x}
remove(M, x) = M \ {x}
= ∅
t falls M = ∅
isempty(M) =
f sonst
emptyset
95
Spezifikation durch abstrakte Datentypen (ADT)
Abstrakter Datentyp NSet:
Sorten:
N, Mengen ⊆ N, Wahrheitswerte (Bool)
Signatur: Operationen mit Typdeklaration
N
N
contains :
Menge × →
add, remove : Menge × →
isempty :
Menge →
emptyset :
Bool
Menge
Bool
Menge
Axiome: formale Beschreibung der Bedeutung der Operationen
(Zusammenhänge dazwischen)
N
∀s ∈ Menge∀n ∈ N
∀s ∈ Menge∀n ∈ N
∀s ∈ Menge∀m, n ∈ N
∀s ∈ Menge∀n ∈ N
∀n ∈
isempty((emptyset) = t
: contains(emptyset, n) = f
: contains(add(s, n), n) = t
:
contains(remove(s, n), n) = f
: add(add(s, n), m) = add(add(s, m), n)
: add(add(s, n), n) = add(s, n)
...
96
Abstrakte und konkrete Datentypen
Abstrakter Datentyp (ADT): (formale Spezifikation)
I Menge von Sorten
I mehrsortige Signatur ΣF
I Menge von Axiomen Φ
ADT = (funktionale) Signatur ΣF + Axiome Φ
Konkreter Datentyp: ΣF -Algebra A mit A ∈ Mod(Φ)
(Struktur mit geeigneten Funktionen, so dass alle
Axiome erfüllt sind)
97
Beispiel: Boolesche Algebra
Abstrakter Datentyp Boolesche Algebra:
Sorten: Bool (zwei Wahrheitswerte)
Signatur:
t:
f:
¬:
Bool →
∨ : Bool × Bool →
∧ : Bool × Bool →
Bool
Bool
Bool
Bool
Bool
Axiome:

∀a∀b : a ∧ b = b ∧ a, ∀a∀b : a ∨ b = b ∨ a,



∀a∀b∀c : a ∨ (b ∧ c) = (a ∨ b) ∧ (a ∨ c),
Φ=
∀a∀b∀c : a ∧ (b ∨ c) = (a ∧ b) ∨ (a ∧ c),



¬(t = f), ∀a∀b : ¬(¬a ∨ b) ∨ ¬(¬a ∨ ¬b) = a







passende konkrete Datentypen, z.B.
I ({0, 1}, max, min, x 7→ 1 − x, 0, 1)
I (2{d} , ∪, ∩, , ∅, {d})
98
Einfache und zusammengesetzte Datentypen
Datentyp:
Menge von Werten mit Operationen auf diesen Werten
I
einfache Datentypen, z.B. int, bool, float, ...
I
zusammengesetzte Datentypen
Konstruktion durch die Operationen
I
I
I
I
kartesisches Produkt von Datentypen:
mehrfaches Produkt desselben Typs, z.B. Tupel
Produkt verschiedener Typen, z.B. Klassen, record
Vereinigung von Datentypen
(in Java: Interface mit mehreren Implementierungen)
rekursive Datentypen, z.B. Liste, Term
Abbildung zwischen Datentypen (Funktionen)
99
Prominente zusammengesetzte Datentypen
Mengen typische Operationen:
I Test auf Leerheit
I Einfügen, Entfernen von Elementen
I Suche nach Element
I Vereinigung, Durchschnitt, Differenz
Folgen (z.B. Listen, Texte), typische Operationen:
I Einfügen, Entfernen von Elementen
I Suche nach Element
I spezielle Elemente suchen (Min, Max, Median)
I Sortieren
I Verketten, Spiegeln
Abbildungen (z.B. Wörterbücher), typische Operationen:
I Einfügen, Entfernen von Argument-Wert-Paaren
I Suche nach dem Wert zu einem Argument
Graphen typische Operationen:
I Einfügen, Entfernen von Knoten und Kanten
I Suche nach Knoten
I Suche nach Pfaden (z.B. kürzeste)
I Suche nach Teilgraphen (z.B. Gerüst)
100
Wiederholung: mehrsortige Strukturen
Modellierung von Strukturen mit
S = {Si | i ∈ I} von Elementen
I
verschiedenen Sorten (Mengen)
I
Operationen
I
Eigenschaften und Zusammenhänge zwischen Operationen
Beispiele:
I
Mengen (Elemente, Mengen von Elementen, polymorph)
Operationen: add, contains, empty
Zusammenhänge: ∀e∀l : empty(add(e, l)) = false
I
Folgen (Elemente, Folgen von Elementen, polymorph)
Operationen: add, remove, append, add, reverse
Zusammenhänge: ∀l : reverse(reverse(l)) = l
I
Vektorraum (Skalare, Vektoren)
Operationen: smult,sprod,+,0,0v
Zusammenhänge: ∀v : smult(0,v) = 0
101
Mehrsortige Strukturen
hier nur funktionale Strukturen (Algebren)
I
Sorten
I
Signatur Σ = (ΣF , ∅) (keine Relationssymbole)
ΣF -Algebra A = ({AS | S ∈ S}, J·KA ) mit
I
I
für jede Sorte S ∈ S eine nichtleere Menge AS
(Träger, Universum der Sorte)
für jedes Funktionssymbol f : Si1 . . . Sin → Si
eine Funktion Jf KA : Ai1 × · · · × Ain → Ai
Modell für Menge Φ von Sätzen:
ΣF -Algebra A, welche alle Sätze aus Φ erfüllt
102
Beispiel ADT Folge
Ziel: Datentyp zur Verwaltung einer endlichen Folge von Elementen
einen Typs a (Zuordnung f : {1, . . . , n} → a) mit Operationen zum
Bestimmen der Länge der Folge, Hinzufügen und Lesen eines
Elementes an einer bestimmten Position.
Sorten: Element, Folge von Elementen (polymorph), Bool, Nat
Signatur:
nil :
Folge
isempty :
Folge → Bool
add :
Folge × Element → Folge
get :
Folge × Nat → Element
size :
Folge → Nat
weitere sinnvolle Operationen für Folgen:
head :
Folge →
tail :
Folge →
reverse :
Folge →
remove : Folge × Element →
append :
Folge × Folge →
Element
Folge
Folge
Folge
Folge
Axiome: ? (Tafel)
103
(Ein möglicher) konkreter Datentyp für Folgen
N
N
Sorten: Bool: {0, 1}, Nat: , Element: {a, b, c},
Folge:
{(x1 , . . . , xn ) | n ∈ ∧ ∀i ∈ {1, . . . , n} : xi ∈ {a, b, c}}
Realisierung der Operationen:
nil =
()
t falls x = ()
f sonst
isempty(x)
=
add((x1 , . . . , xn ), y )
=
(y , x1 , . . . , xn )
get((x1 , . . . , xn ), i)
=
xi
size(x1 , . . . , xn )
=
n
Nachweis der Gültigkeit der Axiome: (Tafel)
104
Realisierung zusammengesetzter Typen
(Verwaltung mehrerer Daten derselben Art)
I
lineare Datenstrukturen,
z.B. Folge, Liste, Queue, Stack
I
hierarchische Strukturen, z.B. Bäume
I
Relationen, z.B. Graphen
105
Realisierungen des ADT Menge
einige Möglichkeiten:
I ungeordnete Folge (Aufzählung aller Elemente)
I
I
I
I
I
geordnete Folge (sortierte Aufzählung aller Elemente)
I
I
I
I
I
add O(1)
remove O(n)
contains O(n)
isempty O(1)
add O(n)
remove O(n)
contains O(log n)
isempty O(1)
Bitvektor (charakteristische Funktion)
I
I
I
I
add O(1)
remove O(1)
contains O(1)
isempty O(n)
106
ADT Folge mit Positionszugriff
ADT PFolge (Spezifikation):
Sorten: Element, Folge von Elementen (polymorph), Bool,
Nat, Pos
Signatur:
nil :
isempty :
Folge →
get :
Folge × Pos →
set :
Folge × Element × Pos →
remove :
Folge × Pos →
size :
Folge →
Folge
Bool
Element
Folge
Folge
Nat
Axiome z.B. isempty(nil) = t,
∀l ∈ Folge∀y ∈ Element∀i ∈ Pos :
get(set(l, y , i), i) = y
107
Modell für Folgen mit Positionszugriff
Trägermengen: Element E, Folgen: E ∗
nil = ε
t falls n = 0
isempty(x1 · · · xn ) =
f sonst
xi
falls i ≤ n
get(x1 · · · xn , i) =
undef sonst
set(x1 · · · xn , y , i)
=
remove(x1 · · · xn , i)
=
size(x1 · · · xn )
=
x1 · · · xi−1 , y , xi+1 , . . . , xn
x1 · · · xi−1 ◦ xi+1 · · · xn
undef
falls i ≤ n
sonst
n
Implementierung z.B. als Array (hinreichender Größe)
108
ADT Folge ohne Positionszugriff
ADT Folge (Spezifikation, Auszug):
Sorten: Bool, Element, Folge, Nat
Signatur:
nil :
isempty :
Folge →
head :
Folge →
tail :
Folge →
add, remove : Folge × Element →
append :
Folge × Folge →
reverse :
Folge →
size :
Folge →
Folge
Bool
Element
Folge
Folge
Folge
Folge
Nat
Axiome z.B
isempty(nil) = t
∀x ∈ Folge∀e ∈ Element : isempty(add(e, x)) = f
∀x ∈ Folge∀e ∈ Element : head(add(e, x)) = e
∀x ∈ Folge∀e ∈ Element : tail(add(e, x)) = x
109
Modell für Folgen ohne Positionszugriff
Trägermengen: Element E, Folgen: E ∗
nil = ε
isempty(x1 · · · xn ) =
head(x1 · · · xn ) =
tail(x1 · · · xn ) =
t falls n = 0
f sonst
x1
falls n > 0
undef sonst
x2 · · · xn falls n > 0
undef
sonst
add(e, x1 · · · xn ) = ex1 · · · xn
append(x1 · · · xn , y1 · · · ym ) = x1 · · · xn ◦ y1 · · · ym
reverse(x1 · · · xn ) = xn · · · x1
size(x1 · · · xn ) = n
110
Rekursive Datentypen
Wiederholung:
Funktion f heißt rekursiv gdw. in der Definition von f kommt f
selbst vor.
analog:
ADT heißt genau dann rekursiv, wenn er in seiner Definition
selbst vorkommt.
Jeder induktiv definierte Datentyp (z.B. Listen, Terme, Formeln)
ist rekursiv.
Operationen in rekursiven Datentypen lassen sich rekursiv
realisieren.
111
Einfach verkettete Liste
Knotentyp:
I
I
nil (Konstante) oder
Knoten aus
I
I
Element (head) und
(Verweis auf) Liste (tail)
in Haskell:
data List a = Nil {}
| Cons { head :: a, tail :: List a }
oft kürzer (Nil 7→ [], Cons 7→ :, ohne Komponentennamen):
data [a] = [] | a : [a]
Spezialfall: zyklisch verkettete Liste
112
Realisierung des ADT Folge (mit Positionszugriff)
durch verkettete Liste:
I
isempty O(1)
I
add O(1) (am Anfang anfügen)
I
contains O(n) (ein Vorkommen finden)
I
remove O(n) (alle Vorkommen finden)
I
get, set O(n) (Position finden)
durch Array (variabler Länge):
I
isempty O(1)
I
add O(1) (am Ende anfügen)
I
contains O(n) (ein Vorkommen finden)
I
remove O(n) (alle Vorkommen finden und Nachrücken)
I
get, set O(1) (Direktzugriff über Index)
113
Doppelt verkettete Liste
Knotentyp:
I
I
nil (Konstante) oder
Knoten aus
I
I
I
Element (head) und
(Verweis auf) Liste (next) und
(Verweis auf) Liste (prev) und
114
Spezielle lineare Datenstrukturen
add, remove und get nur an festgelegten Positionen
(remove’ ohne Element, get’ ohne Index)
ADT Lin (Spezifikation):
Sorten: Bool, Element, Folge
Signatur:
isempty :
Folge →
nil :
add :
Folge × Element →
remove0 :
Folge →
get0 :
Folge →
Bool
Folge
Folge
Folge
Element
Spezialfälle:
Stack: andere Namen für Operationen:
add 7→ push, remove’ 7→ pop, get’ 7→ top
Queue: andere Namen für Operationen:
add 7→ enqueue, remove’ 7→ dequeue, get’ 7→ front
115
Stack (Stapel, Keller, LIFO)
ADT Stack
Sorten: Bool, Element, Stack (polymorph)
Signatur:
isempty :
Stack →
nil :
push :
Stack × Element →
pop :
Stack →
top :
Stack →
Axiome:
Bool
Stack
Stack
Stack
Element

isempty(nil) = t,



∀s∀e : isempty(push(s, e)) = f,
∀s∀e : pop(push(s, e)) = s,



∀s∀e : top(push(s, e)) = e, . . .







Realisierungen meist durch
verkettete Liste oder Array
116
Queue (Warteschlange, FIFO)
ADT Queue
Sorten: Bool, Element, Queue (polymorph)
Signatur:
isempty :
Queue →
nil :
enqueue : Queue × Element →
dequeue :
Queue →
front :
Queue →
Bool
Queue
Queue
Queue
Element
Axiome:

isempty(nil) = t, ∀q∀e : isempty(enqueue(q, e)) = f,



∀a∀b : front(enqueue(enqueue(nil, a), b)) = a
∀a∀b : dequeue(enqueue(enqueue(nil, a), b))



= enqueue(nil, b), . . .







Realisierung meist durch
zyklisch verkettete Liste oder Array
117
Herunterladen