Skript mit Übungen (veraltet) - Hochschule Ravensburg

Transcription

Skript mit Übungen (veraltet) - Hochschule Ravensburg
Grundlagen der Informatik
Wolfgang Ertel
24. Juli 2008
Inhaltsverzeichnis
1 Was ist Informatik?
1.1 Informatik . . . . . . . . . . . . .
1.2 Computer . . . . . . . . . . . . .
1.3 Information . . . . . . . . . . . .
1.4 Teilgebiete der Informatik? . . . .
1.5 Programm, Algorithmus, Software
1.6 Betriebssysteme . . . . . . . . . .
1.7 Softwaretechnologie . . . . . . . .
1.8 Datensicherung . . . . . . . . . .
1.9 Datenschutz . . . . . . . . . . . .
1.10 Datenbanken . . . . . . . . . . .
1.11 Das Informatikstudium . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2 Geschichte der Informatik
2.1 Wichtige Quellen . . . . . . . . . . .
2.2 Zahlendarstellung . . . . . . . . . . .
2.3 Geschichte der Bauelemente . . . . .
2.4 Geschichte der Rechenmaschinen . .
2.5 Geschichte der Programmiersprachen
2.6 Geschichte des Internet . . . . . . . .
2.7 Große Informatiker . . . . . . . . . .
2.8 Frauen in der Informatik . . . . . . .
2.9 Wichtige Institute und Firmen . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3 Algorithmen und Datenstrukturen – Einführung
3.1 Sortieren durch Einfügen . . . . . . . . . . . . . .
3.2 Quicksort . . . . . . . . . . . . . . . . . . . . . .
3.3 Sortieren mit Bäumen (Heapsort) . . . . . . . . .
3.4 Sortieren in linearer Zeit . . . . . . . . . . . . . .
3.5 Hashing . . . . . . . . . . . . . . . . . . . . . . .
4 Algorithmen auf Graphen
4.1 Einführung . . . . . . . . . . . . . .
4.2 Eulerkreise . . . . . . . . . . . . . . .
4.3 Datenstrukturen für Graphen . . . .
4.4 Kürzeste Wege . . . . . . . . . . . .
4.5 Das Problem des Handlungsreisenden
4.6 Planare Graphen . . . . . . . . . . .
.
.
.
.
.
.
2
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
4
4
5
5
6
6
7
8
9
9
10
.
.
.
.
.
.
.
.
.
12
12
12
13
14
19
19
20
25
26
.
.
.
.
.
27
27
33
37
43
44
.
.
.
.
.
.
48
48
50
52
53
56
61
5 Formale Sprachen und Endliche Automaten
5.1 Grundlagen . . . . . . . . . . . . . . . . . .
5.2 Grammatiken . . . . . . . . . . . . . . . . .
5.3 Reguläre Ausdrücke . . . . . . . . . . . . . .
5.4 Endliche Automaten zur Worterkennung . .
5.5 Automaten mit Ausgabe . . . . . . . . . . .
5.6 Formale Beschreibung von Automaten . . .
6 Übungen
6.1 Geschichte der Informatik . . . . . . . . . .
6.2 Sortieren . . . . . . . . . . . . . . . . . . . .
6.3 Graphen . . . . . . . . . . . . . . . . . . . .
6.4 Formale Sprachen und Endliche Automaten
Literaturverzeichnis
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
63
63
65
67
68
69
70
.
.
.
.
73
73
73
76
77
80
3
Kapitel 1
Was ist Informatik?
1.1
Informatik
Definition 1.1 Informatik ist die Wissenschaft der automatischen Verarbeitung von Informationen mit Hilfe von Computern.
(Am.: Computer Science)
Verschiedene Aspekte der Informatik:
•
•
•
•
1.2
Spaß am Programmieren (Erfolgserlebnisse)
Spaß an der Beherrschung der Maschine
Teilweise sehr abstrakte Wissenschaft (Mathematik)
Ohnmachtgefühl von Laien
Computer
Definition 1.2 Programmierbare Rechenmaschinen werden als Computer bezeichnet.
früher wurden Menschen, die “rechnen” als Computer bezeichnet.
Computer
•
•
•
•
•
•
•
machen unser Leben bequemer
helfen beim Beschaffen von Informationen
vereinfachen die Kommunikation
können süchtig machen
können zum Pseudopartner werden
vernichten Arbeitsplätze
schaffen Arbeitsplätze
•
•
Wem nützt die Informatik?
Wem schadet die Informatik?
⇒
Soziale Verantwortung des Informatikers!
4
1.3
Information
Information: Wissen, Gegenteil von Unsicherheit.
Definition 1.3 Als elementare Maßeinheit für Information dient das Bit. Eine Nachricht
(z.B. ein Text od. eine Zahl) hat einen Informationsgehalt von n Bit, wenn die minimale
Zahl von Ja/Nein Fragen, zur exakten Ermittlung der Information genau n ist.
Ein Computer-Wort besteht aus 8, 16, 32, oder 64 Bit.
Beispiel 1.1
1
0
0
1
1
0
1
0
1 · 27 + 0 · 26 + 0 · 25 + 1 · 24 + 1 · 23 + 0 · 22 + 1 · 21 + 0 · 20 =
128 +
16 +
8+
2
=
154
1.4
Teilgebiete der Informatik?
Informatik
Theoretische Informatik
•
•
•
•
•
•
•
•
Logik (logisch!)
Berechenbarkeit (ist jedes Problem berechenbar?)
Komplexität (Rechenaufwand)
Formale Sprachen (Programmiersprachen)
Informationstheorie (Datenübertragung)
Kryptographie (Datensicherheit)
Formale Spezifikation und Verifikation (Korrektheitsbeweise von Programmen)
...
Technische Informatik
•
•
•
•
•
Hardware
Rechnernetze
Schaltungen
Schnittstellen
Peripheriegeräte
Praktische Informatik
Bereitstellen von Hilfsmitteln für die Arbeit mit Computern
•
•
Rechnerarchitektur
Betriebssysteme (DOS, Windows, Unix, . . . )
5
•
•
•
•
•
•
•
Datenbanken
Künstliche Intelligenz
Software-Entwicklung
Datenkommunikation
Prozeßsteuerung
Bildverarbeitung
...
Angewandte Informatik
•
•
•
•
•
•
1.5
Wirtschaftsinformatik
Medizinische Informatik
Medieninformatik (Multimedia)
Kommunikationstechnik
Automatisierungstechnik
Künstliche Intelligenz
Programm, Algorithmus, Software
Definition 1.4
Algorithmus: Allgemeines Schema zur Lösung einer Klasse von Problemen.
Programm: Folge von Befehlen in einer festen Programmiersprache
Softwareentwicklung:
•
•
•
•
•
Problemanalyse
Problemlösung (Algorithmierung)
Programmierung (Kodierung)
Test
Inbetriebnahme
Softwaretechnologie:
Systematische Untersuchung der Softwareentwicklung und Bereitstellung von Entwicklungswekrzeugen.
1.6
Betriebssysteme
1.6.1
•
•
Betriebssysteme: Aufgaben
Laden u. Starten von Programmen
Verwalten des Hauptspeichers
◦
◦
Schützen der Speicherbereiche von Programmen
Verwaltung des virtuellen Speichers (paging, swapping)
Paging: Auslagern von Programmteilen
Swapping: Auslagern ganzer Programme
6
•
Verwaltung von Dateien
◦
◦
•
Ein- und Ausgabe
◦
◦
◦
•
Verwaltung von Dateiattributen (Größe, Datum, Rechte)
Verwaltung von Verzeichnissen
zeichenorientiert: Tastatur, Bildschirm, Drucker, serielle Schnittstelle
blockorientiert: Festplatte, Diskette, CD-Rom, Streamer
Verwaltung von Warteschlangen, z.B. f. Drucker
Zeitgeberfunktionen: Datum, Uhrzeit, verzögerter Programmstart
1.6.2
Betriebssysteme: Bestandteile
Betriebssystemkern: (Kernel) allgemeine Module f. Ein/Ausgabe, Speicherverwaltung, etc.
Dienstprogramme: kopieren, löschen v. Dateien, formatieren v. Disketten, ...
Bootprogramme: zum Hochfahren des Rechners benötigte Programme
ladbare Treiber: z.B. f. Netzwerkanbindung, Streamer
1.7
Softwaretechnologie
Kosten von Hard- und Software:
Früher: 90% Hardware, 10% Software
Heute: 10% Hardware, 90% Software
⇒
Informatik als Ingenieursdisziplin mit der Aufgabe der Softwareentwicklung!
Definition 1.5 Beim Softwareengineering laufen folgende Prozesse parallel nebeneinander ab:
Softwareentwicklung
Projektmanagement
Qualitätssicherung
Projektverwaltung
1.7.1
Softwareentwicklung
Wichtige Begriffe:
•
•
•
Softwarelebenszyklus (software life cycle)
Phasenmodell der Softwareentwicklung
Wasserfallmodell
7
Planung
Der Softwarelebenszyklus
Spezifikation
Entwurf
Kodierung
Test
Betrieb
Stillegung
1.7.2
Moderne Softwareentwicklung
Unix-Pipe: ps | sort | lp
Wichtige Schritte im Entwicklungsprozess:
ps
Use Cases: Typische Benutzer-Programm Interaktionen
Prozeßliste
sort
Verteilungsmodell: Verteilung von Objekten/Prozessen auf einzelne Rechner, bzw. teilnetze
sortierte Liste
lp
Datenflußdiagramm: Graphische Darstellung des Datenflusses.
Führt zu Schnittstellendefinitionen.
druckbare Daten
Drucker
Ausdruck auf Papier
1.7.3
CASE: Computer Aided SW-Engineering
CASE-Tools sind Werkzeuge, die teilweise automatisch den ganzen Entwicklungsprozeß unterstützen.
1.8
Datensicherung
Definition 1.6 Datensicherung (engl. Dump) ist das regelmäßige Speichern von Daten
von der Festplatte auf einen anderen Datenträger mit dem Ziel der Rekonstruktion bei Datenverlust.
klassisches Verfahren: inkrementeller Dump
8
Level 0 Dump: 1× pro Monat wird die gesamte Platte (inklusive Betriebssystem) auf dem
Magnetband gesichert. (in den ungeraden Monaten auf Band M-1, in den geraden Monaten auf Band M-2.)
Level 1 Dump: 1× pro Woche werden die Benutzerdaten von der Platte auf dem Magnetband
gesichert. (in den ungeraden Wochen auf Band W-1, in den geraden Wochen auf Band
W-2.)
Level 2 Dump: täglich werden die Benutzerdaten von der Platte auf dem Magnetband inkrementell gesichert. (in den ungeraden Wochen auf die Bänder Mo-1, . . . , Fr-1, in den
geraden Wochen auf die Bänder Mo-2, . . . , Fr-2)
Bemerkungen:
•
insgesamt werden 14 Magnetbänder für die Datensicherung benötigt!
•
während des Dumps sollte kein Benutzer auf dem Rechner arbeiten.
•
die gesicherten Medien (Bänder) sollten in einem anderen Gebäude sicher verwahrt werden.
modernes Verfahren:
Daten werden monatlich, wöchentlich, täglich auf je eine monatliche, eine wöchentliche, bzw.
eine tägliche Festplatte (im Wechsel) gespiegelt, nach ähnlichem Verfahren wie oben.
1.9
Datenschutz
Bundesdatenschutzgesetz (BGBL. 1 2003, S. 66) § 1, Abs. 1:
“Zweck dieses Gesetzes ist es, den Einzelnen davor zu schützen,
dass er durch den Umgang mit seinen personenbezogenen
Daten in seinem Persönlichkeitsrecht beeinträchtigt wird.”
Beispiel:
Die Veröffentlichung von Fotos von Mitarbeitern ist nur erlaubt,
wenn der Mitarbeiter freiwillig und schriftlich sein Einverständnis erklärt.
1.10
Datenbanken
Beispiele:
•
Literaturdatenbank
•
Personaldatenbank
•
Gefahrstoffdatenbank
•
Buchunssystem für Reisebüros/Fluggesellschaften
•
...
9
Eva Müller
Mitarbeiterin des Monats
Definition 1.7 Eine Datenbank ist eine systematisch strukturierte, langfristig verfügbare
Sammlung von Daten einschließlich der zur sicheren und schnellen Manipulation dieser Daten
erforderlichen Software.
Vorteile einer Datenbank:
•
Mehrbenutzerbetrieb möglich
•
Unterschiedliche Sichten auf die Daten sind möglich
•
Daten sind unabhängig von Nutzerprogrammen; Nutzung ist unabhängig von der Art der
Speicherung.
•
Vollständigkeit (Integrität) und Korrektheit (Konsistenz) werden automatisch gewährleistet.
Eine Datenbank besteht aus
Datenbasis: die (z.B. als Tabellen) in Dateien gespeicherten Daten.
Datenbankmanagementsystem (DBMS): Programm für Aufbau, Verwaltung und Anwendung der Datenbank.
Datenbanksprache: formale Sprache zur Formulierung von Benutzeranfragen an die Datenbank. (Beispiel: SQL (Structured Query Language))
1.11
Das Informatikstudium
Leonardo da Vinci:
Studium ohne Hingabe schadet dem Gehirn
Der Studienerfolg wird statistisch u.a. bestimmt durch folgende Variablen:


Schnitt
falls Abitur
Schnitt − 0.5 falls FH-Reife direkt
Note: Note =

Schnitt − 1 falls FH-Reife auf 2. Bildungsweg
Interesse (für Informatik): Ich wollte schon immer wissen, wie (intelligente Roboter, Verschlüsselung, Internet, . . . ) funktioniert (0|1)
Biss (Wille): Wenn nötig arbeite ich auch am Abend und am Wochenende (0|1)
SozUm: Finanziell gesichert, Wohnen vor Ort, Partnerschaft o.k. (0|1)
10
1.11.1
Entscheidungsbaum
Variablenwerte für Interesse, Biss, SozUm:
1: trifft voll zu;
0: trifft nicht oder nur teilweise zu
Studienerfolg: −: keine Abschluss;
+: Bachelor;
++: Bachelor, sehr gut
Note
>3
Biss
0
Biss
0
1
+
<1.5
1.5-2.5
Interesse
2.5-3
1
0
1
+
Biss
Interesse
0
Interesse
0
0
1
0
1
+
++
+
++
SozUm
0
1
0
1
+
Biss
0
+
1.11.2
1
+
Score (einfach)
Score = (3 − Note) + 3 · Biss + 2 · Interesse + SozUm

 ++ falls Score > 3.5
+ falls Score > 0
Studienerfolg =

− falls sonst
11
++
SozUm
Interesse
1
1
Kapitel 2
Geschichte der Informatik
2.1
•
•
•
•
•
Wichtige Quellen
http://de.wikipedia.org
www.computerhistory.org
F. Naumann, Vom Abakus zum Internet [2]
H. Matis, Die Wundermaschine[3]
W. de Beauclair, Rechnen mit Maschinen – eine Bildgeschichte der Rechentechnik[4]
2.2
Zahlendarstellung
Additive Zahlendarstellung:
additiv (ohne Null)
–
1
11
111
1111
11111
111111
1111111
11111111
...
1111111111111111111111111111111111111111
mit Null (binär)
0
1
10
11
100
101
110
111
1000
...
110010
additive Zahlendarstellung ist für große Zahlen nicht brauchbar!
Mit n Stellen lassen sich darstellen:
additiv:
die Zahlen 1 . . . n
binär:
die Zahlen 0 . . . 2n − 1
dezimal:
die Zahlen 0 . . . 10n − 1
Ziffern 0 . . . b: die Zahlen 0 . . . (b + 1)n − 1
Wieviele Stellen braucht man, um eine große Zahl z darzustellen?
binär:
z = 2n
⇔
allgemein:
12
n = log2 z
dezimal
0
1
2
3
4
5
6
7
8
...
50
additiv:
binär:
dezimal:
Ziffern 0 . . . b:
Zahl d. Stellen um die Zahlen 0 . . . m darzustellen
m+1
≤ log2 m + 1
≤ log10 m + 1
≤ logb+1 m + 1
Die Zahl der Stellen bei Stellenwertsystemen wächst nur logarithmisch mit der Größe
der darzustellenden Zahl (dank der Null).
2.2.1
Geschichte der Zahlen und des Rechnens
30000 v. Chr. erste Zeichensysteme für Zahlen in Ägypten und Mesopotamien
3500 v. Chr. Zeichen auf Tontafeln in Pakistan
Additive Zahldarstellung in Rom, Mexiko (Maya), China, Ägypten, Sumerer
200 v. Chr
Erfindung der Null in Indien ⇒ Stellenwertsystem
0
Römische Schriftzeichen
1200
Fibonacci führt negative Zahlen ein (Schuld)
2.3
Geschichte der Bauelemente
2.3.1
Rechenlogik
Elektrische Rechenmaschine braucht elektrische Schalter!
Mechanik
Antike bis heute
Relais
1835 – 1950, J. Henry
Röhre
1904 – 1970, J.A. Fleming
(Engl.)
Transistor
1947 – heute, Bell Labs
(USA)
13
Integrierter
Schaltkreis
1958, heute bis zu 1 Milliarde Transistoren auf unter 1
cm2
Pentium 4
Intel, 2000, bis 3.8 GHz
Taktfrequenz, 2 CPUs auf
einem Chip
2.3.2
•
•
•
•
•
erste Festplatte
50 Platten, je 60 cm Durchmesser, 1200 Umdr./min
pro Platte 2 × 100 Spuren mit je 500 Zeichen
⇒ pro Platte 100 kB Speicher
gesamt: 5 MB Speicher
2.3.3
•
•
•
Speichertechnologie 2005
4 Gigabit pro cm2
Spurabstand ≈ . . .
Köpfe fliegen 10-15 Nanometer über d. Platte
2.3.4
2.4
Speichertechnologie 1956–2005
Geschichte der Rechenmaschinen
2.4.1
•
•
Speichertechnologie 1956, IBM-RAMAC
Kerbhölzer und Knotenschnüre
Speicherung von Zahlen
Additition und Subtraktion
14
2.4.2
Mechanische Rechenmaschinen (Mittelalter)
Analytical Engine
Abakus: +, −
Pascal (1641): +, −
kannt):
+,
−,
×,
/
1.
In der Programmierbarkeit einer Maschine durch
Die
grundlegend neuen
Ideenlange
bestehen:unbeSchickard
(1623,
Verwendung von Jacquard‘schen Lochkarten.
In der Weiterverwendung von
Zwischenergebnissen. („the engine eating its
own tail“)
3.
Der Aufteilung des Gerätes in Speicher(Store)
und Rechenwerk (Mill). Zahnstangen dienten der
Übertragung von Zahlenwerten zwischen Store
und Mill (Rechnerbus).
Bis 1948 (Speicherprogrammierbarkeit, John
von Neumann) gibt es keine grundlegende
Weiterentwicklung dieses Konzepts! Die
ersten „modernen“ Rechner hatten eine
einfachere Architektur.
2.
Die Analytical Engine war ein Papiercomputer. Nur
einzelne Komponenten (Teile des Rechenwerks)
wurden wirklich gebaut.
Leibniz (1675) +, −, ×, /
Babbage (1823), Difference Babbage (1833–?), Analytical
Informatikgeschichte, E. Ehses 2003
17
Engine
Engine (programmierbar!)
Der Abakus (ca. 2000 v.Chr. bis heute!)
•
•
•
die universale Rechenmaschine schlechthin!
Datenblatt
Analytical
Engine(bis heute), Rußland
verwendet in Griechenland,
Rom, der
Japan,
China
(bis heute)
heute in Japan: Wettbewerbe
Abakus
Taschenrechner
Speicher
für rund–100
Variable zu je 30-40 Stellen.
Die Analytical Engine
Vorrichtung zur Wiederholung von Operationen
(„mechanical means have been provided for backing
up or advancing the operation cards to any extend“)
Stanzer für Zahlenkarten (Massenspeicher).
•
•
•
Programmierbarkeit einer Drucker.
Maschine (revolutionär!) durch Verwendung von Jacquard’schen
Lochkarten.
Zeichengerät.
Weiterverwendung von Zwischenergebnissen.
(“the engine eating
Setzmaschine (offline).
its own tail”)
Addition und Subtraction vermutlich ca. 2 sec.
Multiplikation ca 1 min.und Rechenwerk (Mill).
Aufteilung des Gerätes in Speicher(Store)
Zahnstangen dienten der Übertragung von Zahlenwerten zwischen
Store und Mill (Rechnerbus).
Informatikgeschichte, E. Ehses 2003
15
18
Die Analytical Engine war ein Papiercomputer. Nur einzelne Komponenten (Teile des Rechenwerks) wurden wirklich gebaut. Bis 1948 (Speicherprogrammierbarkeit, John von Neumann)
gibt es keine grundlegende Weiterentwicklung dieses Konzepts! Die ersten modernen Rechner
hatten eine einfachere Architektur.
Eingabeschnittstelle für Lochkarten, unterschieden nach operation cards für die Befehlseingabe,
variable cards zur Eingabe von Variablen und ihrer Speicheradresse, sowie den number cards.
Ausgabeschnittstelle entweder für einen Drucker oder für Lochkarten die in die Bibliothek
eingereiht werden.
Die Chiffriermaschine Enigma
•
•
•
•
•
•
•
1923: Erfindung durch Arthur Scherbius zum Gebrauch
für Geschäftsleute.
1925: Deutsche Wehrmacht kauft Enigmas.
mehrfach geknackt (Polen) und wieder verbessert.
1939: Der Großangriff der Briten auf die Enigma in Bletchley Park.
1942: Neue Enigma mit vier Walzen ist wieder sicher
und wird im U-Boot-Krieg eingesetzt.
1943: Nach fast einem Jahr wird die 4-Walzen-Enigma
geknackt. Hier kam Colossus zum Einsatz.
1945: Entschlüsseln der Enigma-Codes war am Sieg der
Alliierten mit beteiligt. ca. 10 000 Personen arbeiteten
in drei Schichten rund um die Uhr.
Zuse Z1, Z2
•
•
•
Baujahr 1938, 1939
Bleche schieben Stifte, Relais (Z2)
binär-dezimal
Konvertierung,
√
+, −, ×, /, ,
2.4.3
Operationen:
Elektrische Rechenmaschinen
Zuse Z3
Der im Flugzeugbau tätige Maschinenbauer und Bauingenieur Konrad Zuse (Berlin, 1910–1985)
erfand 1941 den ersten frei programmierbaren Rechner Z3.
•
•
•
•
•
•
•
•
Baujahr 1941
programmierbar über Lochstreifen
Ausgabe über Lampenfeld
Binäre Schaltlogik
“RISC”-Architektur: wenige Befehle
Gleitpunktarithmetik
Multiplikationszeit: 3 sec.
Hauptspeicher: 64 Worte à 22 Bit
16
ASCC (MARK 1)
•
•
•
•
•
•
•
•
H. Aiken will Rechner zum Lösen von DGLs
erster Rechner mit konsequenter vonNeumannArchitektur
Baujahr 1944, Univ. Harvard und IBM
programmierbar über Lochstreifen
Multiplikationszeit: 6 sec.
in Betrieb bis 1959
760 000 Einzelteile
15 m lang, 2.5 m hoch
Colossus
•
•
•
•
•
•
entwickelt u.a. von Alan Turing zum
Knacken von Enigma-Codes
Baujahr 1943,
programmierbar über Lochstreifen
photoelektr. Leser (5000 Zeichen/sec.)
Multiplikationszeit: 6 sec.
Original
1500 Röhren
Eniac (electronical numerical integrator and computer)
•
•
•
•
•
•
Baujahr 1946, Univ. Pennsylvania, USA
universell eingesetzt, in Betrieb bis 1955
Dezimalrechner, 10 Dezimalstellen
Taktfrequenz 100 kHz (Addition 0,2 ms)
18000 Röhren, 1500 Relais
Multiplikationszeit: 3 sec.
IBM 360
• Baujahr 1964
• Erster kommerziell erfolgreicher Großrechner
• MTS: Michigan Time sharing system, 1966
Control Data CDC 6600
•
•
•
Erbaut 1964 von S. Cray
3 MIPS
verteilte Architektur, 10 I/O-Prozessoren
17
Nachbau
Telefunken TR 440
•
•
•
•
•
Baujahr 1970
6,50 m breit
Gewicht ca. 1250 Kg
Taktfreq. 20 MHz, 1.2 MIPS
1,5 MB Kernspeicher mit virtueller
Adressierung
CPU
Lochkartenstanzer
Cray 1
•
•
•
•
•
•
Baujahr 1976
Vektorrechner
Supercomputer für numerische Berechnungen
64 parallel arbeitende 64-Bit Prozessoren
166 Mega-FLOPS
Gewicht: 2.5 Tonnen
Connection Machine
•
•
•
•
Baujahr 1986, D. Hillis of Thinking Machines Corp
Massiv parallel: 16000 parallele Prozessoren
Milliarden Operationen pro sec.
Anwendung in der KI, u.a. Neuronale Netze
PCs
Commodore
Pet, Apple 2, 1977, 1 Main1977,
Kassetten- board, Farbgrafik
laufwerk, 4/8 kB
Hauptspeicher 2
2.4.4
IBM PC, 1981, 4.77 Commodore 64, 1981, für 595 US$ viel billiMHz Intel 8088, MS- ger als die Konkurrenz, TV-Bildschirm, KasDOS (Microsoft disc settenlaufwerk, 64 KB RAM
operating system)
Zitate
“I think there is a world market for about five computers.”
Thomas J. Watson Jr., chairman of IBM (1943)
“Where a calculator on the ENIAC is equipped with 18,000 vacuum tubes and weighs 30 tons,
computers in the future may have only 1,000 vacuum tubes and perhaps weigh 1 12 tons.”
Popular Mechanics (March 1949)
“640 K [of computer memory] ought to be enough for anybody.”
18
2.5
•
•
Geschichte der Programmiersprachen
Heute gibt es über 2500 verschiedene Programmiersprachen
Siehe Aushang, bzw. www.levenez.com
prozedural: Assembler, Fortran (1954), PL/1, Basic, Simula, APL, C, Pascal, Cobol, Perl,
sh, awk, SQL, PHP
funktional: Lisp (1958), Haskell, Miranda, Mathematica
logisch: Prolog (1970)
objektorientiert: Smalltalk (1969), C++, Oberon, Java, C#
Fakultät in C, Prolog, Mathematica
C (prozedural):
1
2
3
4
5
6
7
8
int fakultaet(int n)
{
int ergebnis;
if (n == 1) return 1;
ergebnis = n * fakultaet(n-1);
return(ergebnis);
}
Mathematica (funktional):
1
2
Fac[0] := 1;
Fac[n_] := n * Fac[n - 1]
Prolog (logisch):
1
2
2.6
•
•
•
•
•
•
fakultaet(1,1).
fakultaet(N,Res) :- N1 is N-1, fakultaet(N1,Res1), Res is N * Res1,
Geschichte des Internet
Gegründet 1962 durch die Advanced Research Projects Agency (ARPA) der USA.
Bob Kahn und Vint Cerf erfinden 1973 das Transmission Control Protocol (TCP) und
1976 das TCP/IP Protokoll.
Bob Kahn und Vint Cerf erfinden 1973 das Transmission Control Protocol (TCP).
Erstes Email-Netz 1977 an der Univ. Wisconsin.
TCP/IP wird weltweit eingeführt
Tim Berners-Lee erfindet 1989 das World Wide Web (WWW)
19
“In the Beginning, ARPA created the ARPANET.
And the ARPANET was without form and void.
And darkness was upon the deep.
And the spirit of ARPA moved upon the face of the network and ARPA said, ’Let there be a
protocol,’ and there was a protocol. And ARPA saw that it was good.
And ARPA said, ’Let there be more protocols,’ and it was so. And ARPA saw that it was good.
And ARPA said, ’Let there be more networks,’ and it was so.”
– Danny Cohen
2.6.1
•
•
•
•
•
•
Neben Text und Bildern soll der Inhalt (Semantik) von Webseiten in Zukunft durch
Annotationen formal beschrieben werden.
Anfrage: Wie viele Tore hat Michael Ballack im Jahre 1998 geschossen?
Google kann die Anfrage nicht beantworten.
Das Semantic Web soll das demnächst können.
Resource Description Framework (RDF) und Web Ontology Language (OWL) zur Beschreibung von Metainformation über Webseiten
Unter Verwendung von Automatischen Theorembeweisern sollen semantische Anfragen beantwortet werden.
2.6.2
2.7
Das Semantic Web
Aktuelle Trends (2005)
Große Informatiker
Blaise Pascal (Frankreich, 1623–1662)
• baute als 18 jähriger für seinen Vater die erste funktionierende
mechanische Rechenmaschine zur Addition sechsstelliger Zahlen.
(Digitalrechner)
20
Gottfried Wilhelm Leibniz (Leipzig, 1646–1716)
•
•
•
•
Philosoph, Mathematiker, Diplomat, Bibliothekar
baut eine Rechenmaschine für alle vier Grundrechenarten.
Gründer der Akademie der Wissenschaften in Berlin
Erfindung der Dualzahlen
Charles Babbage (England, 1791-1871)
•
•
Entwickelt die Difference Engine zur Ableitung von Polynomen
(1823)
Entwickelt die Analytical Engine (1833)
Kurt Gödel (Österreich, 1906–1978)
Der Österreicher Kurt Gödel zeigt 1931
•
•
dass in der Prädikatenlogik erster Stufe alle wahren Aussagen
herleitbar sind.
In Logiken höherer Stufe hingegen gibt es wahre Aussagen, die
nicht beweisbar sind. Es lassen sich also nicht alle Berechnungsaufgaben automatisieren.
Zusammen mit Einstein arbeitet er auch an der Relativitätstheorie und
Kosmologie.
Denken Sie nach über die Aussage: ,,Ich bin nicht beweisbar” oder über ,,Die Menge aller
Barbiere, die all die Menschen rasieren, die sich nicht selbst rasieren.” oder über die
Menge {x|x ∈
/ x}.
Alan Turing (England, 1912–1954)
Der Brite Alan Turing leistet u.a. folgendes
•
Er erfindet 1935 das bis heute universelle Berechnungsmodell, die “Turingmaschine”.
•
Er zeigt, dass es viele Funktionen gibt, die nicht berechenbar sind.
•
Er beweist das Halteproblem: Es kann kein Programm geben, das in endlicher Zeit entscheidet, ob ein beliebiges Programm auf einer Eingabe hält oder eine Endlosschleife hat.
•
Er definiert den Begriff der Intelligenz über den “Turing Test”.
•
Ende der Dreißiger Jahre macht er schon Vorschläge für lernfähige Computer.
•
Er ist im 2. Weltkrieg führend beteiligt an der Dechiffrierung der Enigma.
•
Er ist beteiligt am Bau von Colossus, dem ersten britischen Computer für die Dechiffrierung der Enigma (1944).
•
Er entwickelt einen Schachalgorithmus. Mangels Computer simuliert er auf Papier den
Computer und benötigt so etwa 90 Minuten pro Zug.
21
Denken Sie nach über das Programm:
Unmöglich(int i)
if( hält(unmöglich,0))
while( TRUE ) printf(“das kann noch dauern ...”);
else
printf(“0”);
Lesekopf
Die Turingmaschine:
HAL LO
Z
Zustand
Claude Shannon (Michigan, 1916–2001)
•
•
•
•
A Mathematical Theory of Communication (1948)
Informationstheorie, Entropie als Informationsmaß
Formale Grundlagen der Kryptographie (Konfusion und Diffusion, 1949)
Entwickelt einen Schachcomputer (1960)
Alonzo Church (Washington, 1903–1995)
•
•
•
Berechenbarkeit
Lambda Kalkül
Church’sche These: Die Turingmaschine kann alles berechnen, was
wir intuitiv für berechenbar halten.
John von Neumann (Polen, 1903–1957)
•
•
•
•
Spieltheorie, Minimax Algorithmus (1928)
Quantenmechanik, Entwicklung der Atombombe
von Neuman Architektur von Rechnern (EDVAC)
genial, lebenslustig, trinkfest
Die vonNeumann-Architektur
•
•
•
•
Zentraleinheit (CPU mit Rechen- und Steuerwerk)
Speicher (Hauptspeicher)
Bus (Busse)
Ein/Ausgabe (I/O) ⇒ Peripheriegeräte
22
CPU
Rechenwerk Steuerwerk
Speicher
(RAM)
Datenbus
Adressbus
I/O
Edsger Dijkstra (Rotterdem, Holland, 1930–)
• Algorithmen auf Graphen
• Kürzeste Wege Algorithmen
• Korrektheit von Programmen
Donald Knuth (Milwaukee, 1938–)
•
•
•
•
Meister der Algorithmen, u.a.: Zufallszahlen, Sortieren, Suche, ...
Autor der 5-bd. ,,Bibel”: The Art of Computer Programming
Erfinder des Textsatzsystems TEX
spielt eine selbstgebaute Orgel
Zitate: ,,Computer Programming is an art form, like the creation of poetry or music.”
,,I got into compilers because I thought the most amazing thing you could do with computers
was to have them write their own programs. When computing is applied to computing, that’s
when computer science reaches an ultimate completeness.”
Stephen A. Cook (Buffalo, New York, 1939–)
•
•
Begründer der modernen Komplexitätstheorie
NP-Vollständigkeit
Leslie Lamport (New York, 1941–)
• Theorie verteilter Systeme
• Lamport clock: partielle Ordnung der Zeit, keine globale Zeit
• Enwickler von LATEX(TEX-Macropaket)
Zitat: ,,When I look back on my work, most of it seems like dumb luck – I happened to be
looking at the right problem, at the right time, having the right background.”
Ken Thompson, Dennis Ritchie (New Orleans, 1943–, New York, 1941–)
•
•
1969: Erfindung von UNIX und C (Bell Laboratories, New Jersey, später AT&T)
Viele innovative Konzepte: Pipelining, verteilte Prozesse, Sockets, Timesharing und Prozesse mit Prioritäten (auch auf PCs)
Nikolaus Wirth (Winterthur, Schweiz, 1934–)
•
•
Erfinder der Programmiersprachen Pascal (1970) und Modula
(1975)
Erfinder der Objektorientierten Sprache Oberon (1987)
23
Bill Gates (Seattle, 1955–)
•
•
•
•
•
brach nach zwei Jahren sein Studium in Harvard ab.
zus. mit Paul Allen Gründer von Microsoft
mit d. Kauf von MS-DOS 1980 beginnt die Erfolgsstory von Microsoft
1983 erscheint die erste Version des Betriebssystems Windows
reichster Mann der Welt (fast 50 Mrd. US$)
Tim Berners-Lee (London, 1955–)
•
•
1989 schlug Berners-Lee seinem Arbeitgeber CERN (Europäisches
Kernforschungslabor) ein Projekt vor, das auf dem Prinzip des
Hypertexts beruhte und den weltweiten Austausch sowie die
Aktualisierung von Informationen zwischen Wissenschaftlern vereinfachen sollte.[1]
entwickelte den ersten Webbrowser, baute die erste Webseite
2.7.1
Der Turing Award
siehe www.acm.org/awards/taward.html
ACM’s most prestigious technical award is accompanied by a prize of $ 100,000.
Financial support of the Turing Award is provided by the Intel Corporation.
ACM: Association of Computing Machinery
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
A.J. Perlis
Maurice V. Wilkes
Richard Hamming
Marvin Minsky
J.H. Wilkinson
John McCarthy
E.W. Dijkstra
Charles W. Bachman
Donald E. Knuth
Allen Newell, Herbert A. Simon
Michael O. Rabin, Dana Scott
John Backus
Robert W. Floyd
Kenneth E. Iverson
C. Antony R. Hoare
Edgar F. Codd
Stephen A. Cook
Ken Thompson, Dennis Ritchie
Niklaus Wirth
Richard M. Karp
John Hopcroft, Robert Tarjan
John Cocke
Ivan Sutherland
William (Velvel) Kahan
Fernando J. Corbato
Robin Milner
Butler W. Lampson
Juris Hartmanis, Richard Stearns
Edward Feigenbaum, Raj Reddy
Manuel Blum
Amir Pnueli
Douglas Engelbart
James Gray
Frederick P. Brooks
Andrew Chi-Chih Yao
Ole-Johan Dahl, Kristen Nygaard
Ron Rivest, Adi Shamir, Leonard Adleman
Alan Kay
Compilerbau
EDSAC, erster Computer mit internem Programmspeicher
Kodierung, Hamming-Distanz
Perzeptron, Neuronale Netze
Numerik
Künstliche Intelligenz, LISP
Graphenalgorithmen, ALGOL
Datenbanken
Algorithmen, “The Art of Computer Programming”, Erfinder von TEX
Künstliche Intelligenz, General Problem Solver
Automaten, Alg., Nichtdeterminismus, randomisierte Alg.
FORTRAN, Backus-Naur-Form Grammatik
formale Methoden zur Software Entwicklung
Programmiersprachen, APL
Programmiersprachen
Relationale Datenbanken
Komplexität, NP-Vollständigkeit
Betriebssystem UNIX
MODULA, PASCAL, Oberon
NP-Vollständigkeit
Algorithmen und Datenstrukturen (Lehrbuch)
Compilerbau, RISC-Computer
Computergraphik
Numerik, Floating Point Arithmetik
Time sharing
Logik, funktionale Progarmmierung: ML
PC-Entwicklung (Microsoft)
Komplexitätstheorie
Künstliche Intelligenz, prakt. Umsetzung
Komplexitätstheorie, Kryptographie
Temporallogik, Programmverifikation
Maus, Fenster
Datenbanktechniken
Rechnerarchitaktur, IBM 360
Zufallszahlen, Kryptographie
Simula, OOP
Public Key Kryptographie, RSA-Algorithmus
Objektorientierte Programmierung, Smalltalk
24
2004
2005
2006
2007
Vinton G. Cerf, Robert E. Kahn
Peter Naur
Frances E. Allen
E. Clarke, A. Emerson, J. Sifakis
2.8
Vernetzung, TCP/IP
Design von Programmiersprachen (Algol 60), Compilerdesign
Parallele Programmierung, erste Frau mit Turing Preis!
Modellprüfung
Frauen in der Informatik
Warum gibt es so wenige Frauen in der Informatik?1
•
Intelligenztests zeigen minimale Unterschiede ausschließlich bei:
◦
◦
•
Vorstellung räumlicher Drehungen von Figuren zugunsten der Männer
Sprachkompetenzen zugunsten der Frauen
Es gibt keine Intelligenz und Begabungsunterschiede die die geringe Beteiligung der Frauen erklären können!
Frauenanteil am Informatik-Studium (2001)
Land
England
Italien, Frankreich, Spanien, Portugal
frühere Sowjetunion
Bulgarien
Griechenland
Indien, Malaysia, Singapur
Deutschland
2.8.1
Frauenanteil [%]
35
40–50
50
60–70
59
50
8
Frauen in der Geschichte der Informatik
Ada Augusta von Lovelace (1815-1852)
•
•
•
•
arbeitet mit Ch. Babbage an der Analytical Engine
Mutter von vier Kindern
Sie erfand Unterprogramme, Schleifen und bedingte Sprünge!
publizierte unter dem Kürzel A.A.L.
Grace Murray Hopper (1906-1992)
•
•
•
•
•
beteiligt an Entwicklung von Mark 1, Mark 2, Univac 1
entwickelt 1952 einen der ersten Compiler
“Debugging”: Eine tote Motte (bug) blockiert ein Relais im Rechner. Zitat: First actual case of a bug being found.
Zitat: Wenn du eine gute Idee hast, dann tu es einfach, denn es
ist viel einfacher sich hinterher zu entschuldigen, als vorher um
Genehmigung zu bitten.
Über 40 Ehrendoktorwürden und Preise
Bis etwa 1960 waren viele Frauen in der Informatik tätig:
1
teilweise entnommen aus Olga Goldmann Seminar: Geschichte der Informatik, www.virtosphere.de/
schillo/teaching/WS2001/Geschichts-Seminar.html
25
•
•
2.9
Beim Knacken der Enigma in Bletchley Park (England)
Bei der Bedienung und Programmierung früher Rechner, u.a. Colossus (G.B.), Eniac
(USA), nach dem Krieg in Deutschland
Wichtige Institute und Firmen
IAS: Institute for advanced studies, Princeton, New Jersey, USA
MIT: Massachusettes Institute for Technology, Cambridge, Massachusetts, USA
SRI: Stanford Research Institute, Palo Alto, USA
Stanford University, Palo Alto, California, USA
Harvard University, Cambridge, Massachusetts, USA
UCB: Univ. of California, Berkeley, USA
AT&T Bell Labs: New Jersey, USA
26
Kapitel 3
Algorithmen und Datenstrukturen –
Einführung
In diesem Kapitel werden hauptsächlich Sortieralgorithmen untersucht. Ziel ist hier aber nicht
primär das Sortieren. Vielmehr wird hier an einem einfachen Beispiel die Entwicklung und
Verbesserung von Algorithmen und Datenstrukturen aufgezeigt. Wichtig ist auch die mathematische Analyse der Algorithmen bezüglich Rechenzeit und Speicherplatzverbrauch.
3.1
Sortieren durch Einfügen
Beispiel 3.1 7 4
4 7
4 7
3 4
3 4
1 3
8
8
8
7
5
4
3
3
3
8
7
5
5
5
5
5
8
7
1
1
1
1
1
8
Definition 3.1 Eine Liste A = (A1 , . . . , An ) heisst sortiert, wenn für alle
i = 1, . . . , n − 1 gilt Ai ≤ Ai+1 .
3.1.1
Algorithmus (grob)
Von links nach rechts: eine Zahl x wählen und verschieben nach links bis Ai−1 ≤ Ai = x ≤ Ai+1
erfüllt ist.
For i:= 2 To n Do
x:= a[i];
"füge x am richtigen Platz ein"
27
3.1.2
Algorithmus als PASCAL-Programm
Program Sortieren(input,output);
CONST n = 8000;
TYPE
index = 0..n;
item = RECORD
key : Integer;
data : String[20]
END;
itemarray = ARRAY [0..n] OF item;
VAR a : itemarray;
i,j : Index;
Rechenzeit
Procedure Ins sort(var a: itemarray);
VAR
i,j : index;
x : item;
BEGIN
FOR i := 2 TO n DO
BEGIN
x := a[i]; a[0] := x; j := i-1;
WHILE x.key < a[j].key DO
BEGIN
a[j+1] := a[j];
j := j-1;
END;
a[j+1] := x
END
END;
Index i:
Liste A:
0
x
1
worst case
(Tmax (n))
(n − 1) · (I + C)
(n
Pn− 1) · (3M + I)
i=2 i · C
best case
(Tmin (n))
(n − 1) · (I + C)
(n − 1) · (3M + I)
(n − 1) · C
Pn
i · (M + I)
Pi=2
n
i=2 i · (M + I)
0
0
(n − 1) · (I + M )
(n − 1) · (I + M )
i
a(i)
n
Durch kopieren von a(i) auf die Variable x und auf a(0) wird die Terminierung der Schleife
sichergestellt. Sollte die Zahl a(i) also kleiner als alle Elemente davor in der Liste sein und
ganz nach links verschoben werden müssen würde der Schleifenindex i ohne diese Terminierung einen negativen Wert annehmen. Da die Liste aber bei a(0) aufhört, würde dies zu einem
undefinierten Zustand führen. Diese Terminierung führt zu einem weiteren Schleifendurchlauf.
Dieser Durchlauf fällt aber nicht weiter ins Gewicht, da es sich um einen konstanten Aufwand
handelt. Dagegen wird im Vergleich zu einer zusätzlichen Bedingung im Kopf der While-Schleife
ein Aufwand proportional zu n eingespart.
3.1.3
Worst - Case Rechenzeit
Im Programmcode eingetragen ist für jede Programmzeile die Laufzeit. Als Parameter treten
rechnerabhängigen Größen I (Increment), M (Move) und C (Compare) auf:
28
I = Rechenzeit für eine Zähloperation
M = Rechenzeit für eine Zuweisungsoperation
C = Rechenzeit für eine Vergleichsoperation
Diese Zeiten sind konstant, d.h. nicht von n abhängig und deshalb für die Berechnung der
Komplexität unbedeutend. Für die Berechnung von exakten Laufzeiten sind sie jedoch sehr
wichtig.
Tmax (n) = (n − 1) · (I + C + 3M + I + M + I) +
n
X
(i · C + i · (2M + 2I))
i=2
= (3I + 4M + C) · n − (3I + 4M + C) + (2I + 2M + C) ·
n
X
i
i=2
mit
n
X
i=2
i=
n(n + 1)
n2 + n − 2
n2 n
−1=
=
+ −1
2
2
2
2
erhalten wir
a
b
{
c
z
}|
{
3
C
Tmax (n) = (I + M + ) ·n2 + (4I + 5M + C) ·n −(5I + 6M + 2C)
2
2
2
= a·n +b·n+c
}|
z
{
z
}|
Wenn die Konstanten nicht interessieren, kann die Berechnung der Worst-Case Rechenzeit
vereinfacht werden:
(n − 1) · (I + C)
(n − 1) · (3M + I)
n
X
i·C
→
→
→
(n − 1) · c1
(n − 1) · c2
2
X
i) · c3
(
i=2
i=2
..
.
..
.
..
.
Ergebnis: a · n2 + b · n + c
Bestimmung von a, b und c
1.) Messe drei Zeiten für verschiedene n = n1 , n2 , n3
−→ (n1 , T1 ), (n2 , T2 ), (n3 , T3 )
T(n)
T3
T2
T1
n1
n2
n3
29
n
2.) Einsetzen in Parabelgleichung:
T1 = a · n21 + b · n1 + c
T2 = a · n22 + b · n2 + c
T3 = a · n23 + b · n3 + c
3.) Auflösen des linearen Gleichungssystems nach a, b und c (siehe Übung 2).
Beispiel 3.2 Vergleich von 3 verschiedenen Komplexitäten
n
10
100
1000
Algorithmus 1
T (n) = log n · c
1s
2s
3s
Algorithmus 2
T (n) = c · n
10 s
100 s
1000 s
Algorithmus 3
T (n) = c · n2
100 s
10 000 s
1 000 000 s
Algorithmus 4
T (n) = c · n3
1 000 s
1 000 000 s
1 000 000 000 s
Algorithmus 5
T (n) = c · 2n
1024 s
≈ 1030 s
≈ 10300 s
Die Werte wurden mit einem c von einer Sekunde errechnet. Eine bessere Hardware würde nur
dieses c verbessern und dadurch die Rechenzeit nicht wesentlich beeinflussen. Bei großen n ist
die Komplexität viel ausschlaggebender als die Konstante c.
3.1.4
Best-Case Rechenzeit
Ist die Liste A vorsortiert, so wird die While-Schleife nicht durchlaufen und das Programm ist
viel schneller.
Analog zu den Berechnungen im Worst-Case kann man auch im Best-Case die Zeiten aus der
Tabelle aufaddieren und man erhält
Tmin (n) = d · n + e.
3.1.5
Einschub: Asymptotik
Beschreibung des asymptotischen Verhaltens von Rechenzeiten T (n) (oder Speicherplatz oder
anderer Funktionen) für n → ∞.
Idee: Vernachlässigung von konstanten Faktoren. Nur die Abhängigkeit von n für große n ist
wichtig.
30
Definition 3.2 Seien die Funktionen f : N → R+ , g : N → R+ gegeben. Dann schreibt
man:
Asymptotische obere Schranke:
f (n)
≤c
n→∞ g(n)
f (n) = O(g(n)),
wenn ∃ c ∈ R+ : lim
f (n) = o(g(n)),
wenn
f (n)
=0
n→∞ g(n)
lim
Asymptotische untere Schranke:
f (n)
≥c
n→∞ g(n)
f (n) = Ω(g(n)),
wenn ∃ c ∈ R+ : lim
f (n) = ω(g(n)),
wenn
f (n)
=∞
n→∞ g(n)
lim
Asymptotische enge (harte) Schranke:
f (n) = Θ(g(n)),
f (n)
≤ c2
n→∞ g(n)
wenn ∃ c1 , c2 ∈ R+ : c1 ≤ lim
O, Ω, Θ, o, ω sind Relationen auf Funktionen, wie z.B. <, ≤ auf reellen Zahlen.
Analogien:
Funktionen f : N → R+
f (n) = O(g(n))
f (n) = o(g(n))
f (n) = Ω(g(n))
f (n) = ω(g(n))
f (n) = Θ(g(n))
reelle Zahlen
a≤b
a<b
a≥b
a>b
a=b
Satz 3.1
T (n) = Θ(g(n))
⇔
T (n) = Ω(g(n)) und T (n) = O(g(n))
Die bisher berechneten Ergebnisse lassen sich nun also formulieren wie folgt:
Satz 3.2 Beim Sortieren durch Einfügen gilt
Tmin (n)
Tmax (n)
T (n)
T (n)
=
=
=
=
31
Θ(n)
Θ(n2 )
Ω(n)
O(n2 )
3.1.6
Schwachstellen und mögliche Verbesserungen
x
Die Suche nach der Einfügestelle für das Element x soll verbessert werden.
Suche in Listen
Aufgabe 1: Suche ein Element x in einer beliebigen Liste.
optimale Lösung: lineare Suche mit Tmax (n) = Θ(n)
Aufgabe 2: Suche ein Element x in einer sortierten Liste A[1 . . . n]
optimale Lösung: Bisektion
Der Bereich links von x ist bereits sortiert. Man findet die richtige Stelle für x indem man die
Liste links von x mehrfach halbiert.
Definition 3.3 bxc := max{y ∈ Z|y ≤ x}. bxc ist also die größte ganze Zahl kleiner oder
gleich x. Analog sei dxe = min{y ∈ Z|y ≥ x}.
Der Bisektionsalgorithmus
Bisektion(A,x)
a=1
b=n
m = b a+b
c
2
While A[m] 6= x & b > a
If x < A[m]
Then b = m
Else a = m
m = b a+b
c
2
If A[m] == x
Then print (”Hurra ”,x,”gefunden an position ”,m)
Else print (”Schade, ”,x,”nicht in A”)
Komplexität
Sei die Arraylänge n = 2k . Dann sind höchstens k Wiederholungen der While-Schleife erforderlich. Also ist die Rechenzeit proportional zu k, d.h. T (n) = c · k.
n = 2k
ln n = k · ln 2
ln n
k =
ln 2
32
Also gilt für die Bisektion
T (n) = c ·
ln n
= c · log2 n = O(log n)
ln 2
x
= c · ln x ← log n, erkennt man, daß sich alle Logarithmen nur
Erläuterung: An log2 x = ln
ln 2
um einen kostanten Faktor unterscheiden.
Das Suchen der Einfügestelle ist mit logarithmischem Aufwand möglich.
Aber: verschieben der O(n) Arrayelemente im Array kostet linearen Aufwand.
Idee: verwende dynamische Datenstruktur als verkettete Liste.
x
Verschieben der Arrayelemente ist damit unnötig. x wird direkt an der richtigen Stelle eingefügt.
Aber: die Bisektion ist auf einer verketteten Liste nicht anwendbar.
Daher: für Sortieren durch Einfügen bleibt Tmax (n) = Θ(n2 )
3.2
Quicksort
Es soll die Liste 5, 3, 2, 6, 4, 1, 3, 7 sortiert werden. Dies erfolgt nach dem Prinzip divide and
conquer durch rekursiv wiederholtes Aufteilen und bearbeiten, wie in folgender Tabelle zu
sehen:
5
3
2
6
4
1
3
7
↑i
x = 5 (Pivotelement)
↑j
5
↑i
3
3
2
3
2
3
3
2
3
↑i
1
3 2
←→
3 2
↑i ↔↑j
2 3
3
↑j ↑i
2 3
3
↑i ↔↑j
2 3
3
↑j
↑i
2 3
3
↑i ↑j
2 3
3
1
1
↑i ↑j
1
1
1
6
4
←→
6
4
↑i ↔
1
4
↑j
1
4
↑j
3
4
1
3
↑j
5
7
4
1
↑j
6
5
↑i
6
5
↑i ↔↑j
5
6
↑j
↑i
5
6
↑i ↑j
5
6
4
5
6
7
4
5
6
7
4
5
6
7
4
7
7
7
x = 3, x = 6
7
7
7
Erläuterung: Der erste Wert der Liste ist das Pivotelement (ausgezeichnetes, besonderes Element). Zwei Indizes i und j durchlaufen die Liste nach folgendem Kriterium:
33
i sucht von links nach einem Wert ≥ x und j von rechts nach einem Wert ≤ x. Dann werden i
und j vertauscht. Das setzt sich solange fort bis sich beide Indizes überkreuzen oder gleich sind.
Dann wird die Liste rechts von j geteilt und auf beiden Hälften rekursiv von vorne begonnen.
3.2.1
Der Algorithmus
Seien A=Liste, p=Anfangsindex, r=Endeindex. Dann ist die rekursive Struktur gegeben durch:
Quicksort(A,p,r)
if p < r
then q=Partition (A,p,r)
Quicksort (A,p,q)
Quicksort (A,q+1,r)
Das Aufteilen erfolgt mittels
Partition(A,p,r)
x=A[p]
i=p-1
j=r+1
while TRUE do
repeat j=j-1
until A[j] ≤ x
repeat i=i+1
until A[i] ≥ x
if i < j
then vertausche A[i] mit A[j]
else Return(j)
Der erste Aufruf von Quicksort auf einer Liste der Länge n erfolgt durch
Quicksort(A,1,length(A))
3.2.2
Analyse
Laufzeit von Partition
auf Array A[p...r] mit n = r − p + 1
T (n) = Θ(n)
34
Laufzeit von Quicksort im Best Case
n
n/2
n/2
n/4
2
1
n/4
2
1 ... 1
n/4
2
2
1 ... 1
1 ... 1
n/4
2
1 ... 1
2
1 ... 1
2
1 ... 1
log2 n Ebenen
2
1 ... 1
1
Rekursionsbaum
Der Rekursionsbaum hat n Blattknoten. Er wächst in der Breite exponentiell. Trotzdem ist die
Komplexität auf jeder Ebene Θ(n). Warum?
Zahl der Ebenen im Rekursionsbaum? Zur Vereinfachung nehmen wir an, das Array hat
n = 2k Elemente. Dann ist die Tiefe des Baumes gleich k. Auflösen nach der Tiefe k ergibt:
log2 n = log2 2k = k.
Die gesamte Rechenzeit ist also hier gleich der Produkt aus dem Aufwand pro Ebene und der
Zahl der Ebenen (Tiefe):
Tmin (n) = c · n · log2 n = Θ(n log n)
Laufzeit von Quicksort im Worst Case (sortierte Liste)
1
2
3
4 5
6
7 8
1
↑i ↑j
1
2
3
4 5
6
7 8
2
↑i ↑j
2
3
4
5 6
7 8
3
↑i ↑j
4
5 6
7 8
↑i
↑j
1
Aufwand pro Ebene:
n
n
n−1
1
n Ebenen
n
1
n−2
n−1
2
1
1
Rekursionsbaum
35
1
2
n
X
Tmax (n) = c2 · (
i + n)
i=2
n(n + 1)
= c2 · (
− 1 + n)
2
n2 3
= c2 · ( + n − 1)
2
2
= Θ(n2 )
Für die Rechenzeit T(n) gilt:
c1 · n log n ≤ T (n) ≤ c2 · n2
Idee zur Verhinderung des Worst Case: Liste vorher zufällig permutieren.
Begründung: Die Wahrscheinlichkeit für das Erzeugen einer sortierten Liste ist sehr klein. 101n
falls nur 10 Zahlen erlaubt sind.
Allgemeine Wahrscheinlichkeit: M1n für M unterschiedliche zu sortierende Werte und n verschiedene Zahlen in der Liste.
Beispiel 3.3 32 Bit Integer Zahlen: M = 232 , n = 106 ,
1
Mn
=
1
6
(232 )10
=
1
6
232·10
Folgerung: Die Wahrscheinlichkeit, dass ein randomisiertes Quicksort den Worst-Case trifft
ist sehr klein. Aber die zufällige Permutation der Liste vor dem Sortieren kostet Rechenzeit.
Daher:
Zufällige Wahl des Pivotelements
ersetze in Partition x = A[p] durch x = A[random (p,r)]
oder Ersetzung von Partition (A,p,r) durch:
Random-Partition(A,p,r)
i=Random (p,r)
vertausche A[p] mit A[i]
return Partition (A,p,r)
Random (p,r) liefert zufällig mit konstanter Wahrscheinlichkeit eine Zahl aus {p, p+1, . . . ,r}.
Bemerkung: Durch Randomisierung gibt es keine Eingabe mehr, für die der Algorithmus
immer Worst-Case Verhalten zeigt.
Average-Case-Analyse: Berechnung der mittleren Laufzeit des Algorithmus z.B. Quicksort
auf einer repräsentativen Menge von Eingaben.
Beispiel 3.4 Die Average-Case-Analyse für Quicksort ist sehr schwierig. Daher wird hier der
ungünstige Fall eines konstanten Aufteilungsverhältnisses 1 : m am Beispiel 1 : 9 behandelt.
36
n
9n/10
1n/10
81n/100
9n/100
9n/100
1n/100
729n 81n
1000 1000
81n
9n
1000 1000
81n
9n
1000 1000
9n
1n
1000 1000
1 dr
( 10
) ·n=1
9 dl
) ·n=1
( 10
dl · log
9
+ log n = 0
10
log n
log 10
9
dl =
T (n) <
Tiefe k =
log n
log 10
9
c
· n log n
log 10
9
≈ 21, 8 · log10 n
Aufwand auf jeder Ebene ≤ n ⇒
im Best-Case auch n · log n ist, gilt:
T (n) = O(n · log n). Da die komplexität von Quicksort
Satz 3.3 Quicksort besitzt im Average-Case die Komplexität T (n) = Θ(n · log n)
3.3
Sortieren mit Bäumen (Heapsort)
Beispiel 3.5
1
16
i:
A[i] :
2
14
3
10
4
8
5
7
6
9
7
3
8
2
9
4
10
1
Darstellung von A als Baum:
16
14
8
2 8
4
4 9
1
2
10
7
5
9
6
3
3
7
1 10
Keine neue Datenstruktur nötig, sondern nur Funktionen parent, left, right mit den Eigenschaften
37
parent(i) = b 2i c
left(i) = 2i
right(i) = 2i + 1
(Vorgänger)
(linker Nachfolger)
(rechter Nachfolger)
Definition 3.4 Ein Array mit den Funktionen left, right, parent heisst heap, wenn gilt
A[parent(i)] ≥ A[i]
Definition 3.5 Die Höhe eines Knotens i in einem Baum ist gleich der Zahl der Kanten
im längsten Pfad von i zu einem Blattknoten. Die Höhe des Baumes ist gleich der Höhe
des Wurzelknotens.
Der folgende Algorithmus verwandelt einen Binärbaum in einen Heap unter der Voraussetzung,
dass beide Unterbäume schon Heaps sind.
Heapify(A,i)
vertausche A[i] mit seinem größten Nachfolger
A[largest] falls A[largest] > A[i]
Heapify (A,largest)
Beispiel 3.6
1
16 P
"" PPPP
"
2
4 bb
b
5
4
14
7 %e
%8 e
9 10
2
8 1 3
10 %e
%6 e
7
9 3 1
16
P
"" PPPP
"
2
14 bb
b
5
4
4
7 %e
%8 e
9 10
2
8 1 3
10 %e
%6 e
7
9 3 1
16
P
"" PPPP
"
Der Algorithmus
Heapify(A,i)
l = Left(i)
r = Right(i)
if l ≤ heapsize(A) AND A[l] > A[i]
then largest = l
else largest = i
if r ≤ heapsize(A) AND A[r] > A[largest]
then largest = r
if largest 6= i
then vertausche A[i] mit A[largest]
Heapify(A, largest)
38
2
14 bb
b
5
4
8
7 %e
%8 e
9 10
2
4 1 3
10 %e
%6 e
7
9 3 Laufzeit von heapify
Vergleich von A[i] mit A[left(i)] und A[right(i)]: konstante Zeit= Θ(1)
Rekursion
Die maximale Zahl von Knoten in einem der Unterbäume ist gleich 32 n, wenn n = Zahl der
Unterknoten in i.
Rekurrenzrelation
2
T (n) ≤ T ( n) + Θ(1)
3
Das Auflösen der Rekurrenzrelation erfolgt mit Hilfe des Mastertheorems:
Satz 3.4 (Mastertheorem) Seien a ≥ 1, b > 1 Konstanten und f : R+ → R+ , T : R+ → R+
Funtionen mit
T (n) = aT (n/b) + f (n)
wobei n/b für die ganzzahlige Division (bn/bc
beschränkt werden durch


Θ(nlogb a )
falls






 Θ(nlogb a log n) falls
T (n) =




Θ(f (n))
falls




oder dn/be) steht. Dann kann T (n) asymptotisch
∃ε>0 : f (n) = O(nlogb a−ε )
f (n) = Θ(nlogb a )
∃ε>0 : f (n) = Ω(nlogb a+ε ) und
∃c<1 ∃n0 ∀n≥n0 : af (n/b) ≤ cf (n)
Für Heapsort gilt T (n) ≤ T ( 32 n) + Θ(1). Für den Worst Case gilt
n
Tmax (n) = 1 · Tmax
+c
3/2
Für die Anwendung des Mastertheorems gilt dann also a = 1, b = 32 , f (n) = 1 sowie
nlogb a = n
log 3 1
2
=1
Es ist der zweite Fall anwendbar, denn f (n) = Θ(nlogb a ). Also gilt für heapify
Tmax (n) = Θ(1 · log n) = Θ(log n).
Beispiel 3.7 Anwendung des Master-Theorems auf Quicksort (Best Case):
T (n) = 2 T ( n2 ) + c · n
a = 2, b = 2, f (n) = c · n
nlogb a = nlog2 2 = n
f (n) = Θ(n)
⇒ 2. Fall: T (n) = Θ(n · log n)
Beispiel 3.8 wie oben, jedoch mit anderem f (n):
39
T (n) = 2T ( n2 ) + c · log n
a = 2, b = 2, f (n) = c · log n
nlogb a = n
f (n) = c · log n = O(n(1−ε) )
⇒ 1. Fall: T (n) = Θ(n)
3.3.1
Erzeugen eines Heap
Build-Heap(A)
length(A)
for i = b
c downto 1
2
do heapify(A,i)
Beispiel 3.9
1
4 PPP
PP
2
3
1
4 PPP
PP
2
1
4 "PPP
"
PP
"2
3
1
10 bb
b
%%ee
4
5 6 7
14 16 9 3 %e
%8 e
9 10
2 8 7 3
1 3 HH
ee
HH
4
5 6 7
16 9 10 2 %@@
%
8 9 10
14 8 7 1 3 bb
ee
b
4
5 6 7
14 16 9 10 %e
%8 e
9 10
2 8 7 1
4P
"
PP
"
PP
" 2
3
16
10 bb
%e
b
5 %6 e
7
4
14
7
9
3 %e
%8 e
9 10
2 8 1 1
16
P
"" PPPP
" 2
3
14
10 bb
%e
b
4
5 %6 e
7
8
7
9
3 %e
%8 e
9 10
2 4 1 Analyse
obere Schranke
Jeder der Θ(n) Aufrufe von heapify kostet O(log n) Zeit. Also gilt
=⇒ T (n) = O(n log n).
bessere Schranke
Die Laufzeit von heapify hängt von der Höhe des Knotens im Baum ab. Die meisten Knoten
haben sehr niedrige Höhe!
(Zahl der Knoten auf Höhe h) ≤ d
40
n
2h+1
e
Die Laufzeit von heapify für Knoten der Höhe h wächst linear mit h. Also Theapif y (h) = O(h) =
O(log(Anzahl Knoten im Unterbaum))


blog nc l
blog nc
m
X
X h
n
 = O(2n) = O(n)
n
T (n) ≤
·
O(h)
=
O
h+1
h
2
2
h=1
h=1
Die vorletzte Gleichung gilt weil
∞
1
X
h
2
=
1 2 = 2,
h
2
(1
−
)
2
h=1
was man in der Formelsammlung findet.
3.3.2
Der Heapsort - Algorithmus
Voraussetzung: Build-Heap setzt maximales Element an die Wurzel, d.h. in A[1]
Idee
Wiederhole folgende Schritte bis der Heap nur noch aus einem Element besteht: 1.) vertausche
A[1] mit A[n]
2.) lösche A[n] aus dem Heap
3.) Heapify (A,1)
Beispiel 3.10
14
8
4
2 8
10
2
10
4
7
1 9
1
5
9
3
6
8
3
7
16 10
4
2 8
i
4
10 8
5
1
2
4
10 8
4
14 9
3
1
3
6
8
3
7
16 10
6
9
7
10 8
10 8
5
16 10
4
2
14 9
8
6
3
1
9
7
4
10 8
4
3
7
14 9
5
1
3
6
2
7
16 10
4
14 9
4
3
i
5
8
3
6
2
9
7
16 10
8
5
6
3
2
9
7
4
10 8
Algorithmus
Heapsort(A)
Build-Heap(A)
for i= length(A) downto 2
do vertausche A[1] mit A[i]
heapsize(A)= heapsize(A)-1
Heapify(A,1)
4
14 9
8
3
6
9
7
16 10
1
i
16 10
41
7
i
3
5
3
i
4
14 9
1
2
1
2
7
1
10 8
2
1
2
1
2
1
2
7
1
4
1
i
4
i
16 10
3
i
5
7
3
2
14 9
7
1
2
4
9
i
8
7
9
2
4
14 9
1
1
2
3
7
16 10
5
8
6
3
9
7
Analyse
Build-Heap: T (n) = O(n)
for-Schleife: (n − 1) mal Heapify mit T (n) = O(log n) und Vertauschen mit O(1)
T (n) ≤ c1 · n + (n − 1) · [c2 · log n + c3 ]
= c2 · n log n + (c1 + c3 ) · n − c2 log n − c3
|
{z
}
vernachlässigbar für n → ∞
= O(n log n)
3.3.3
Priority-Queues als Anwendung der Heap-Struktur
Bei der Verwaltung von Warteschlangen mit Aufträgen unterschiedlicher Priorität muß als
jeweils nächster Auftrag immer ein Auftrag mit höchster Priorität ausgewählt werden. Dies
kann zum Beispiel erreicht werden, indem man die Aufträge in einer sortierten Liste speichert.
Allerdings ist dann die Komplexität zum Speichern der Aufträge in der Liste linear in der Länge
n.
Verwendet man dagegen einen Heap zur Verwaltung der Warteschlangen von Aufträgen, so ist
die Komplexität zum speichern und holen von Aufträgen im Heap logarithmisch in n.
Einfügen eines Elements x im Heap
1.) neues Blatt erzeugen
2.) Pfad vom Blatt zur Wurzel durchsuchen und x an der richtigen Stelle einfügen.
Algorithmus
Heap-Insert(A, key)
heapsize(A) = heapsize(A)+1
i=heapsize(A)
while i>1 AND A[parent(i)] < key
do A[i] = A[parent(i)]
i=parent(i)
A[i]=key
Beispiel 3.11 Anwendung von Heap-Insert zum Einfügen des Elements X = 15
42
1
16
X
XXX
""
XXX
" 1
16
P
"" PPPP
" 2
14 bb
b
5
4
8
7 %e
%8 e
9 10
2
4 1 3
10 %e
%6 e
7
9 3 2
14 b
bb
5
4
7 8 %e
@
@ %8 e
9 10 11
1
2
4
X 3
10 %e
%6 e
7
9 3 1
16
X
XXX
""
XXX
" 3
2
15
10 b
%e
bb
%6 e
7
4
5
9 3 14 8 @
%e
%8 e
11
9 10 @
2 4 1 7 1
16
X
XXX
""
XXX
"
3
2
X
10 b
%e
bb
%6 e
7
4
5
3
9
8
14
%e
@
%8 e
9 10 @
11
2 4 1 7 Analyse
T (n) = O(log n).
3.4
Sortieren in linearer Zeit
Unter ganz bestimmten Bedingungen ist Sortieren sogar in linearer Zeit möglich, wie man an
folgendem Beispiel erkannt.
Idee
Wenn alle in der Liste A vorkommenden Sortierschlüssel aus einer bekannten endlichen Menge
sind, kann man durch einfaches Abzählen der Häufigkeiten aller in A vorkommenden Elemente
eine Tabelle S der Häufigkeiten erstellen. Danach wird die Liste A überschrieben mit den
Elementen in der richtigen Reihenfolge (siehe Beispiel).
Beispiel 3.12 Zu sortieren sei A = (2, 1, 4, 5, 4, 7, 3, 1, 4, 4, 1). Als Häufigkeitstabelle S erhält
man
Sortierschlüssel
Häufigkeit
1 2 3 4 5 6 7
3 1 1 4 1 0 1
Daraus erhält man einfach die sortierte Liste A = (1, 1, 1, 2, 3, 4, 4, 4, 4, 5, 7).
Komplexität
Mit m = |S| entsteht beim Abzählen ein linearer Aufwand und beim Zurückschreiben auch und
man erhält
T (n) = c1 · n + c2 · m + c3 · n
= Θ(n + m)
43
Dieser Algorithmus ist besonders interessant, wenn die Zahl m der verwendeten Sortierschlüssel
klein ist, zum Beispiel beim Sortieren einer großen Adressdatei nach Postleitzahlen.
Das hier verwendete Verfahren setzt voraus, dass die Menge der verwendeten Schlüssel bekannt
ist. Daher ist der aufwändige Vergleichen der Sortierschlüssel nicht nötig. Ist diese Voraussetzung jedoch nicht erfüllt und auch sonst kein Zusatzwissen über die zu sortierenden Daten
vorhanden, so ist Sortieren in linearer Zeit nicht möglich und man kann für die Komplexität
folgende untere Schranke angeben:
Satz 3.5 Wenn ein Sortieralgorithmus für beliebige Listen nur mit Vergleichen und Kopieren
arbeitet und keine Zusatzinformation über die Liste erhält, dann gilt:
T (n) = Ω(n log n)
3.5
Hashing
Egal, welchen Suchbegriff man eingibt, moderne Suchmaschinen finden sehr schnell eine Antwort. Dies wird ermöglicht durch eine geeignete Datenstruktur, einen sogenannten Index. Eine
Möglichkeit, solch einen Index zu realisieren ist die Speicherung der Daten in einer Baumstruktur, wie wir sie bei der Verwaltung von priorisierten Warteschlangen in Form des Heap
kennengelernt haben. In Datenbanken werden oft B-Bäume verwendet.
Wir werden hier mit dem sogenannten Hashing ein Verfahren vorstellen, das im Mittel einen
Zugriff in konstanter Zeit erlaubt. Das heißt, die Zugriffszeit hängt nicht von der Datenmenge
ab.
Welche bekannte Datenstruktur erlaubt konstante Zugriffszeit?
3.5.1
Direkte Adressierung
Versuchen wir, für eine Suchmaschine einen Index unter Verwendung eines Array zu erzeugen.
Zuerst müssen die eingegebenen Strings auf numerische Schlüssel (natürliche Zahlen) abgebildet
werden. Bei einem erlaubten Alphabet mit 80 Zeichen (deutsche Klein-, Großbuchstaben, Ziffern
und 10 Sonderzeichen) werden diese nummeriert von 0 bis 79 und dann wird die Zeichenkette
z0 , . . . zl kodiert als Schlüssel
k = nl · 80l + nl−1 · 80l−1 + . . . + n1 · 80 + n0 · 1,
wobei ni die Nummer des i-ten Eingabezeichens ist. Wenn die Kleinbuchstaben die Nummern
0 bis 30 (inkl. Umlaute und ß) erhalten, würde zum Beispiel die Eingabe ,,hallo” kodiert als
o
l
l
a
h
14 · 804
+ 11 · 803 + 11 · 802 + 0 · 801 + 7 · 800 =
573440000 + 5632000 + 70400 +
0
+
7
= 579142407
Mit einer derartigen Nummer kann dann direkt ein Arrayelement angesprochen werden in der
Tabelle T in Abbildung 3.1.
Wir beschränken die Strings als Eingabe für die Suchmaschine auf eine Länge von 20 Zeichen.
Wieviele unterschiedliche Eingaben sind hier möglich?
.....................................................................................................................................
Offenbar wird hierbei zu viel Speicherplatz benötigt.
44
Tabelle T
Schlüssel
Daten
0
1
Schlüsseluniversum
U
0
2
3
4
3
4
8
7
verw.
Schlüssel
K
1
2
5
1
6
5
5
6
7
6
9
8
9
7
Abbildung 3.1: Direkte Adressierung über Array T .
3.5.2
Hash-Tabellen
Bei der direkten Adressierung muss die Tabelle Θ(|U |) Elemente haben, also gleich groß sein
wie das Schlüssel-Universum. Bei Verwendung einer sogenannten Hash-Tabelle kann viel Speicherplatz gespart werden. Die Größe der Tabelle reduziert sich Θ(|K|) Elemente, wobei K die
Menge der tatsächlich verwendeten Schlüssel ist.
Idee: Hash-Funktion bildet Schlüssel ab auf Indizes der Tabelle
Hash-Tabelle
h(k1 )
Schlüsseluniversum U
h(k4 )
verw.
Schlüssel
K
k1
k4
h(k3 ) = h(k2 )
k3
k2
Abbildung 3.2: Adressierung über Hash-Tabelle.
Definition 3.6 Eine Hashfunktion h bildet die Schlüssel des Universums ab auf eine (viel
kleinere) Menge {0, 1, . . . , m − 1} von Hash-Werten. Man nennt h(k) den Hash-Wert des
Schlüssels k.
Nachteil: Kollisionen sind nicht vermeidbar, s.o.: h(k3 ) = h(k2 ). Warum?
3.5.3
Hash-Funktionen
Eigenschaften von guten Hash-Funktionen:
•
•
•
•
Deterministisch. Warum?
Ähnliche Schlüssel werden nicht auf ähnliche Hash-Werte abgebildet
Möglichst wenige Kollisionen
Aber: Kollisionen sind möglich!
45
Modulo m:
h(k) = k mod m
Beispiel: k = 67, m = 16:
h(67) = 67 mod 16 = 3
Problem, wenn m = 2p : Dann berechnet h(k) die p niederwertigsten Bits von k.
Gute Wahl von m: Primzahlen nicht zu nahe bei einer Zweierpotenz
Die Multiplikationsmethode:
Zuerst wird k multipliziert mit einer Konstanten 0 < A < 1. Dann werden die Nachkommastellen des Ergebnisses mit m multipliziert. Von diesem Ergebnis wird dann der ganzzahlige Anteil
genommen:
h(k) = bm(kA mod 1)c
√
D. Knuth empfiehlt A = ( 5 − 1)/2 ≈ 0.61803.
Beispiel: k = 674301, A = 0.61803, m = 1000:
√
h(k) = b1000 · (674301 · ( 5 − 1)/2 mod 1)c = b1000 · (416740.93664804 mod 1)c
= b1000 · 0.93664804c = b936.64804c = 936
3.5.4
Kollisionsauflösung durch Verkettung
Hash-Tabelle
k1
Schlüsseluniversum U
verw.
Schlüssel
K
k1
k5
k4
k4
k5
k3
k2
k3
k2
Abbildung 3.3: Adressierung über Hash-Tabelle.
Analyse
Definition 3.7 Sei T eine Hash-Tabelle mit m Feldern, in der m Elemente gespeichert sind,
so wird α = n/m als Auslastung der Tabelle bezeichnet.
Wir nehmen im Folgenden an, dass die verwendete Hash-Funktion jeden vorkommenden Schlüssel
mit gleicher Wahrscheinlichkeit auf eines der Felder der Tabelle abbildet. Diese Annahme wird
als einfaches uniformes Hashing bezeichnet.
46
Satz 3.6 Werden in einer Hash-Tabelle die Kollisionen durch Verkettung aufgelöst, so kostet
eine Suche im Mittel Θ(1+α) Rechenzeit unter den Annahme des einfachen uniformen Hashing.
Wenn die Zahl der Felder der Hash-Tabelle proportional zur Zahl der zu speichernden Elemente
wächst, gilt n = O(m) und
α = n/m = O(m)/m = O(1).
Also folgt für die Zeit zum Suchen im Mittel Θ(1).
3.5.5
Offene Adressierung
Bei dieser alternativen Methode der Kollisionsauflösung werden alle Elemente direkt in der
Hash-Tabelle selbst gespeichert. Im Fall von Kollisionen wird ein neuer alternativer Index berechnet, und dies wird so lange wiederholt, bis eine freie Speicherzelle gefunden wird.
Diese Methode hat den Vorteil, dass keine Zeiger benötigt werden, was etwas Speicherplatz
spart. Allerdings kann es hier passieren, dass die Hash-Tabelle voll wird. α kann hier also nicht
größer als eins werden.
Als Literatur empfehle ich für dieses Kapitel [9].
47
Kapitel 4
Algorithmen auf Graphen
4.1
Einführung
Graphen werden immer dann verwendet, wenn man eine Menge von Objekten und Relationen
zwischen diesen Objekten darstellen und/oder untersuchen will. Verkehrsnetze werden z.B. oft
als Graph modelliert:
48
Bay
F
N
Ma
Ka
Reg
Ul
S
Pa
Li
M
Ros
Rv
Ba
Sal
Z
Be
Inn
Definition 4.1 Ein gerichteter Graph ist ein Paar G = (V, E), bestehend aus einer endlichen Knotenmenge V (engl. vertex) und einer zweistelligen Relation E ⊆ V × V . Die
Elemente von E werden Kanten (engl. edge) genannt.
G0 = (V 0 , E 0 ) ist ein Teilgraph von G = (V, E), wenn V 0 ⊆ V und E 0 ⊆ E.
Beispiel 4.1 folgendes sind Graphen:
•
•
•
V1 = Menge aller Städte in Süddeutschland
E1 = {(x, y) ∈ V1 × V1 |es gibt eine direkte Straßenverbindung von x nach y}
V2 = Menge der Einwohner von Ravensburg
E2 = {(x, y) ∈ V2 × V2 |x kennt y}
V3 = Menge der Einwohner von Ravensburg
E3 = {(x, y) ∈ V3 × V3 |x ist verheiratet mit y}
G3 = (V3 , E3 ) ist Teilgraph von G2 = (V2 , E2 )
Zur graphischen Darstellung von Graphen werden Knoten durch Punkte und jede Kante (x, y)
durch einen Pfeil von x nach y dargestellt.
Beispiel 4.2
c
V = { a, b, c, d, e, f, g, h }
E = { (a, d), (d, a), (a, b),
(b, c), (c, a), (b, e),
(a, e), (f, g), (f, f ) }
f
a
h
b
d
e
g
Definition 4.2 Falls für jede Kante e = (x, y) ∈ E eines Graphen G = (V, E) auch die
Kante e0 = (y, x) ∈ E ist, so heißt G ungerichteter Graph. Alle anderen Graphen sind
gerichtet. Beim Zeichnen von ungerichteten Graphen wird für jedes verbundene Knotenpaar
nur eine Linie ohne Pfeile gezeichnet.
49
Beispiel 4.3 G = (V, E) mit V = Menge von Städten in Süddeutschland,
E = {(x, y) ∈ V1 × V1 | es gibt eine direkte Straße von x nach y (keine Einbahnstraße!)}
Definition 4.3
• Sei G = (V, E) ein Graph. Ein Pfad (oder Weg) von Knoten x ∈ V nach y ∈ V ist eine
Folge (x = a0 , . . . , a` ) von Knoten mit (ai , ai+1 ) ∈ E. ` ist die Länge des Weges von x
nach y.
• In einem einfachen Pfad kommt jeder Knoten höchstens einmal vor.
• Ein Pfad der Länge ` ≥ 1 von x nach x heißt Kreis.
• Ein Kreis, in dem außer dem Startknoten kein Knoten mehr als einmal vorkommt, heißt
Zyklus.
• Ein gerichteter Graph G = (V, E) heißt zyklenfrei oder gerichteter azyklischer Graph
(engl. directed acyclic graph (DAG)), wenn er keine Zyklen enthält.
• (x, x) und (x, y, x) heißen triviale Zyklen. Ein ungerichteter Graph ist zyklenfrei, wenn
es zwischen jedem Paar von Knoten (x, y) höchstens einen Pfad (ohne triviale Zyklen)
gibt.
• Die Zahl der Kanten, die von einem Knoten v ausgehen oder in ihm enden heißt Grad
des Knotens. Er wird mit deg(v) bezeichnet. Bei ungerichteten Graphen wird jede Kante
nur einfach gezählt.
Beispiel 4.4 Für den Graphen aus Beispiel 4.2 gilt:
• (b, c, a, d, a) ist ein Pfad von b nach a.
• (c, a, b, e) ist ein einfacher Pfad von c nach e.
c
• (f, f, f, g) ist ein Pfad.
f
a
• Er enthält u.a. den Kreis (a, b, c, a, d, a).
• ({a, b, c, e}, {(a, b), (b, c), (b, e), (a, e)}) ist ein azyklischer Teilgraph von G.
h
b
• (a, b, c, a) und (a, d, a) und (f, f ) sind die einzigen Zyklen.
d
e
g
• deg(a) = 5, deg(b) = deg(f ) = 3, deg(h) = 0.
Definition 4.4
• Ein ungerichteter Graph G heißt zusammenhängend, wenn es zwischen je zwei beliebigen
Knoten einen Weg gibt.
• Ein zusammenhängender zyklenfreier Graph ist ein Baum.
• Eine Menge paarweise nicht zusammenhängender Bäume heißt Wald.
• Ein Kreis heißt Eulerkreis, wenn er jede Kante des Graphen genau einmal durchläuft.
4.2
Eulerkreise
Beispiel 4.5 Die Stadt Königsberg (heute Kaliningrad, Rußland) hatte folgenden Verlauf des
Flusses Pregel mit sieben Brücken. Leonhard Euler fragte sich 1736, ob es einen Rundweg durch
50
die Stadt gibt, auf dem jede Brücke genau einmal überquert wird. Der zugehörige Graph ist
rechts angegeben.
C
A
D
B
Satz 4.1 Ein ungerichteter zusammenhängender Graph enthält genau dann einen Eulerkreis
wenn der Grad jedes Knotens gerade ist.
Beweis: (Beweisskizze) “⇒”: Wird ein Knoten besucht, so über eine ankommende und eine
abgehende Kante. Bei jedem Besuch eines Knoten auf dem Eulerkreis werden also zwei Kanten
“verbraucht”.
“⇐”: Sei G ein Graph in dem alle n Knoten geraden Grad haben. Weil der Graph zusammenhängend ist, muss der Grad aller Knoten mindestens 2 sein. Dann besitzt der Graph also
mindestens n Kanten und damit einen Zyklus.
Nun konstruieren wir einen Eulerkreis mit folgendem Algorithmus: Wir starten bei einem Knoten und traversieren den Graphen so lange bis ein Knoten vorkommt, der schon besucht wurde.
Nun ist ein Kreis C gefunden. Alle Kanten von C werden nun gelöscht. Im verbleibenden Graphen wird dieses Verfahren fortgesetzt, bis alle Kanten besucht sind. Nun ist der Graph in
disjunkte Zyklen zerlegt. Diese lassen sich leicht zu einem Eulerkreis verbinden. Haben zwei
Kreise einen Knoten gemeinsam, so starten wir auf einem Kreis bis wir einen gemeinsamen
Knoten V finden, verfolgen dann den zweiten Kreis von V bis wieder zu V und traversieren
dann den Rest des ersten Kreises. Wir haben nun einen Kreis der beide Kreise zu einem neuen
verbindet. Dieses Verfahren wird rekursiv fortgesetzt, bis alle alle Zyklen zu einem Eulerkreis
verbunden sind (siehe Abbildung).
2
Der im Beweis skizzierte Algorithmus arbeitet in linearer Zeit. Das heißt, bei einem Graphen
mit geradem Grad und m Knoten gilt für die Rechenzeit T (m) = Θ(m).
51
4.3
4.3.1
Datenstrukturen für Graphen
Adjazenzmatrix
Rv Ul M S Ka Z Ba Be F Ma N
Rv
x x x
x x
Ul x
x x
x
M x x
x
S x x
x
x x x
Ka
x
x
x
Z x
x x
Ba x
x x
x
Be
x x
F
x
x x
Ma
x x
x
x
N
x x x
x x
Die Matrix ist symmetrisch. Warum?
4.3.2
N
Ma
Ka
Ul
S
M
Rv
Ba
Z
Be
Adjazenzlisten
a
b
c
d
e 0
f
g 0
h 0
4.3.3
F
b
c
a 0
a 0
e
e 0
f
g 0
c
d 0
f
a
h
b
d
g
e
Liste von Adjazenzlisten
a
b
e
b
c
e 0
c
a 0
d
a 0
d 0
c
f
a
f
h
b
e 0
f
d
g 0
g 0
h 0
0
52
e
g
4.3.4
Vergleich der drei Datenstrukturen
Vorteile
Berechnung der Inzidenz mit
O(1)
Speicherplatz = O(n + m)
Adjazenzmatrix
Adjazenzlisten
Liste von Adjazenzlisten
Nachteile
Speicherplatz und Initialisierung teuer, beide O(n2 )
Berechnung der Inzidenz mit
O(m)
Berechnung der Inzidenz mit
O(n + m), Knotensuche mit
O(n)
Speicherplatz = O(n +
m), Knoten können einfach
gelöscht oder hinzugefügt
werden
n = Knotenzahl, m = Kantenzahl
4.4
Kürzeste Wege
Definition 4.5 Ein gewichteter Graph (auch bewerteter Graph) ist ein Tripel G =
(V, E, w), bestehend aus einem Graphen (V,E) zusammen mit einer Gewichtungsfunktion w : E → R+ , die jeder Kante eine relle Zahl zuordnet. Die Länge eines Weges
(x = a0 , . . . , a` ) ist
`−1
X
w(ai , ai+1 ).
i=0
Beispiel 4.6 Entfernungstabelle einiger süddeutscher Städte
RV Ul M S Ka
Rv 0 86 178 195 –
Ul
0 123 107 –
M
0
–
–
S
0 64
Ka
0
Z
Ba
Be
F
Ma
N
Z
91
–
–
–
–
0
Ba Be F Ma
180 –
–
–
–
–
–
–
–
–
–
–
–
– 210 135
191 –
– 67
85 120 –
–
0 91 –
–
0
–
–
0 85
0
N
–
171
170
210
–
–
–
–
230
230
0
F
230
85
230
Ma
Ka
107
S
64
210
171
123
170
86
180
Be
Ul
195
191
Ba
N
210
67 135
85
91
120
Z
91
RV
178
M
Wegen der Symmetrie kann die untere Dreiecksmatrix weggelassen werden.
Definition 4.6 Ein Baum T = (V, E 0 ), der alle Knoten V eines Graphen G = (V, E) enthält,
heißt minimal aufspannender Baum, wenn die Summe aller Kantengewichte minimal ist,
d.h. wenn
X
E 0 = argminX⊂E
w(e).
e∈X
53
4.4.1
Der Kruskal-Algorithmus
Satz 4.2 (Kruskal-Algorithmus) Für einen ungerichteten, zusammenhängenden, bewerteten Graphen findet der folgende Algorithmus einen minimal aufspannenden Baum T :
1. Setze T = {}
2. Sortiere die Kanten nach ihrem Gewicht.
3. Wähle aus den noch nicht gewählten Kanten die mit dem kleinsten Gewicht. Falls diese
Kante in T keinen Zyklus erzeugt, erweitere T um diese Kante. Wiederhole Schritt 3 bis
alle Kanten verbraucht sind.
Beispiel 4.7 Wir wenden nun den Kruskal-Algorithmus auf obiges Beispiel an und erhalten
folgenden minimal aufspannenden Baum:
F
230
85
230
Ma
210
67 135
Ka
107
S
64
171
123
170
86
180
Be
Ul
210
195
191
Ba
N
85
91
120
Z
91
RV
178
M
Satz 4.3 Die Laufzeit des Kruskal-Algorithmus ohne Sortieren für einen Graphen mit n Knoten
und m Kanten ist O(m + n log n). Mit optimierten Datenstrukturen ist (ohne Sortieren) sogar
eine fast lineare Komplexität erreichbar [9].
54
Definition 4.7 Gegeben sei ein bewerteter Graph G = (V, E, w).
• Beim Single Pair Shortest Path Problem (SPP) ist ein kürzester Weg von einem
Knoten a zu einem Knoten b gesucht.
• Beim Single Source Shortest Path Problem (SSP) sind kürzeste Wege von einem
Knoten a zu allen anderen Knoten b ∈ V gesucht.
• Beim All Pairs Shortest Path Problem (APSP) ist für jedes Paar von Knoten (a, b)
ein kürzester Weg gesucht.
4.4.2
Der Dijkstra-Algorithmus
Wir geben nun einen bekannten Algorithmus für das SSP an:
Satz 4.4 (Dijkstra-Algorithmus) Für einen bewerteten Graphen G = (V, E, w) und einen
gegebenen Knoten a findet der folgende Algorithmus einen aufspannenden Baum, der das SSPProblem für den Knoten a löst. Hierbei ist
δ(S) = {k ∈ V \S|k ist mit einem Knoten aus S direkt verbunden.}
Dijkstra(G,a)
Setze S = {a}, F = {}
while S 6= V do
suche in δ(S) den Knoten v mit dem
kürzesten Pfad (a, . . . , u, v) von a zu v.
S = S ∪ {v}
F = F ∪ {(u, v)}
Beispiel 4.8 Dijkstra-Algorithmus mit a = Rv:
F
230
85
230
Ma
64
S
107
Be
91
N
120
Z
91
Knoten in S:
Knoten in δ (S):
171
170
123
M
178
85
Ul
86
180
Ba
210
195
191
Ka
67 135 210
RV = a
S
55
Kanten in F:
F
230
85
230
Ma
210
67 135
Ka
107
S
64
210
171
123
170
86
180
Be
Ul
195
191
Ba
N
85
91
120
Z
91
RV
178
M
Satz 4.5 Die Laufzeit des Dijkstra-Algorithmus O(m + Cn), wobei C eine Konstante ist, die
vom maximalen Kantengewicht abhängt [9].
4.4.3
•
•
Anwendungen
“Städteverbindungen” der Bahn
Routing im Internet: Router berechnet die beste Route zum nächsten Backbone-Knoten
über einen aufspannenden Baum, den er mit dem Dijkstra-Algorithmus erstellt.
Definition 4.8 Ein Hamilton-Kreis (hamiltonian circle) in einem Graphen G ist ein geschlossener Weg, in dem jeder Knoten aus G genau einmal vorkommt. Eine Clique in einem
(ungerichteten) Graphen ist ein vollvernetzter Teilgraph.
4.5
Das Problem des Handlungsreisenden
(traveling salesman problem, TSP)
gegeben: Menge von Städten s1 , . . . , sn und eine Entfernungstabelle w mit wij = |si − sj | =
Entfernung zwischen Stadt i und Stadt j.
gesucht: Eine Permutation (Vertauschung) Π von (s1 , . . . , sn ), so dass
n−1
X
wΠ(i),Π(i+1) + wΠ(n),Π(1)
i=1
56
minimal ist. Es ist also eine Route gesucht, die jede Stadt genau einmal besucht und am Ende
wieder im Ausgangspunkt endet.
Definition 4.9 Eine bijektive Abbildung einer Menge M auf sich selbst heißt Permutation.
Beispiel 4.9 Eine Permutation der Menge {1, . . . , 6}
i
Π(i)
4.5.1
1
4
2
2
3
1
4
3
5
5
6
6
Ein praktisches Ergebnis
TSP-Tour durch mehr als 15112 deutsche Städte:
David Applegate, Robert Bixby und William Cook von der Rice-Universität in Houston (Texas) sowie Vasek Chvatal von der
Rutgers-Universität in New Brunswick (New Jersey), 1998, siehe: www.tsp.gatech.edu
57
4.5.2
Der Nearest-Neighbour-Algorithmus
Idee
Starte in einem Knoten und wähle als nächsten immer den mit dem geringsten Abstand.
Algorithmus
NN TSP(w)
For i=1 To n Do
tour[i]=i
tour[n+1]=1
For i=2 To n-1 Do
next=argmin{w[i-1,j] | j ∈ tour[i...n]}
vertausche tour[i] mit tour[next]
Return(tour)
Komplexität
T (n) = Θ(n2 )
4.5.3
Der Greedy - Algorithmus
Idee
“Greedy” heißt auf deutsch “gierig”. Dieses Attribut trifft auf den Algorithmus sehr gut zu,
denn er greift gierig immer nach der “besten” Kante ohne auf das Gesamtresultat zu schauen.
Algorithmus
• sortiere alle Kanten in der Liste K
• Sei (v, v 0 ) die Kante aus K mit kleinstem Gewicht. Falls deg(v) < 2 und deg(v 0 ) < 2 und
(v, v 0 ) schließt keinen Zyklus mit < n Knoten, erweitere die Tour um (v, v 0 ) und lösche (v, v 0 )
aus K.
• Wiederhole 2. bis für alle v ∈ V deg(v) = 2.
Komplexität
T (n) = Θ(n2 log n)
Beispiel 4.10 Vergleich von 2 Heuristiken mit der optimalen Lösung an einem ganz einfachen
Beispiel:
a
6
1
b
3
f
5
4
e
a
c
2
d
3
Greedy Algorithmus
b
f
4
2
e
1
6
a
5
c
b
f
e
c
d
d
Nearest Neighbour (Start in d)
58
optimale Tour
Beispiel 4.11 Vergleich von 3 Heuristiken mit der optimalen Lösung:
4.5.4
Optimaler Algorithmus Optimal TSP
Idee
berechne für jede Tour
Pn
i=1
wtour[i],tour[i+1] und wähle eine Tour mit minimalem Wert.
Komplexität
Ohne Beschränkung der Allgemeinheit ist die erste Stadt frei wählbar. Für die zweite Stadt
ergeben sich n − 1 Möglichkeiten, für die dritte n − 2 Möglichkeiten . . . Für die n-te Stadt: eine
Möglichkeit. Insgesamt sind dann also ·(n − 1)! Routen möglich.
Für jede Route muss dann noch deren Länge berechnet werden und am Ende die kürzeste
ermittelt werden, was bei naiver Implementierung einen zusätzlichen Faktor n zur Rechenzeit
liefert. Durch Speicherung der aktuellen Länge einer Tour kann dieser Faktor n aber auf einen
konstanten Faktor reduziert werden.
Also: T (n) = Θ · (n − 1)!
grobe Abschätzung:
n! ≤ n n . . . n = nn ,
(n − 1)! = (n − 1)(n − 2) . . . 1 ≤ (n − 1)n−1
damit ergibt sich
T (n) = O(nn−1 )
Eine bessere Abschätzung liefert die Stirling’sche Formel:
√
n
n! ≈ ( )n · 2Πn für n → ∞
e
√
n
⇒ T (n) = Θ(( )n−1 · n)
e
Man erhält hier also ein überexponentielles Wachstum.
59
Resultate
1.) Fachleute sind überzeugt, daß es keinen polynomiellen Alg. für TSP gibt!
2.) und dass es sogar für fast optimale Lösungen keinen polynomiellen Alg. gibt.
3.) für TSP mit Dreiecksungleichung gibt es einen fast optimalen Alg. mit T (n) = O(n2 )
Dreiecksungleichung:
∀i, j, k wij ≤ wik + wkj
i
Diese Gleichung besagt, dass die direkte Verbindung zwischen zwei Städten immer minimale
Länge hat. Sie gilt zum Beispiel für Luftlinienverbindungen zwischen Städten. Für die Entfernungen auf Straßen gilt sie jedoch nicht immer.
j
dij
djk
d
ik
k
Wachstum der Rechenzeit von Optimal TSP
Folgende Tabelle veranschaulicht das extrem schnelle Wachstum der Rechenzeit von Optimal TSP. Heute ist das TSP-Problem mit optimierten Algorithmen für etwa 30 Städte lösbar.
Wie man an der Tabelle erkennt, ist der Aufwand für 40 Städte etwa um den Faktor 1016 höher
und damit also unerreichbar.
n
10
20
30
40
50
4.5.5
(n-1)!
362880
121645100408832000
8841761993739701954543616000000
20397882081197443358640281739902897356800000000
608281864034267560872252163321295376887552831379210240000000000
(n-1)!
3.6 · 105
1.2 · 1017
8.8 · 1030
2.0 · 1046
6.1 · 1062
Die Minimum-Spanning-Tree-Heuristik
Definition 4.10 Ein Preorder-Tree-Walk traversiert einen Baum folgendermassen: Beginnend mit dem Wurzelknoten werden von links nach rechts rekursiv alle Nachfolgerknoten
besucht.
60
Beispiel 4.12
Listet man nun alle besuchten Städte in der
Angewendet auf den minimal aufspannenden besuchten Reihenfolge und löscht alle WiederBaum mit Wurzelknoten Bern ergibt sich:
holungen so ergibt sich ein einfacher Pfad, der
alle Knoten besucht.
F
230
Ma
Ka
107
S
64
Ul
210
230
85
230
Ma
Ka
170
123
180
85
91
120
Z
91
RV
85
91
Be
210
171
123
170
86
180
Ba
Ul
195
191
M
178
107
S
64
86
N
210
67 135
171
195
191
Ba
N
210
67 135
Be
F
230
85
120
Z
RV
91
178
M
Im Fall eines voll vernetzten Graphen läßt sich dieser Pfad durch eine Verbindung von Frankfurt
nach Bern zu einem Hamilton-Kreis schließen und man erhält eine Näherungslösung für das
TSP-Problem. Dieses heuristische Vorgehen nennt man die Minumum-Spanning-TreeHeuristik.
Ist der Graph nicht vollständig vernetzt, wie im Beispiel, so ist es durchaus möglich, dass es
keinen Hamilton-Kreis gibt.
Der minimal aufspannende Baum liefert jedoch auch hier einen guten Ausgangspunkt für eine
Näherung zur Lösung des TSP-Problems.
F
230
85
230
Ma
67 135
Ka
107
S
64
4.6
210
171
123
170
86
180
Be
Ul
195
191
Ba
N
210
85
91
120
Z
91
RV
178
M
Planare Graphen
Definition 4.11 Läßt sich ein Graph in der Ebene darstellen, ohne dass sich Kanten kreuzen, so nennt man ihn planar. Die Menge der durch die Kanten begrenzten Flächenstücke
wird mit A bezeichnet.
Beispiel 4.13 Zwei planare Darstellungen des vollständigen Graphen mit vier Knoten:
61
Für diesen Graphen gilt |A| = 4.
Satz 4.6 (Eulerformel) Für jeden planaren zusammenhängenden Graphen G = (V, E) gilt
|V | − |E| + |A| = 2.
Beweis: Falls G ein Baum ist gilt |V | = |E| + 1 und |A| = 1 und es ergibt sich
|V | − |E| + |A| = |E| + 1 − |E| + 1 = 2.
Für den Fall, dass G kein Baum ist zeigen wir die Behauptung per Induktion über die Zahl der
Kanten n = |E|. Für n = 0 besteht der Baum aus einem Knoten, d.h. es gilt |V | = 1, |E| = 0,
|A| = 1 und die Formel stimmt.
Wir nehmen an, die Formel gilt für n > 0. Nun fügen wir eine Kante hinzu und erzeugen den
neuen Graphen G0 = (V 0 , E 0 ) mit |V 0 | = |V | und |E 0 | = |E| + 1. Die neue Kante schließt einen
Kreis und es gilt |A0 | = |A| + 1, woraus
|V 0 | − |E 0 | + |A0 | = |V | − (|E| + 1) + |A| + 1 = |V | − |E| + |A| = 2
2
folgt.
62
Kapitel 5
Formale Sprachen und Endliche
Automaten
5.1
Grundlagen
Man muss sich Sprachen vorstellen wie einen Legobaukasten. Die Buchstaben des Alphabets
entsprechen elementaren Bausteinen und die Worte, beziehungsweise Sätze entsprechen gebauten Objekten. Solche Mengen lassen sich mehr oder weniger einfach beschreiben. Zum Beispiel
die Menge der Objekte, die nur aus roten Steinen gebaut sind. Oder die Menge der Objekte bei
denen auf einem Basisstein nur Steine oben draufgesetzt werden dürfen, aber nicht daneben.
Was ist, wenn ich das fertige Objekt auf den Kopf stelle? Muß dann die Forderung immer noch
erfüllt sein?
Um solche Unklarheiten auszuschließen, werden wir bei den Sprachen ganz formal vorgehen. Wir
werden Spielgregeln in Form von Grammatiken zum Aufbau von Sprachen angeben. Mit diesen
Spielregeln können dann nur noch Worte aus einer bestimmten Sprache erzeugt (abgeleitet)
werden.
Hier stellen sich sofort einige für den Informatiker sehr wichtige und interessante Fragen:
• Läßt sich jede formale Sprache durch eine Grammatik beschreiben?
• Wenn ich eine Grammatik G habe, die eine Sprache L definiert, wie kann ich erkennen,
ob ein Wort zu dieser Sprache gehört oder nicht?
• Etwas konkreter: Ist es möglich, für eine konkrete Programmiersprache L in endlicher
Zeit zu entscheiden, ob ein vorgegebener Text ein Programm dieser Sprache darstellt
oder nicht. Diese Aufgabe ist der Syntaxcheck des Compliers.
• Ist diese Entscheidung vielleicht sogar effizient möglich, das heißt, auch für große Programme in kurzer Zeit?
• Wenn ja, wie macht man das?
• Kann man vielleicht sogar automatisch Fehler in Programmen erkennen, wie zum Beispiel
Endlosschleifen?
• Kann man überprüfen, ob ein Programm korrekt ist?
Die Beantwortung dieser Fragen ist Bestandteil des Gebiets der formalen Sprachen und Automaten. In dieser sehr knappen Einführung werden wir aber nur auf ganz einfache (reguläre)
Sprachen und auf die endlichen Automaten, das einfachste Maschinenmodell, eingehen können.
63
Definition 5.1 Ein Alphabet Σ ist eine endliche nicht leere Menge von Zeichen.
Definition 5.2 Die Menge Σ∗ aller Worte ist wie folgt rekursiv definiert.
• Σ ⊂ Σ∗ und auch das leere Wort ε ist in Σ∗ enthalten.
• Für jedes Wort w ∈ Σ∗ und jedes Zeichen x ∈ Σ ist auch wx ∈ Σ∗ . wx ist die Zeichenkette,
die entsteht, wenn man das Zeichen x an das Wort w anhängt.
Jede Teilmenge von Σ∗ wird Sprache genannt.
Sprachen sind noch einfacher als Lego-Baukästen. Es gibt genau vier Möglichkeiten, zwei Alphabetzeichen a und b miteinander zu verknüpfen, nämlich aa, ab, ba, oder bb. Diese Verknüpfung
heißt Konkatenation und ist nicht vertauschbar. Damit kann man beliebig lange endliche Worte
bauen, ähnlich wie beim Lego-Baukasten.
Beispiel 5.1
Σ = {0, 1}
Σ∗ = {0, 1, ε, 00, 01, 10, 11, 001, 000, 011, 010, . . .}
Beispiel 5.2
Σ
Σ∗
T erme
T erme
=
=
=
⊂
{+, −, ·, /, (, ), 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, x, y, a, b}
{. . . , ) + − · 567ax, . . .}
{x, y, a, b, (a), a + b, (a − 4) · y, . . .}
Σ∗
Die Menge aller korrekten arithmetischen Terme ist eine kleine Teilmenge von Σ∗ . Ein Affe,
der zufällig auf einer entsprechenden Tastatur tippt würde viele Versuche benötigen, um einen
korrekten Term zu erzeugen.
Definition 5.3
• Sei w ∈ Σ∗ und n ∈ N0 . Dann ist wn das durch n-fache Wiederholung von w entstandene
Wort. w0 ist also das leere Wort ε.
• Für eine endliche Zeichenmenge M ist M ∗ die Menge aller Zeichenketten die aus Elementen
in M gebildet werden können. Das leere Wort gehört zu M ∗ dazu. Die Menge M + = M ∗ \ε
enthält dagegen nur Worte mit mindestens einem Zeichen.
Beispiel 5.3 Sei Σ = {a, b, c}. Dann sind
∅,
{aa, ab, aaa},
{an |n ∈ N0 } = {ε, a, aa, aaa, aaaa, . . .},
{(ab)n |n ∈ N0 } = {ε, ab, abab, ababab, abababab, . . .},
{an bn |n ∈ N0 } = {ε, ab, aabb, aaabbb, aaaabbbb, . . .}
Teilmengen von Σ∗ und somit Sprachen über dem Alphabet Σ.
64
5.2
Grammatiken
Besonders interessant sind strukturierte Sprachen. Eine Sammlung von zufällig erzeugten Wörtern
ist für die meisten Anwendungen nicht sehr hilfreich. “Struktur” heißt hier, dass sich die Sprache
endlich beschreiben läßt. Wir werden Grammatiken verwenden um Sprachen zu beschreiben.
Aus dem Sprachunterricht in der Schule ist die Grammatik der deutschen Sprache bekannt.
Ein Satz der deutschen Sprache kann zum Beispiel bestehen aus < Subjekt > < Prädikat >
< Objekt > und < Subjekt > wiederum kann ersetzt werden durch < Artikel >< Substantiv >.
Damit ist also Die Studentin spielt Schach ein wohlgeformter Satz entsprechend der einfachen
angegebenen Grammatik. Jede Programmiersprache besitzt eine Grammatik.
Beispiel 5.4 Die Menge der arithmetischen Terme wie zum Beispiel x · (x + a · (b − 12)) läßt
sich durch folgende Regelgrammatik charakterisieren:
< Term >
< Term >
< Term >
< Term >
< Term >
< Term >
< Term >
< Var >
< Konst >
< Zahl >
< Ziffer >
→
→
→
→
→
→
→
→
→
→
→
< Term > + < Term >
< Term > − < Term >
< Term > / < Term >
< Term > · < Term >
(< Term >)
< Var >
< Konst >
x|y
a|b| < Zahl >
< Zahl >< Ziffer > | < Ziffer >
0|1|2|3|4|5|6|7|8|9
Hier steht das Zeichen | für “oder”, das heißt, eine Regel S → u|v steht für die zwei Regeln
S → u und S → v.
Durch sukzessives Anwenden einer der Regeln aus P beginnend mit dem Startsymbol kann man
den obigen Term x · (x + a · (b − 12)) ableiten:
< Term > ⇒
⇒
⇒
⇒
⇒
⇒
⇒
⇒
⇒
⇒
< Term > · < Term >
x· < Term >
x · (< Term > + < Term >)
x · (x+ < Term >)
x · (x+ < Konst > · < Term >)
x · (x + a · (< Term >))
x · (x + a · (< Konst > − < Term >))
x · (x + a · (b− < Konst >))
x · (x + a · (b− < Zahl >< Ziffer >))
x · (x + a · (b − 1 < Ziffer >))
⇒
⇒
⇒
⇒
⇒
⇒
⇒
⇒
⇒
⇒
< Var > · < Term >
x · (< Term >)
x · (< Var > + < Term >)
x · (x+ < Term > · < Term >)
x · (x + a· < Term >)
x · (x + a · (< Term > − < Term >))
x · (x + a · (b− < Term >))
x · (x + a · (b− < Zahl >))
x · (x + a · (b− < Ziffer >< Ziffer >))
x · (x + a · (b − 12))
Definition 5.4 Eine Grammatik ist ein 4-Tupel
G = (V, Σ, P, S)
mit
• V als endliche nichtleere Menge der Variablen.
• Σ als Menge der Konstanten oder Terminalalphabet und V ∩ Σ = ∅.
• P ⊂ (V ∪ Σ)+ × (V ∪ Σ)∗ als endliche Menge der Produktionsregeln.
• S ∈ V ist die Startvariable.
65
Definition 5.5 Die in Beispiel 5.4 und im Folgenden verwendete Art der Darstellung von
Grammatikregeln wird nach ihren Erfindern Backus-Naur-Form (BNF) genannt.
Beispiel 5.5 Mit
G = ( {< Term >, < Var >, < Konst >, < Zahl >, < Ziffer >},
{x, y, a, b, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, (, ), +, −, ·, /},
P, < Term >)
und P als Menge der Regeln aus Beispiel 5.4 ergibt sich also eine Grammatik mit den angegebenen Variablen, Konstanten und < Term > als Startsymbol.
Eine äquivalente Darstellung von Regelgrammatiken in grafischer Form bieten die Syntaxdiagramme, die wir hier nicht formal einführen. Ein Beispiel soll genügen:
Beispiel 5.6 Syntaxdiagramm für Terme
Var:
Term:
Term
+
Term
x
Term
_
Term
y
Term
/
Term
Term
*
Term
a
(
Term
)
b
Konst:
Zahl
Var
Konst
Zahl:
Ziffer:
Ziffer
0
1
2
3
4
5
6
7
8
9
Definition 5.6 Eine Folge von Wörtern (w0 , w1 , . . . , wn ) mit w0 = S und wn ∈ Σ∗ heißt
Ableitung von wn , falls für i ≥ 1 jedes der Wörter wi aus wi−1 entstanden ist durch
Anwendung einer Regel aus P auf ein Teilwort von wi−1 . Für einen Teilschritt schreibt man
wi−1 ⇒ wi . Ist ein Wort w durch einen oder mehrere Teilschritte aus u ableitbar, so schreibt
man u ⇒∗ w.
Obige Grammatik erzeugt die (unendliche) Menge der Terme als Teilmenge von Σ∗ . Allgemein
definiert man
66
Definition 5.7 Die durch G erzeugte Sprache L(G) ist die Menge aller Worte aus Σ∗ ,
die aus G ableitbar sind, d.h.
L(G) = {w ∈ Σ∗ | S ⇒∗ w}.
Formale Sprachen werden eingeteilt in verschiedene Klassen, die sogenannte Chomsky-Hierarchie.
Wir werden uns im Folgenden mit regulären Sprachen beschaftigen.
Definition 5.8 Eine Sprache heißt regulär, wenn alle Regeln die Form A → a, A → aB
oder A → ε besitzen, d.h. auf der linken Seite der Regeln steht immer eine Variable und auf
der rechten Seite steht entweder ein Terminalsymbol oder ein Terminalsymbol gefolgt von
einer Variablen.
Beispiel 5.7 Die Sprache {an bm |n ∈ N, m ∈ N} ist regulär und läßt sich durch die Grammatik
G = ({S, T }, {a, b}, P, S) beschreiben mit
P = { S → aS, S → aT, T → bT, T → b }.
Beispiel 5.8
Σ = {a, b}
G1 = ({S}, Σ, P, S)
P = { S → aS, S → bS, S → ε }
Offenbar läßt sich aus dieser Grammatik jedes Wort w ∈ Σ∗ ableiten, also gilt L(G1 ) = Σ∗ .
5.3
Reguläre Ausdrücke
Reguläre Ausdrücke dienen wie reguläre Grammatiken der Beschreibung von Typ-3-Sprachen.
Definition 5.9 Reguläre Ausdrücke zum Alphabet Σ sind:
1.) ∅ = {}
2.) ε
3.) a, falls a ∈ Σ
4.) sind α, β reguläre Ausdrücke, so auch αβ, α|β und α∗
hierbei steht α|β für α oder β, α∗ für beliebig viele Wiederholungen von α (auch 0 Wiederholungen).
Beispiel 5.9 aa∗bb∗ beschreibt {an bm /n ∈ N, m ∈ N}. Für aa∗ schreibt man kürzer a+. Der
Operator + steht also für beliebig viele Wiederholungen, aber mindestens eine.
67
Beispiel 5.10 Sei Σ = {., 0, 1, 2, 3, 4, 5, 6, 7, 8, 9}.
0.(0|1|2|3|4|5|6|7|8|9)+
beschreibt die Menge aller Dezimalzahlen mit 0 vor dem Dezimalpunkt.
Noch einfacher geht es, wenn man zur Beschreibung von Zeichenmengen folgende vereinfachende
Notationen einführt:
[xyz]
.
\x
a{n,m}
[a ]
[a −k]
Kurzform von (x|y|z)
steht für jedes (beliebige) Zeichen
steht für das Zeichen x, auch wenn x ein Sonderzeichen (z.B. ,,.”) ist
Ausdruck a mit n bis m Wiederholungen
jedes Zeichen außer a
jedes Zeichen außer a bis k
Nun lassen sich die Dezimalzahlen einfacher beschreiben mit
0\.[0123456789]+
oder noch einfacher durch
0\.[0 − 9]+
0 − 9 steht hier für den Zeichenbereich von 0 bis 9.
Die Syntax von Email-Adressen lässt sich durch den Ausdruck
................................................................................................................................. beschreiben.
Satz 5.1 Jede reguläre Sprache ist durch einen regulären Ausdruck beschreibbar. Umgekehrt
definiert jeder reguläre Ausdruck eine reguläre Sprache.
Im Gebiet der formalen Sprachen werden Sprachen, die mächtiger sind als die regulären Sprachen, behandelt. Zum Erkennen dieser Sprachen reichen aber endliche Automaten nicht mehr
aus. Hier werden mächtigere Maschinenmodelle, wie zum Beispiel Kellerautomaten und Turingmaschinen benötigt.
Alle gängigen Programmiersprachen sind Turingmächtig. Das heißt, Programme in diesen Sprachen können alles berechnen, was wir intuitiv als berechenbar ansehen. Diese Sprachen sind also
sehr “mächtig”. Für einfache Aufgabenstellungen in der Softwareentwicklung möchte man ein
einfacheres Programmiermodell um die Programmierung zu vereinfachen.
5.4
Endliche Automaten zur Worterkennung
Ein derartiges einfaches Modell ist der endliche Automat. Anschaulich ist ein endlicher Automat
ein Rechenelement, welches auf einem Eingabeband beginnend mit dem ersten Zeichen der
Eingabe das eingegebene Wort Zeichen für Zeichen liest. In jedem diskreten Rechenschritt macht
der Automat einen Zustandsübergang. Abhängig vom aktuellen Zustand und dem gelesenen
Zeichen geht der Automat in einen neuen Zustand über. Die Zahl der Zustände ist endlich.
Erreicht der Automat nach Lesen des letzten Zeichens einen Endzustand, so hat er das Wort
erkannt.
68
Lesekopf
HAL LO
Z
Zustand
Beispiel 5.11 Der durch folgende Regeln beschriebene Automat akzeptiert alle Zeichenketten
(Worte) bestehend aus einer beliebigen Anzahl a-s gefolgt von einer beliebigen Anzahl b-s,
mindestens jedoch ein a und ein b. Die Regelmenge des Automaten mit den Zuständen S, T
und dem Endzustand e ist
δ = {S, a → S; S, a → T ; T, b → T ; T, b → e}
Die Zustandsübergangsrelation δ läßt sich übersichtlich durch die Zustandsübergangstabelle
darstellen
δ S
T
e
a {S, T }
b
{T, e}
Man beachte, dass die Zustandsübergangsrelation δ nicht eindeutig ist, denn zum Beispiel kann
der Automat nach Lesen eines a im Zustand S nach S oder nach T übergehen. Dies zeichnet
den nichtdeterministischen Automaten aus.
Besonders anschaulich ist der zugehörige Zustandsgraph:
a
S
b
a
T
b
e
Der beschriebene Automat kann nur passiv Eingaben akzeptieren oder abweisen. Er löst also
ein binäres Entscheidungsproblem. Man kann solch einen Automaten einfach erweitern durch
eine Ausgabefunktion.
5.5
Automaten mit Ausgabe
Beispiel 5.12 Es soll ein Getränkeautomat mit Hilfe eines endlichen Automaten programmiert
werden. Der Automat kann mit bis zu 4 Dosen Mineralwasser gefüllt werden. Wenn eine 1-EuroMünze eingegeben wird, soll er eine Dose Wasser ausgeben. Bei Eingabe einer anderen Münze
soll er die eingegebene Münze wieder ausgeben, aber kein Getränk. Wenn der Automat leer ist
soll er anhalten und per Funk den Service benachrichtigen.
Ein endlicher Automaten (mit Ausgabe) für diese Aufgabe ist gegeben durch folgende Tabelle
mit den Zuständen z0 , z1 , z2 , z3 , z4 und den erlaubten Eingabezeichen e, f, m. Im Zustand zi
enthält der Automat i Flaschen Mineralwasser. e steht für die Eingabe eines Euro, f für Eingabe
einer falschen Münze. m steht für eine Flasche Mineralwasser. m kann sowohl eingegeben werden
(durch den Betreiber) als auch ausgegeben werden (an den Kunden). Ein Paar x, y in der Tabelle
beschreibt den Nachfolgezustand x und das Ausgabezeichen y.
z0
m z1 , ε
e z0 , e
f z0 , f
z1
z2 , ε
z0 , m
z1 , f
z2
z3 , ε
z1 , m
z2 , f
z3
z4
z4 , ε
z2 , m z3 , m
z3 , f z4 , f
Das Zustandsdiagramm zu diesem Automaten sieht so aus:
69
f
z0
f
m
e
z1
f
m
e
z2
f
m
e
z3
f
m
e
z4
e
Dieser Automat akzeptiert alle Eingabesequenzen (Worte), die zum leeren Automaten (d.h. zu
z0 ) führen.
5.6
Formale Beschreibung von Automaten
Genau wie bei allen Programmiersprachen wird auch für endliche Automaten eine streng formale Beschreibung benötigt. Diese ist aber auch noch für theoretische Überlegungen in der Theorie
der formalen Sprachen notwendig ( ⇒ Theoretische Informatik, Master). Wir beginnen ganz
elementar:
Nun kennen wir einige reguläre Sprachen. Wir stellen uns die Frage ob es eine möglichst einfache
und effiziente Rechenmaschine gibt, mit der man für ein beliebiges Wort w entscheiden kann,
ob dieses zu einer vorgegebenen regulären Sprache gehört.
Definition 5.10 Die Aufgabe, zu entscheiden, ob ein Wort w zu einer Sprache L gehört,
heißt Wortproblem.
Grammatik
erzeugt
erkennt
Sprache
Automat
−→
←−
Das Wortproblem für reguläre Sprachen kann durch endliche Automaten effizient gelöst
werden.
Formal wird der Automat wie folgt definiert:
Definition 5.11 Ein endlicher Automat M besteht aus einem 5-, bzw. 7-Tupel
M = (Z, Σ, δ, z0 , E)
bzw.
M = (Z, Σ, δ, z0 , E, γ, Θ)
mit
Z
Σ
δ
z0
E
γ
Θ
:
:
:
:
:
:
:
endliche Zustandsmenge
endliches Eingabealphabet, Σ ∩ Z = φ
Z × Σ → P(Z), die Zustandsübergangsfunktion
Startzustand
Menge der Endzustände
Z × Σ → Θ, die Ausgabefunktion
Ausgabealphabet
70
Definition 5.12 Ein Wort w = w1 . . . wn mit wi ∈ Σ wird akzeptiert von dem endlichen
Automaten M genau dann wenn M gestartet im Startzustand auf w1 nach n Anwendungen
der Funktion δ, d.h. nach Lesen von wn , einen Endzustand z ∈ E erreichen kann.
Die von M akzeptierte (erkannte) Sprache L(M ) ist
L(M ) = {w ∈ Σ∗ | M akzeptiert w}
Beispiel 5.13 Der Automat aus Beispiel 5.11 wird beschrieben durch das 5-Tupel
M = ({S, T, e}, {a, b}, δ, S, {e})
mit
δ = {S, a → S; S, a → T ; T, b → T ; T, b → e}.
Beispiel 5.14 Der Getränkeautomat aus Beispiel 5.12 wird beschrieben durch das 7-Tupel
({z0 , z1 , z2 , z3 , z4 }, {e, f, m}, δ, z0 , {z0 }, γ, {e, f, m})
wobei δ und γ gegeben sind durch die angegebene Automatentabelle.
Definition 5.13 Beim nichtdeterministischen endlichen Automaten (NFA) sind (im Gegensatz zum deterministischen endlichen Automaten (DFA)) für jeden Zustand Z und Eingabezeichen a mehrere Regeln
z, a → z1
..
.
z, a → zn
erlaubt.
Beispiel 5.15 An der Sprache L = {an bm |n ∈ N, m ∈ N} erkennt man schön, wie die Regelgrammatik in einfacher Weise in einen nichtdeterministischen Automaten übersetzt werden
kann:
Regelgrammatik
P = {S → aS
S → aT
T → bT
T → b}
Automat
δ = {S, a →
S, a →
T, b →
T, b →
S
T
T
e}
Es gibt aber auch einen deterministischen Automaten, der diese Sprache erkennt (siehe Aufgabe 39).
Satz 5.2 NFAs und DFAs sind gleich mächtig, d.h. zu jedem NFA gibt es einen DFA, der die
gleiche Sprache erkennt.
71
Satz 5.3 Eine Sprache L wird von einem endlichen Automaten genau dann erkannt, wenn sie
regulär ist.
72
Kapitel 6
Übungen
6.1
Geschichte der Informatik
Aufgabe 1 Recherchieren Sie in Ihrer Lerngruppe über eine(n) berühmten Informatiker(in)
und bereiten Sie ein kurzes Referat vor. In der Übungsstunde tragen Sie darüber vor. Beachten
Sie dabei bitte folgendes:
• Versuchen Sie zu verstehen (und im Vortrag darzustellen), was die von Ihnen gewählte
Person erfunden/geleistet hat.
• Berichten Sie auch über die Persönlichkeit und das Privatleben.
• Versuchen Sie sich kurz zu halten, aber trotzdem das Wesentliche zu vermitteln.
• Arbeiten Sie mit Farbe, Anschauung, Bildern.
6.2
Sortieren
Sortieren durch Einfügen
Aufgabe 2
a) Programmieren Sie “Sortieren durch Einfügen” in C für Integerzahlen - Arrays.
b) Testen Sie das Programm mit sortierten, zufälligen und umgekehrt sortierten Arrays auf
Korrektheit.
c) Bestimmen Sie für sortierte, zufällige und umgekehrt sortierte Arrays die Parameter a, b
und c von T (n) = a · n2 + b · n + c. Da in der Sprache C die Länge statischer Arrays auf
250000 beschränkt ist, sollten Sie mit dynamischen Arrays arbeiten. Das geht (mit C++)
z.B. so:
/* Deklaration Array */
int* a;
n = 300000000
/* Speicherplatz reservieren */
a = new int[n];
d) Bestimmen Sie die theoretische Rechenzeit für ein Array der Länge 5 · 109 .
e) Warum wird in der Praxis T (5 · 109 ) viel größer sein als oben errechneter Wert?
73
f ) Durch welche Massnahme kann man die berechnete Rechenzeit tatsächlich erreichen?
Aufgabe 3 Ordnen Sie folgende Funktionen nach Ihrem asymptotischen Wachstum (log ist
der Zehnerlogarithmus, ln der natürlich Logarithmus):
(ln n)ln n
n3/2
2n
ln ln n
n2n
n log n (n + 1)!
nn
ln n
√
n
n!
(ln n!) n2/3 ( 23 )n log n
n
√
log n
ln 2n
Aufgabe 4 Kreuzen Sie in folgender Tabelle alle zutreffenden Felder an. Es seien k ≥ 1, > 0
und c > 1. Es stehen die Abkürzungen O, o, Ω, ω und Θ für f (n) = O(g(n)), etc. Vergleichen
Sie hierzu das asymptotische Verhalten der Funktionen f und g. Zeichnen Sie ggf. die Graphen
der beiden Funktionen.
f (n) g(n)
nk
cn
log n
n
2n
2n/2
log m
n
mlog n
n!
nn
√
n nsin n
O
o Ω ω Θ
Aufgabe 5 Beweisen Sie Satz 3.1, d.h. T (n) = Θ(g(n))
O(g(n)).
⇔
T (n) = Ω(g(n)) und T (n) =
Quicksort
Aufgabe 6 Skizzieren Sie den Rekursionsbaum von Quicksort für ein konstantes Aufteilungsverhältnis von 1:k und leiten Sie aus diesem Baum T (n) = O(n lg n) ab.
Aufgabe 7 Programmieren Sie Quicksort für einfache Arrays von Integer-Zahlen, indem Sie die
Funktion Partition wie in der Vorlesung beschrieben implementieren. Zeigen Sie empirisch,
daß für zufällig sortierte Arrays Trand (n) = Θ(n lg n) und für vorsortierte Arrays Tmax (n) =
Θ(n2 ) gilt.
Aufgabe 8 Beweisen Sie, daß für Sortieralgorithmen gilt Tmin (n) = Ω(n).
Aufgabe 9
Gegeben sei folgender Programmteil eines C-Programms:
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
for(k = 1; k <= j; k++)
z = z+1;
a) Berechnen Sie die Laufzeit T (n) und geben Sie die (asymptotische) Zeitkomplexität an.
b) Welchen Wert hat z nach Verlassen der äußersten Schleife für n = 100?
74
Aufgabe 10 Gegeben sei die rekursive Funktion fib:
fib(0) = 1
fib(1) = 1
fib(n) = fib(n − 1) + fib(n − 2) für n ≥ 2.
a) Berechnen Sie fib(5).
b) Zeichnen Sie den Rekursionsbaum für fib.
c) Bestimmen Sie anhand des Rekursionsbaumes die Komplexität von fib.
Heapsort
Aufgabe 11 Zeigen Sie, daß gilt
∞
X
k=0
kq k =
q
.
(1 − q)2
Tip: Entweder Sie schreiben die Reihe gliedweise in geeigneter Form und wenden dann die
Formel für die geometrische Reihe an, oder Sie starten indem Sie die Formel für die geometrische
Reihe differenzieren.
Aufgabe 12 Warum wird der Schleifenindex i in Zeile 2 von Build-Heap von blength[A]/2c
bis 1 erniedrigt und nicht von 1 bis blength[A]/2c erhöht?
Aufgabe 13 Stellen Sie den Ablauf von Build-Heap für A = (5, 3, 17, 10, 84, 19, 6, 22, 9)
grafisch dar, ähnlich wie in Beispiel 3.9.
Aufgabe 14 Stellen Sie den Ablauf von Heapsort für A = (5, 13, 2, 25, 7, 17, 20, 8, 4) grafisch
dar, ähnlich wie in Beispiel 3.10.
Aufgabe 15 Benutzen Sie die Master-Methode zur Berechnung der Laufzeit der Suche durch
Bisektion mit der Rekurrenzgleichung T (n) = T (n/2) + Θ(1).
Aufgabe 16 Geben Sie mit Hilfe des Master-Theorems asymptotische Schranken für folgende
Rekurrenzen an:
a)
T (n) = 4T (n/2) + n
b)
T (n) = 4T (n/2) + n2
c)
T (n) = 4T (n/2) + n3 .
Hashing
Aufgabe 17 Vergleichen Sie für eine Hash-Tabelle mit 13 Einträgen die modulare HashFunktion und die Multiplikationsmethode. Überprüfen Sie an einer größeren Zahl von Schlüsseln
(mindestens 50), ob die Bedingung des einfachen uniformen Hashing erfüllt ist.
Aufgabe 18 Für den Fall von Kollisionen in einer Hash-Tabelle sollen die Rechenzeiten für die
Kollisionsauflösung ermittelt werden.
75
a) Überlegen Sie sich, wie die Operationen Einfügen, Suche (erfolgreich und nicht erfolgreich)
und Löschen eines Elements möglichst effizient realisiert werden und bestimmen Sie deren
Komplexität.
b) Was würde sich ändern, wenn wir mit sortierten Listen arbeiten würden?
6.3
Graphen
Aufgabe 19 Zeigen Sie, dass jeder zyklenfreie ungerichtete Graph ein Wald ist.
Aufgabe 20 Zeigen Sie, dass in jedem Graphen G = (V, E) mit m Kanten
X
deg(v) = 2m
v∈V
gilt.
Aufgabe 21 Konstruieren Sie für den Graphen aus dem Beweis von Satz 4.1 einen Eulerkreis,
indem Sie mit anderen Zyklen beginnen.
Aufgabe 22 Geben Sie für den bewerteten Süddeutschlandgraphen die Adjazenzlisten und die
Liste von Adjazenzlisten an.
Aufgabe 23 Geben Sie für den Graphen aus Beispiel 4.2 Adjazenzmatrix an.
Aufgabe 24 Erzeugen Sie einen minimal aufspannenden Baum mit dem Algorithmus von
Kruskal für den SFBay-Graphen:
Aufgabe 25 Verwenden Sie den Algorithmus von Dijkstra für das Single-Source-Shortest-PathProblem beim SFBay-Graphen mit Start in Palo Alto.
Aufgabe 26 Gegeben ist folgende Entfernungstabelle deutscher Städte:
76
Br
Aachen
Basel
Berlin
Bremen
Dortmund
Dresden
Düsseldorf
545
650
370
155
645
90
Aachen
Do
875
775
555
745
550
Basel
Be
400
495
200
560
Berlin
Aa
235
490
285
Bremen
515
70
Dortmund
Dü
Dre
580
Dresden
Ba
a) Bestimmen Sie mit dem Nearest-Neighbour-Algorithmus eine (heuristische) Lösung für
das TSP-Problem. Starten Sie in Düsseldorf. Geben Sie die Tour sowie deren Länge an.
b) Bestimmen Sie einen Minimum Spanning Tree mit dem Kruskal-Algorithmus. Zeichnen
Sie diesen in die Landkarte (unten) ein.
c) Verwenden Sie die Minimum-Spanning-Tree-Heuristik mit Wurzelknoten Bremen zur Bestimmung einer Lösung des TSP-Problems. Zeichnen Sie die Lösung in die Karte ein und
geben Sie Tour sowie Länge an.
Aufgabe 27 Versuchen Sie, die Minimum-Spanning-Tree-Heuristik zur Lösung des TSP-Problems
beim SFBay-Graphen anzuwenden. Vergleichen Sie das Ergebnis mit dem des Greedy-Algorithmus
bei Start in San Franzisko oder anderen Städten. Warum treten hier Probleme auf?
Aufgabe 28 Bestimmen Sie eine optimale Tour für das TSP-Problem beim SFBay-Graphen.
Aufgabe 29 Für einen planaren (ebenen) ungerichteten Graphen sei A die Menge der durch
die Kanten des Graphen begrenzten Flächenstücke. Überprüfen Sie an allen bisher verwendeten
Graphen (V, E) die Gültigkeit der Euler-Formel
|V | − |E| + |A| = 2.
Aufgabe 30 Es soll ein Programm entworfen werden, das bei gegebener Abstandsmatrix für
vollständig vernetzte Graphen eine optimale Tour findet.
a) Schreiben Sie ein Programm für Optimal TSP mit 4 Städten
b) Schreiben Sie ein Programm für Optimal TSP mit n Städten
6.4
Formale Sprachen und Endliche Automaten
Aufgabe 31
a) Geben sie eine Grammatik an, die alle Zeichenketten der Form
ab, abab, ababab, . . . erzeugt.
b) Geben sie einen regulären Ausdruck an, der alle Zeichenketten der Form
ab, abab, ababab, . . . erzeugt.
77
Aufgabe 32 Geben Sie eine Grammatik an für die Sprache L = {ai bj ck | i ∈ N, j ∈ N, k ∈ N}
Aufgabe 33 Geben Sie reguläre Ausdrücke an für
a) groß geschriebene Worte wie z.B. Hallo, aber nicht HALLO.
b) groß geschriebene Worte mit mindestens 3 und höchstens 5 Buchstaben.
c) Datumsangaben der Form 21.10.1999 oder 1.1.2000 oder 1.1.‘00 oder 21.10.‘99.
Nicht erlaubt sind unzulässige Werte wie z.B. 33.44.‘99 oder 121.10.1999
Aufgabe 34 Geben Sie für jede der in Aufgabe 33 angegebenen Sprachen einen endlichen
Automaten an, der diese erkennt.
Aufgabe 35
Beschreiben Sie die durch folgende regulären Ausdrücke definierten Sprachen und geben Sie
Beispiele an.
a) \\(index|color|label|ref)\{[^\}]*\}
b) %.*
c) \\section\*?\{.*\}
d) [A-Za-z0-9]+@[A-Za-z0-9]+(\.[A-Za-z0-9]+){1,6}
Aufgabe 36
konstruieren sie (deterministische oder nichtdeterministische) endliche Automaten für folgende
durch reguläre Ausdrücke gegebenen Sprachen:
a) [0-9]*\.[0-9]+
b) \\section\*?\{.*\}
Aufgabe 37 Es soll eine Fußgängerampel mit Hilfe eines endlichen Automaten programmiert
werden. Die Ampel hat die zwei Zustände rot und grün (aus der Sicht des Fahrzeugs). Im
Zustand rot akzeptiert die Ampel Signale von der Kontaktschleife auf der Straße und schaltet
dann auf Grün. Im Zustand Grün akzeptiert die Ampel Signale vom Fußgängertaster und
schaltet auf Rot. Alle anderen Eingaben ignoriert der Automat.
a) Geben Sie einen endlichen Automaten für diese Aufgabe an.
b) Zeichnen Sie ein Zustandsdiagramm zu diesem Automaten.
Aufgabe 38 Es soll ein Getränkeautomat mit Hilfe eines endlichen Automaten programmiert
werden. Der Automat kann mit bis zu 4 Dosen Mineralwasser, 4 Dosen Limo und 4 Dosen
Bier gefüllt werden. Wenn eine 1-Euro-Münze eingegeben wird, soll er eine Dose des gewählten
Getränks ausgeben. Bei Eingabe einer anderen Münze soll er die eingegebene Münze wieder
ausgeben, aber kein Getränk. Wenn von einer Getränkesorte alle Dosen ausgegeben sind, soll
er anhalten und per Funk den Service benachrichtigen.
a) Geben Sie einen endlichen Automaten (mit Ausgabe) für diese Aufgabe an.
b) Zeichnen Sie ein Zustandsdiagramm zu diesem Automaten.
78
c) Geben Sie einen regulären Ausdruck für diese Sprache an.
d) Geben Sie eine reguläre Grammatik an, welche die für diesen Automaten erlaubte Eingabesprache akzeptiert.
Aufgabe 39 Konstruieren Sie einen deterministischen endliche Automaten, der zu dem aus
Beispiel 5.15 äquivalent ist.
79
Literaturverzeichnis
[1] Wikipedia – Die freie Enzyklopädie. www.wikipedia.org. 2.7
[2] F. Naumann. Vom Abakus zum Internet. Wissenschaftliche Buchgesellschaft, 2001. Geschichte der Informatik. 2.1
[3] H. Matis. Die Wundermaschine. mitp-Verlag, 2002. Geschichte des Computers. 2.1
[4] W. de Beauclair. Rechnen mit Maschinen – eine Bildgeschichte der Rechentechnik. Vieweg
Verlag, 1968. Die Lektüre dieses Bilderbuches lohnt sich! 2.1
[5] D. Shasha and C. Lazere. Out of Their Minds: The Lives and Discoveries of 15 Great
Computer Scientists. Copernicus/ An Imprint of Springer-Verlag, 1995. Sehr unterhaltsam
und informativ.
[6] V. Claus and A. Schwill. Duden Informatik. Bibliographisches Institut & F.A. Brockhaus
AG, 1988. Ein gutes Nachschlagewerk zur Informatik allgemein.
[7] P. Rechenberg and G. Pomberger. Informatik-Handbuch. Hanser Verlag, 2001.
[8] C. Horn and O. Kerner. Lehr- und Übungsbuch Informatik, Band 1: Grundlagen und
Überblick. Fachbuchverlag Leipzig, 2001.
[9] T.H. Cormen, Ch.E. Leiserson, and R. L. Rivest. Introduction to Algorithms. MIT Press,
Cambridge, Mass, 1994. Sehr gute Einführung in die Analyse von Algorithmen. 3.5.5, 4.3,
4.5
[10] N. Wirth. Algorithmen und Datenstrukturen. Teubner-Verlag, Stuttgart, 1983 (3. Auflage).
Ein Klassiker, vom Erfinder der Sprache PASCAL.
[11] R. Sedgewick. Algorithmen. Addison-Wesley, Bonn, 1995. Übersetzung d. engl. Originals,
empfehlenswert.
[12] P. Tittmann. Graphentheorie. Fachbuchverlag Leipzig, 2003. Sehr gutes Buch mit vielen
Beispielen. Leider fehlen die Wegesuchalgorithmen.
[13] S. Krumke and H. Noltemeier. Graphentheoretische Konzepte und Algorithmen. Teubner
Verlag, 2005. Exakt und gleichzeitig anschaulich.
[14] Paul E. Black (Ed.). Dictionary of Algorithms and Data Structures [online]. National
Institute of Standards and Technology, 2004. http://www.nist.gov/dads.
[15] S. Skiena. The Algorithm Design Manual. Springer Verlag, 1997. Gutes Buch mit vielen
Algorithmen für den Praktiker.
80