Skript Waack merged

263
Kapitel 6 Einf ¨ uhrung in den Gegenstand der Vorlesung Informatik III 6.1 Gegenst¨ ande der Vorlesung Im ersten Teil dieser Vorlesung geht es um den Entwurf und die Analyse effizienter Algorithmen f¨ ur wichtige Probleme. Wir wer- den das Suchen und Sortieren, Entwurfs- und Analysetechiken und die effiziente Handhabung von Operationen auf Graphen behan- deln. Leider gibt es f¨ ur sehr viele, sehr wichtige Probleme aus den un- terschiedlichsten Anwendungsbereichen keine effizienten Algorith- men, um sie exakt zu l¨ osen. Aufgaben aus der Transportoptimie- rung geh¨ oren ebenso dazu wie die Bestimmung optimaler Modelle in der Bioinformatik. Alle diese Probleme haben sich zudem bisher hartn¨ ackig jedem Versuch widersetzt, den Nachweis zu f¨ uhren, daß es zu ihrer L¨ osung keine effizienten Algorithmen gibt. Im zweiten Teil werden wir diejenigen Grundbegriffe der Theoretischen Informatik kennenlernen, die es uns gestatten, solche Probleme unter einheitlichen Gesichtspunkten zu klassifizieren: NP-vollst¨ andige Entscheidungsprobleme und als Ausblick NPaquivalente Optimierungs- probleme. Diese Begriffe sind f¨ ur jeden Informatiker von großer Bedeutung. Das trifft auch dann zu, wenn seine Interessen vorwiegend auf praktischem Gebiet liegen. Sie helfen, die M¨ oglich- keiten und Grenzen der Praxis besser einzusch¨ atzen. Zudem kann man viele neuere Ent- wicklungen, z.B. die Konzepte der Computersicherheit, ohne die Methoden der Theoreti- schen Informatik nicht verstehen. Um eine Idee davon zu bekommen, was uns erwarten wird, wenn wir den Entwurf und die Analyse effizienter Algorithmen studieren, betrachten wir das folgende Problem. Das Problem MAXSUM 3

Transcript of Skript Waack merged

Page 1: Skript Waack merged

Kapitel 6

Einfuhrung in den Gegenstand derVorlesung Informatik III

6.1 Gegenstande der Vorlesung

Im ersten Teil dieser Vorlesung geht es um den Entwurf und dieAnalyse effizienter Algorithmen fur wichtige Probleme. Wir wer-den das Suchen und Sortieren, Entwurfs- und Analysetechiken unddie effiziente Handhabung von Operationen auf Graphen behan-deln.

Leider gibt es fur sehr viele, sehr wichtige Probleme aus den un-terschiedlichsten Anwendungsbereichen keine effizienten Algorith-men, um sie exakt zu losen. Aufgaben aus der Transportoptimie-rung gehoren ebenso dazu wie die Bestimmung optimaler Modellein der Bioinformatik. Alle diese Probleme haben sich zudem bisherhartnackig jedem Versuch widersetzt, den Nachweis zu fuhren, daßes zu ihrer Losung keine effizienten Algorithmen gibt. Im zweitenTeil werden wir diejenigen Grundbegriffe der Theoretischen Informatik kennenlernen, diees uns gestatten, solche Probleme unter einheitlichen Gesichtspunkten zu klassifizieren:NP-vollstandige Entscheidungsprobleme und als Ausblick NP-aquivalente Optimierungs-probleme.

Diese Begriffe sind fur jeden Informatiker von großer Bedeutung. Das trifft auch dannzu, wenn seine Interessen vorwiegend auf praktischem Gebiet liegen. Sie helfen, die Moglich-keiten und Grenzen der Praxis besser einzuschatzen. Zudem kann man viele neuere Ent-wicklungen, z.B. die Konzepte der Computersicherheit, ohne die Methoden der Theoreti-schen Informatik nicht verstehen.

Um eine Idee davon zu bekommen, was uns erwarten wird, wenn wir den Entwurf unddie Analyse effizienter Algorithmen studieren, betrachten wir das folgende Problem.

Das Problem MAXSUM

3

Page 2: Skript Waack merged

Eingabe: I = aj | j ∈ J, aj ∈ Z, wobei J := [1, n] ein Intervall naturlicher Zahlen von 1bis n ist.

Ausgabe: maxsum(I) := maxf(i, j) | i, j ∈ J, i ≤ j, wobei f(i, j) als∑j

k=i ak definiertist.

Es bietet sich hier an, die Anzahl n = |I| der in Rede stehenden Zahlen als Problemgroße

zu bezeichnen.Unser erster Algorithmus ist ein Vertreter der Kategorie

”Auschopfende Suche“. Es

werden alle zugelassenen Werte f(i, j) berechnet und dann das Maximum gebildet.

Algorithmus 6.1 (Algorithmus A1 fur MAXSUM)

Großschritt 1.Berechne jeden Wert f(i, j) fur sich.Lege die Werte in einem Feld f ab.

Großschritt 2.Durchlaufe f und bestimme das Maximum.

Grundsatzlich haben wir zwei Fragen zu beantworten, wenn uns ein Algorithmus vor-gelegt wird:

1. Arbeitet der Algorithmus korrekt?

2. Wieviele Ressourcen verbraucht er? (Um diese Frage beantworten zu konnen, mussenwir zunachst festlegen, welches Maß uns interessiert.)

Frage eins laßt sich fur Algorithmus 6.1 durch”Draufschaun“ positiv beantworten:

Jawohl, A1 lost MAXSUM. Was Frage zwei angeht, so legen wir uns zunachst darauf fest,daß wir

– arithmetische Operationen und

– Zahlenvergleiche

zahlen wollen.Als Aufwarmubung bestimmen wir nun die Lange des Feldes f : Es gibt

(

n2

)

Indizes(i, j) mit i < j. Hinzu kommen noch n Paare (i, j) mit i = j. Folglich hat das Feld f dieLange

(

n2

)

+ n =(

n+12

)

.Wir kommen zur eigentlichen Laufzeitanalyse von Algorithmus A1. Wir bezeichnen mit

timeA(n) die maximale Anzahl von arithmetischen Operationen und Zahlenvergleichen, dieder Algorithmus A auf eine Eingabe der Große n benotigt.

Zur Berechnung von f(i, j) in Großschritt 1 mussen wir j − i Additionen durchfuhren.

timeGS1 von A1(n) =

n−1∑

i=1

n∑

j=i+1

(j − i) =

n−1∑

i=1

n−i∑

1

j =

n−1∑

i=1

i∑

j=1

j

4

Page 3: Skript Waack merged

Unter Verwendung der Gleichungen 2.1 und 2.2 aus Abschnitt 2.1 erhalten wir:

timeGS1 von A1(n) =

1

6(n3 − n).

Fur die Analyes von GS 2 konnen wir die oben berechnete Feldlange gut gebrauchen. Essind

timeGS2 von A1(n) =

(

n + 1

2

)

− 1

Vergleiche notwendig. Alles in allem erhalten wir:

timeA1(n) =

1

6n3 +

1

2n2 +

1

3n− 1.

Naturlich ist es unvernunftig, in Algorithmus A1 Zwischenergebnisse bei der Berechnungvon f(i, j) nicht zur Bestimmung eines anderen f(i′, j′) zu verwenden:

Algorithmus 6.2 (Algorithmus A2 fur MAXSUM)

Großschritt 1.Berechne jeden Wert f(i, j) unter Verwendung der folgenden Regel:

f(i, j + 1) = f(i, j) + aj+1.Großschritt 2.

Durchlaufe f und bestimme das Maximum wie bei Algorithmus 6.1.

In Großschritt 1 von Algorithmus 6.2 benotigen wir fur jedes i = 1, 2, . . . , n zur Berech-nung der Werte f(i, i), f(i, i + 1), . . . , f(i, n) genau n− i viele Additionen:

timeGS1 von A2(n) =

n−1∑

i=1

(n− i) =

n−1∑

i=1

i

Unter Verwendung von Gleichung 2.1 aus Abschnitt 2.1 erhalten wir:

timeGS1 von A2(n) =

(

n

2

)

=n2

2−

n

2.

timeGS2 von A2(n) =

(

n + 1

2

)

− 1 =n2

2+

n

2− 1

Alles in allem erhalten wir:

timeA2(n) = n2 − 1.

Viele nutzliche Algorithmen haben eine rekursive Struktur. Sie sind gemaß dem Teile–und–Herrsche Paradigma organisiert und zerfallen auf jeder Rekusionsebene in zwei Pha-sen. Dazu nehmen wir an, daß die Zahl n eine Zweierpotenz ist:

5

Page 4: Skript Waack merged

Teile die Eingabeproblemstellung in mehrere Problemstellungen kleinerer Eingabengroße.

Beherrsche das Gesamtproblem durch

– rekursives Losen der Teilprobleme

– Zusammensetzen der Losungen der Teilproblem zu einer Losung des Gesamt-problems.

Wir wollen einen rekursiven Algorithmus zur Losung des MAXSUM–Problems entwer-fen.

Voruberlegung. Wir zerlegen die Indexmenge einer Problemstellung unseres MAXSUM–Problems in drei Teilbereiche. Dazu sei J = [1, n].

J1 := [1, n/2] J2 := [n/2 + 1, n] K := (i, j) | i ∈ J1, j ∈ J2

Nun konnen wir MAXSUMn auf die folgende Weise losen:

1. Lose die beiden Problemstellungen von MAXSUMn/2 bezogen auf die IndexmengenJ1 und J2.

2. Berechne maxf(i, j) | (i, j) ∈ K.

3. Berechne aus diesen drei Zwischenergebnissen durch zwei weitere Vergleiche derenMaximum und damit die Losung der Eingabeproblemstellung.

So kann man das MAXSUM–Problem losen. Leider handelt es sich dabei nicht umeinen rekursiven Algorithmus. Das Problem

”maxf(i, j) | (i, j) ∈ K“ ist keine Instanz

von MAXSUM.Um unser MAXSUM–Problem in zwei Teilprobleme gleicher Art teilen zu konnen,

erweitern wir die Problemstellung etwas:

l(i) := ai + ai+2 + . . . + an/2

r(j) := an/2+1 + an/2+2 + . . . + aj

und erkennen, daß

f(i, j) := l(i) + r(j) ((i, j) ∈ K)

ist. Das ist die Motivation fur die folgende Erweiterung des MAXSUM–Problems.

Das erweiterte Problem MAXSUM∗

Eingabe: I = aj | j ∈ J, wobei J ein abgeschlossenes Intervall naturlicher Zahlen ist.

Ausgabe: (maxsum(I), maxprefix(I), maxsuffix(I), ). Ist min J das Minimum und max Jdas Maximum uber alle Elemente aus J , so sind

maxsum(I) := maxf(i, j) | i, j ∈ J, i ≤ j (wie bisher)

maxprefix(I) := maxf(minJ, j) | j ∈ J

maxsuffix(I) := maxf(j, maxJ) | j ∈ J.

6

Page 5: Skript Waack merged

Algorithmus 6.3 (Algorithmus A3 fur MAXSUM∗)

Großschritt 1.Falls |I| = 1 ist, so gib aminJ = amax J aus und brich ab.Anderfalls fahre fort.

Großschritt 2.Teile die aktuelle Problemstellung I fur MAXSUM∗

n mit Indexmenge J in zweiProblemstellungen fur MAXSUM∗

n/2 mit Indexmengen J1 und J2.

Großschritt 3.Lose I1 := ai | i ∈ J1 und I2 := ai | i ∈ J2 durch rekursiven Aufruf.

Großschritt 4.Setze die Losung fur I wie folgt zusammen:

maxsum(I)← maxmaxsum(I1), maxsum(I2), maxsuffix(I1) + maxprefix(I2)maxprefix(I)← maxmaxprefix(I1), maxprefix(I2) +

j∈J1aj

maxsuffix(I)← maxmaxsuffix(I2), maxsuffix(I1) +∑

j∈J2aj

Zur Analyse der Laufzeit von Algorithmus 6.3 stellen wir die folgende Rekursion auf:

timeA3(1) = 1

timeA3(n) = 2 · timeA3

(n/2) + (n + 3).

Da es nur log2 n Halbierungen einer Problemstellung der Große n geben kann, folgt leicht

timeA4(n) = Θ (n · log n) .

Der folgende Algorithmus hat noch eine schnellere Laufzeit als Algorithmus 6.3. Eshandelt sich dabei um einen besonders einfachen Algorithmus zur dynamischen Program-

mierung.

Algorithmus 6.4 (Algorithmus A4 fur MAXSUM)

Annahme: J = [1, n].

Max← a1

MaxSuffix← a1

k ← 1

Solange k < n fuhre ausk ← k + 1MaxSuffix← maxMaxSuffix + ak, akMax← maxMaxSuffix, Max

Ausgabe: Max

7

Page 6: Skript Waack merged

Algorithmus 6.4 ist der erste, bei dem man sich einen Moment uberlegen muß, warumer korrekt ist. Man sieht leicht ein, daß

Invk : Max = maxf(i, j) | 1 ≤ i ≤ j ≤ k

MaxSuffix = maxf(i, k) | 1 ≤ k

eine Invariante der while–Schleife in Algorithmus 6.4 ist.Die Laufzeit von Algorithmus 6.4 ist denkbar einfach zu analysieren: Die while–Schleife

wird (n−1) mal durchlaufen. Bei jeder Iteration werden zwei Vergleiche und eine Additionausgefuhrt.

timeA4(n) = 3n− 3.

Wie sich die Verbesserung der asymptotischen Laufzeit fur konkrete Eingabenlangenauswirkt, sehen wir an der folgenden Tabelle.

n A1 A2 A3 A4

22 19 15 13 9210 ≈ 180 · 106 ≈ 106 19457 3069

(6.1)

Nun ist es an der Zeit zu sagen, daß wir uns bei unseren Analysen in der Regel umkonstante Faktoren nicht kummern werden. Das heißt zum Beispiel, daß wir, wenn wir dieLaufzeit von Algorithmus 6.4 angeben, statt 3 · n − 3 lieber O (n) schreiben. Warum dasangebracht ist, werden wir in Abschnitt 7.1 sehen.

Definition 6.5 Seien f, g : N→ N zahlentheoretische Funktionen.

1. Die Funktion f ist genau dann ein Element von O (g), wenn es eine positive re-elle Konstante c und eine naturliche Zahl n0 derart gibt, daß fur alle n ≥ n0 dieUngleichung f(n) ≤ c · g(n) gilt.

2. g ∈ Ω(f) ⇐⇒ f ∈ O (g).

3. g ∈ Θ(f) ⇐⇒ f ∈ O (g) und f ∈ Ω(g).

Bezeichnungen: Obwohl es eigentlich falsch ist, werden wir unverdrossen statt der Ele-mentrelationen f ∈ O (g), f ∈ Ω(g) und f ∈ Θ(g) die Gleichungen f = O (g), f = Ω(g)bzw. f = Θ(g) schreiben.

Beispiele.

1. 28·101000 ·n3+1010100

·n2 ∈ O (10−1000 · n3): Wir sehen, daß Konstanten hier irrelevantsind. Das gleiche gilt fur niederwertige Terme (hier 1010100

· n2).

2. Ist k ≤ ℓ, so ist nk ∈ O(

nℓ)

.

8

Page 7: Skript Waack merged

Der Term”f = O (g)“ steht nach Definition 6.5 dafur, daß die Funktion f von einem

Anfangsstuck abgesehen in gewissem Sinne kleiner ist als die Funktion g. Scharfer ist derfolgende Begriff.

Definition 6.6 Seien f, g : N→ N zahlentheoretische Funktionen.

1. Die Funktion f ist genau dann ein Element von o (g), wenn limn→∞f(n)g(n)

= 0. Mansagt, die Funktion f sei asymptotisch kleiner als die Funktion g.

2. g ∈ ω(f) ⇐⇒ f ∈ o (g).

3. Gilt limn→∞f(n)g(n)

= 1, so heißen f und g asymptotisch aquivalent. Wir schreibenf ∼ g.

Es gelten analoge Bezeichnungsvereinbarungen wie in Definition 6.5.

Wie man leicht sieht, folgt aus f = o (g) die Relation f = O (g). Das ist die Begrundungdafur, daß man sich um Terme geringerer Ordnung nicht zu kummern braucht, wenn mandie O–Notation verwendet.

Beispiele.

1. Fur alle festen reellen Zahlen 0 < c, d ist (log n)c ∈ o(

nd)

.

2. Fur alle festen reellen Zahlen 0 < c < d ist nc ∈ o(

nd)

.

3. Fur alle festen reellen Zahlen 0 < c, d ist nc ∈ o(

2d·n)

.

4. Fur je zwei feste reelle Zahlen 0 ≤ c < d ist 2c·n ∈ o(

2d·n)

.

Bemerkung. An dieser Stelle gilt es dem Eindruck entgegenzuwirken, es ginge in dieserVorlesung darum, fur zwei Funktionen f und g festzustellen, ob f ∈ O (g) oder sogarf ∈ Θ(g) gilt. Das ist nicht der Fall. Wir sind vielmehr in der folgenden Lage. Wir habeneinen Algorithmus A, der ein Problem P lost. Wir studieren die Laufzeit des Algorithmusund stellen beispielsweise folgendes fest:

Obere Laufzeitschranke. Fur jede Problestellung I des Problems P benotigt unsere Algo-rithmus A (hochstens) O (|I|2) Schritte. Wir sagen dann, die Laufzeit des AlgorithmusA sei ein O (n2).

Untere Laufzeitschranke. Fur jede Eingabenlange n gibt es eine Eingabe I derart, daß derAlgorithmus A (mindestens) Ω(n · log n) Schritte benotigt, um I zu bearbeiten. Dannist die Laufzeit von A ein Ω(n · log n).

Die Laufzeitanalyse fur einen Algorithmus besteht also aus zwei Teilen, der Abschatzungnach oben und der Abschatzung nach unten. Fallen die ermittelte obere und untere Lauf-zeitsschranke zusammen, benotigt ein Algorithmus auf jede Eingabe der Lange n hochsten

9

Page 8: Skript Waack merged

O (f(n)) und mindestens Ω(f(n)) Schritte, so sprechen wir von einer scharfen Laufzeit-schranke und sagen, die Laufzeit sei ein Θ(f(n)).

Im obigen Beispiel ist das nicht der Fall. Die obere und die untere Laufzeitschrankefallen auseinander. Hier ist noch etwas zu tun. Man sollte versuchen, entweder die obereSchranke zu drucken oder aber die untere Schranke anzuheben.

In den Kursvorlesungen”Informatik I/II“ (siehe Teil II fur eine Zusammenfassung) ha-

ben wir Kenntnisse daruber erworben, wie man die syntaktische Korrektheit von Program-men begrifflich erfaßt und algorithmisch uberpruft. Dabei war ein Computerprogramm alsZeichenkette uber der Menge der 128 ASCII–Zeichen selbst Gegenstand einer Rechnung.

Was erwarten wir von einem Algorithmus, der in der Lage ist, uber die syntaktischeKorrektheit eines Computerprogramms zu entscheiden? Ein solcher Algorithmus muß aufjede Eingabe anhalten und genau einem Bit ausgeben:

”1“ steht fur

”Jawohl, das Pro-

gramm ist syntaktisch korrekt“,”0“ heißt

”Nein, das Eingabe–Programm ist syntaktisch

fehlerhaft.“ Naturlich muß die Ausgabe der Wahrheit entsprechen. Wir erwarten also genaudas, was in der folgenden Definition erfaßt ist.

Definition 6.7 Sei Σ ein endliches Alphabet, uber dem die Eingabe codiert ist.

1. Ein Entscheidungsproblem ist eine Funktion

f : Σ∗ −→ 0, 1

wobei Σ∗ die Menge der Worter uber dem Alphabet Σ ist. Dabei wird entschieden,ob ein Eingabewort w ∈ Σ∗ zu der formalen Sprache

L := f−1(1) ⊆ Σ∗

des Urbildes der 1 unter f gehort oder nicht. Man spricht auch vom dem Entschei-

dungsproblem fur L.

2. Ein Algorithmus A lost das Entscheidungsproblem fur eine formale Sprache L ⊆ Σ∗

(oder heißt Entscheidungsalgorithmus fur L), wenn A auf jede Eingabe stoppt undentweder 1 oder 0 ausgibt, wobei gilt:

x ∈ L ⇐⇒ A(x) = 1 (x ∈ Σ∗).

Dabei steht A(x) fur die Ausgabe des Algorithmus A auf die Eingabe x.

3. Formale Sprachen L, fur die es einen Entscheidungsalgorithmus gibt, heißen ent-

scheidbar.

Im Teil II ist also die Losung des folgenden Problems skizziert:

Korrektheitsproblem fur Computer–Programme

Eingabe: ein Computer–Programm als Folge von ASCII–Zeichen.

10

Page 9: Skript Waack merged

Ausgabe:

1 falls das Eingabe–Programm syntaktisch korrekt ist;

0 andernfalls.

Ein Algorithmus zur Losung des Korrektheitsproblem fur Computer–Programme alleinware nutzlos. Einerseits ware man ziemlich hilflos, wenn man nur dahingehend beschiedenwurde, daß das Eingabe–Programm nicht korrekt ware. Andererseits soll ja nicht nur uberdie syntaktische Korrektheit entschieden werden. Vielmehr geht es darum, das Eingabe-programm in ausfuhrbaren Code zu ubersetzen. Wir benotigen den folgenden Begriff.

Definition 6.8 Seien Σ1 und Σ2 zwei endliche Alphabete. Wir sagen, daß ein AlgorithmusA eine Funktion

f : Σ∗

1 −→ Σ∗

2

berechnet, wenn A auf jede Eingabe w ∈ Σ∗1 halt und

f(w) = A(w)

gilt, wobei A(w) die Ausgabe von A auf w bezeichnet.

Man hat Interesse an der Losung des folgenden Problems.

Ubersetzungsproblem fur Computer–Programme

Eingabe: ein Computer–Programm P als Folge von ASCII–Zeichen.

Ausgabe:

ein ausfuhrbares Programm falls P syntaktisch korrekt ist;

eine aussagekraftige Fehlermeldung andernfalls.

Auf den ersten Blick scheint es beim Ubersetzungsproblem fur Computer–Programmeum die Berechnung einer Funktion zu gehen. Bei naherem Hinsehen stellt sich jedoch her-aus, daß sich weder fur den Fall der syntaktischen Korrektheit von P , noch fur den anderenFall ein Funktionswert eindeutig bestimmen laßt: Was eine aussagekraftige Fehlermeldungist, steht bis zu einem gewissen Grade im Ermessen des Nutzers. Und sicherlich gibt esmehrere aquivalente ausfuhrbare Programme. Wir stehen also vor einem Relationsproblem.

Definition 6.9 Seien Σ1 und Σ2 zwei endliche Alphabete und sei

R ⊆ Σ∗

1 × Σ+2

eine Relation in Σ1 und Σ2. (Die Menge Σ+2 umfaßt alle Worter uber Σ2 mit Ausnahme

des leeren Wortes.) Eine Funktion

f : Σ∗

1 −→ Σ∗

2

heißt Losung fur R, wenn fur alle w ∈ Σ∗1 gilt:

11

Page 10: Skript Waack merged

– Wenn f(w) 6= ǫ, so ist (w, f(w)) ∈ R.

– Wenn f(w) = ǫ, so ist gibt es kein w′ ∈ Σ+2 mit (w, w′) ∈ R.

ist.

Ein Algorithmus berechnet R (oder lost das Relationsproblem R), wenn er eine Losungfur R im Sinne von Definition 6.8 berechnet.

Ein Polynomialzeit–Algorithmus kommt auf jede Eingabe w nach |w|O(1) Schritten zueinem Ergebnis. Im Sinne der Theoretischen Informatik heißt ein solcher Algorithmus ef-

fizient.

In dieser Vorlesung werden zahlreiche effiziente Algorithmen vermittelt. Auch die Al-gorithmen aus Teil II haben polynomial beschrankte Laufzeit. Bei soviel Effizienz gepaartmit jugendlichem Optimismus kann man leicht zu dem Glauben gelangen, jedes Problemim Sinne von Definition 6.9 habe einen effizienten Algorithmus, der es lost. Warum dasnicht so ist, ist Gegenstand dieser Vorlesung ab dem Kapitel 12.

Es ist unmittelbar klar, daß man jedes endliche Alphabet Σ in algorithmisch leicht nach-zuvollziehender Weise uber 0, 1 codieren kann. (Ublicherweise wahlt man einen Blockco-

de. Hier wird jedes a ∈ Σ als Wort der Lange ⌈log2 |Σ|⌉ uber 0, 1 dargestellt.) Folglichreicht es aus theoretischer Sicht aus, formale Sprachen L uber 0, 1, Funktionen f von0, 1∗ nach 0, 1∗ und Relationen R aus 0, 1∗ × 0, 1+ zu betrachten. (In vielen kon-kreten Fallen ware das freilich sehr lastig.)

Definition 6.10 Die Komplexitatsklasse P besteht aus allen formalen Sprachen L ⊆0, 1∗, die durch einen Polynomialzeit–Algorithmus entschieden werden konnen.

Wir betrachten das folgende Beispiel.

Rucksack–Entscheidungsproblem

Eingabe: eine Folge naturlicher Zahlen

I := (w1, w2, . . . , wn, c1, c2, . . . , cn, C, W ) ∈ N2n+2

in kanonischer Darstellung (siehe Abschnitt 1.1).

(Die Indizes i = 1, 2, . . . , n symbolisieren Gegenstande, die in einen Rucksack gepacktwerden konnen. Die Zahlen (w1, w2, . . . , wn) stehen fur die Gewichte der Gegenstande,die Zahlen (c1, c2, . . . , cn) fur deren Nutzen. Das zulassige Gesamtgewicht des Ruck-sacks ist W . Die Zahl C ist der mindestens anzustrebende Nutzen. Die Große |I|der Instanz I ist gleich

∑ni=1 | bin ci| +

∑ni=1 | binwi| + | binC| + | binW |, wobei fur

eine naturliche Zahl m die Zeichenkette bin m deren kanonische Binardarstellung, dieGroße | binm| deren binare Lange bezeichnet.)

12

Page 11: Skript Waack merged

Ausgabe: eine Entscheidung daruber, ob es eine sogenannte zulassige Losung

(β1, β2, . . . , βn) ∈ 0, 1n

gibt, fur die

n∑

i=1

βici ≥ C

gilt.

(Eine Losung (β1, β2, . . . , βn) — hier: eine Befullung des Rucksacks — heißt zulassig,wenn ihr Gewicht das zulassige Gesamtgewicht von W nicht ubersteigt:

∑ni=1 βiwi ≤

W .)

Es ist nicht bekannt, ob das Rucksack–Entscheidungsproblem in P liegt. Vermutlich istdies nicht der Fall. Man hat aber den folgenden

”Algorithmus“.

Algorithmus 6.11 (NP–Algorithmus fur das Rucksack–Problem)

Großschritt 1 [Rate–Phase].Rate eine Losung (β1, β2, . . . βn).

Großschritt 2 [Verifikationsphase].Uberprufe, ob

∑ni=1 βiwi ≤W gilt.

Uberprufe, ob∑n

i=1 βici ≥ C gilt.Ist beides der Fall, gib 1 aus.Andernfalls gib 0 aus.

Zunachst ist klar, daß Algorithmus 6.11 auf jede Eingabe mit mehreren Rechengangenreagieren kann. Er akzeptiert die formale Sprache, die zum Rucksack–Entscheidungsproblemgehort. Das heißt folgendes:

– Gibt es fur eine Eingabe I = (w1, w2, . . . , wn, c1, c2, . . . , cn, C, W ) eine zulassige Losung(β1, β2, . . . , βn) mit

∑ni=1 βici ≥ C, so kann diese in Großschritt 1 geraten werden.

Folglich gibt es auf I einen Rechengang mit Ausgabe 1.

– Gibt es fur eine Eingabe I eine solche zulassige Losung nicht, so gibt es auf I auchkeinen Rechengang mit Ausgabe 1, denn jeder Vorschlag aus der Rate–Phase scheitertin der Verifikationsphase.

Was die Laufzeit angeht, so zahlen nur die Eingaben, die akzeptiert werden. Und hierwird auch nur der beste Rechengang in Anschlag gebracht. Die Rechenzeit fur einen Ra-tevorgang ist gleich der Zeit, die es bedarf, um die geratene Sequenz zur Verfugung zustellen: je Bit ein Zeittakt. Folglich handelt es sich bei Algorithmus 6.11 um einen nicht-

deterministischen Polynomialzeitalgorithmus.

13

Page 12: Skript Waack merged

Die Komplexitatsklasse NP besteht aus allen Entscheidungsproblemen, fur die es einenAlgorithmus von der Art des Algorithmus 6.11 gibt. Naturlich gilt P ⊆ NP. Das P–

NP–Problem ist die Frage, ob diese Inklusion echt ist.

Das Rucksack–Entscheidungsproblem ist ein sogenanntes NP–vollstandiges Problem:Jedes andere Problem aus NP laßt sich effizient darauf reduzieren. Folglich ist P genaudann gleich NP, wenn es ein NP–vollstandiges Problem in P gibt.

Es gibt sehr viele interessante NP–vollstandige Entscheidungsproblem. Wir werdeneinige kennenlernen.

Fur mogliche Anwendungen erscheint die folgende Optimierungsvariante des Rucksack–Entscheidungsproblems interessanter.

Rucksack–Optimierungsproblem

Eingabe: eine Folge

(w1, w2, . . . , wn, c1, c2, . . . , cn, W ) ∈ N2n+1.

Ausgabe: eine optimale zulassige Losung (β1, β2, . . . , βn) ∈ 0, 1n. (Eine zulassige Losung

(β1, β2, . . . , βn) heißt optimal, wenn deren Wert, die Zahl∑n

i=1 βici, maximal unterallen zulassigen Losungen ist.)

Diskrete Optimierungsprobleme sind in der Regel Relationsprobleme, denn es wirdmeist mehrere optimale zulassige Losungen geben. Das Rucksack–Optimierungsproblemist insbesondere ein NP–aquivalentes Optimierungsproblem: Es hat genau dann einenPolynomialzeit–Optimierungsalgorithmus, wenn P gleich NP ist. Wenn man statt eineroptimalen auch mit einer suboptimalen Losung zufrieden ist, gibt es einen Ausweg: Ap-proximation. Gerade das Rucksack–Optimierungsproblem ist, wie wir sehen werden, sehrgut approximierbar.

Sollte sich entgegen der allgemeinen Erwartung herausstellen, daß die Komplexitats-klassen P und NP gleich sind, hatte das fur das praktische Leben nicht nur positive Kon-sequenzen. Manche der Folgen ließen sich vielleicht mit einigem Humor ertragen. Anderewaren schlicht eine Katastrophe:

Das Lebenswerk nicht weniger Komple-xitatstheoretiker hat die Ungleichheit derKlassen P und NP zum Fundament. IhreErgebnisse wurden gegenstandslos. Kompli-zierte Hierarchien kollabierten.Keines der gangigen Verschlusselungsverfah-ren ware aus theoretischer Sicht mehr sicher.Zur Sicherung wichtiger oder gar brisanterInformationen mußte man sich etwas ganzNeues einfallen lassen.

14

Page 13: Skript Waack merged

6.2 Ausblick

Es gibt zahlreiche NP-aquivalente Optimierungsprobleme aus sehr vielen Anwendungsbe-reichen. Viele von ihnen sind zu wichtig, um sich einfach mit der Aussage zu begnugen,daß man fur sie vermutlich keine effizienten Algorithmen wird entwerfen konnen, die sieexakt losen. Einen Ausweg stellt, wie bereits gesagt, die approximative Losung dar: Mansucht nach schnellen Algorithmen fur suboptimale Losungen hoher Qualitat. Man kann nunNP-aquivalente Optimierungsprobleme danach klassifizieren, mit welcher Gute sie effizientapproximierbar sind.

Fur das erganzende Literaturstudium im Rahmen der Vorlesung Informatik III beson-ders geeignet sind [CLRS01], [GD03], [Weg99], [Hro01], [Rei99], [Pap94].

15

Page 14: Skript Waack merged

Literaturverzeichnis

[CLRS01] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein. Introduction to

Algorithms. MIT Press, 2001.

[GD03] R. H. Guting and St. Dieker. Datenstrukturen und Algorithmen. Leitfaden derInformatik. Teubner Verlag, Stuttgart, Leipzip, Wiesbaden, 2003.

[Hro01] J. Hromkovic. Algorithmische Konzepte der Informatik. Leitfaden der Informa-tik. Teubner Verlag, 2001.

[Pap94] C. H. Papadimitriou. Computational Complexity. Addison–Wesley, 1994.

[Rei99] K. R. Reischuk. Komplexitatstheorie. Leitfaden der Informatik. Teubner Verlag,1999.

[Weg99] I. Wegener. Theoretische Informatik — eine algorithmische Einfuhrung.Leitfaden der Informatik. Teubner Verlag, 1999.

16

Page 15: Skript Waack merged

Kapitel 7

Das Berechnungsmodell

7.1 Die Registermaschine (RAM) in ihrer Gottinger

Variante (GRAM)

Unserer Rechnermodell ist die in Abbildung 7.1 dargestellte GRAM.

∈ ZR1

R2

...

R31

PC

RO 0

Halde

Laufzeitstapel

µ(−1)

µ(−2)

µ(2)

...

...

µ(1)

µ(−3)

1

2

0

−1

−2

HauptspeicherRegister

∈ Z

...

∈ Z

∈ Z −3

...

...

...

Programm

1:

2:

3:

Befehl 1

...

BefehleBefehlsadressen

µ(0)

Speichereinheiten Adressen

Befehl 2

Befehl 3

Abbildung 7.1: Die GRAM

Zum besseren Verstandnis von Abbildung 7.1 bemerken wir folgendes:

17

Page 16: Skript Waack merged

– Register und Speichereinheiten (Speicherzellen) konnen beliebige ganze Zahlen bein-halten.

– Die Bezeichner fur die Register und fur die Speichereinheiten (z.B. R5 oder µ(7))stehen sowohl fur diese selbst als auch fur deren Inhalt.

– Unsere GRAM hat kein Ein- und Ausgabewerk. Wir begnugen uns an dieser Stelle mitder Vorstellung, daß die Eingabe bereits eingelesen ist und an einer wohldefiniertenStelle der Halde, z.B. in den ersten N Einheiten, gespeichert ist.

– Um zu verhindern, daß nichtberechenbare Informationen in die Rechnung der GRAMeinfließen, gilt fur jeden Zeitpunkt der Rechnung und fast alle i ∈ Z, daß µ(i) = 0ist.

– Die GRAM hat 32 Universalregister. Lediglich fur das Register R0 gilt die folgendeBesonderheit. Es ist nicht verwendungsbeschrankt. Es gilt jedoch, daß sein Inhaltstets gleich 0 ist.

– Einige Register werden nur fur bestimmte Zwecke eingesetzt:

1. Das Register R31 dient der Verwaltung der Rucksprungadressen im Rahmen derMethodenaufrufe.

2. Das Register R30 verweist auf die erste freie Speicherzelle unterhalb des Lauf-zeitstapels. Es wird deshalb Stack Pointer genannt und mit SP abgekurzt.

3. Das Register R29 wird auch Frame Pointer (FP) genannt und hat eine spezielleFunktion im Rahmen des Prozeduraufrufs.

4. Das Register R28 heißt Heap Pointer (HP) und verweist auf die erste freieSpeicherzelle oberhalb des Heaps.

Ein Programm ist eine konsekutiv wachsend durchnumerierte Folge von Befehlen ausder Tabelle 7.1. Fur Programme haben wir abweichend von der in Informatik I/II bespro-chenen von–Neumann–Struktur des Rechners einen eigenen Programmspeicher. Man stellesich vor, daß die einzelnen Befehle in je einer Speichereinheit gehalten werden, die uber eineAdresse erreichbar sind. Die Adresse eines Befehls ist seine Ordnungszahl im Programm.

In Hinblick auf den Programmablauf legen wir folgendes fest:

1. Der Inhalt des Befehlszahlers (engl. program counter) PC vor Beginn der Ausfuhrungdes Programms ist die Adresse des ersten auszufuhrenden Befehls.

2. Der Inhalt des Befehlszahlers nach der Ausfuhrung eines Befehls ist die Adresse desnachsten auszufuhrenden Befehls.

3. Ist der Inhalt des Befehlszahlers”außer Bereich“, so ist die Abarbeitung des Pro-

gramms beendet. Diese Situation entspricht dem Ergebnis der Ausfuhrung des Be-fehls end.

18

Page 17: Skript Waack merged

Programmende

END

Transportbefehle

LOAD r1,a(r2) PC← PC+ 1 & r1 ← µ(a + r2)

STORE a(r1),r2 PC← PC+ 1 & µ(a + r1)← r2

C-LOAD r,m PC← PC+ 1 & r ← m

Additive Arithmetik

ADD r1,r2,r3 PC← PC+ 1 & r1← r2+ r3

C-ADD r1,r2,m PC← PC+ 1 & r1← r2+ m

SUB r1,r2,r3 PC← PC+ 1 & r1← r2− r3

Multiplikative Arithmetik

MULT r1,r2,r3 PC← PC+ 1 & r1← r2 · r3

DIV r1,r2,r3 PC← PC+ 1 & r1← ⌊r2/r3⌋

MOD r1,r2,r3 PC← PC+ 1 & r1← r2− ⌊r2/r3⌋ · r3

Ordnung

SLT r1,r2,r3 PC← PC+ 1 & if r2 < r3 then r1← 1 else r1← 0

Sprunge

JMP r PC← PC+ 1 & PC← r

JAL r PC← PC+ 1 & R31← PC & PC← r

Verzweigungen

BEQ r,a PC← PC+ 1 & if r = 0 then PC← PC + a

BNQ r,a PC← PC+ 1 & if r 6= 0 then PC← PC + a

Legende

r, r1, r2, r3 Platzhalter fur die konkreten Register aus R0, R1, . . . , R31

a, m Platzhalter fur konkrete ganze Zahlen

& steht fur”und dann“.

Tabelle 7.1: Assemblerbefehle der GRAM

Auf diese Weise ist jedem Programm ein eindeutig bestimmter Programmablauf zugeord-net.

Ahnliche Formalisierungen der Registermaschine finden sich in (fast) jedem Lehrbuchzur Algorithmen- oder Komplexitatstheorie. Hier sei nur auf [Pap94] verwiesen.

7.2 Das Einheitskostenmaß

Wir wollen uns in diesem Teil der Vorlesung mit effizienten Algorithmen beschaftigen.Dazu benotigen wir (mindestens) ein Komplexitatsmaß.

Aus dem Grundkurs Informatik I/II wissen wir, daß der Befehlssatz eines Rechnershardwareunterstutzt ist. Fur unsere GRAM unterstellen wir dasselbe. Daher ist es gerecht-fertigt, das Einheitskostenmaß zu verwenden:

19

Page 18: Skript Waack merged

Einheitskostenmaß.

– Die Ausfuhrung jedes Befehls aus Tabelle 7.1 geschieht in einem Zeittakt.

– Jede Speicherzelle und jedes Register, das wahrend der Laufzeit benutzt wird,geht als eine Einheit in den Speicherbedarf des Programms auf die entsprechendeEingabe ein.

Ein Programm A ist nach dem vorangegangenen Abschnitt eine numerierte Folge vonGRAM–Assemblerbefehlen.

Definition 7.1 Sei A ein Programm und I eine Eingabe.Der Zeitbedarf timeA(I) des Programms A auf die Eingabe I ist die Anzahl der vom

Programm A auf die Eingabe I ausgefuhrten GRAM–Assemblerbefehle.Der Speicherbedarf spaceA(I) des Programms A auf die Eingabe I ist die Anzahl der

vom Programm A auf die Eingabe I benutzten Register und Speicherzellen.

Unter welchen Voraussetzungen ist das Einheitskostenmaß realistisch? Das ist immerdann der Fall, wenn mit Zahlen gerechnet wird, die im Rahmen der Verarbeitungsbreite

des verwendeten Rechners liegen. Nur dann ist gesichert, daß diese in eine Speicherzel-le/Register passen und durch die Schaltkreise des Rechners in einem verarbeitet werdenkonnen. Ist das nicht der Fall, fuhrt die Verwendung des Einheitskostenmaßes zu einerUnterschatzung des tatsachlichen Ressourcenverbrauchs. Dasselbe gilt naturlich, wenn derArbeitsspeicher des benutzten Rechners zu klein ist.

Vor allem um die Laufzeit und den Speicherdarf zweier Programme miteinander ver-gleichen zu konnen, mussen die Zahlen timeA(I) und spaceA(I) zur Große |I| der EingabeI in einen funktionalen Zusammenhang gestellt werden:

timeA(n) := suptimeA(I) | |I| = n (7.1)

spaceA(n) := supspaceA(I) | |I| = n (7.2)

Die in den Gleichungen 7.1 und 7.2 definierten Komplexitatsmaße heißen Zeit– bzw.Raumbedarf von A im schlechtesten Fall (engl. worst case).

Manche Algorithmen haben fur jedes n in geringer Anzahl Eingaben der Lange n mitrelativ hoher Laufzeit. Sei A ein solcher Algorithmus. Startet man ihn auf eine zufallige

Eingabe fester Lange, so ist es sehr wahrscheinlich, daß man es mit keinem der schlechtenFalle zu tun hat. Man hat keine große Laufzeit zu erwarten. Das richtige Komplexitatsmaßin dieser Situation ist der mittlere Zeitbedarf von A:

timeA(n) :=1

πn

I: |I|=n

timeA(I), (7.3)

wobei hier πn die Anzahl der Eingaben des Programms A der Große n bezeichnet.

Wir haben bereits betont, daß wir in unseren Analysen auf konstante Faktoren unddamit auch auf Terme niederer Ordnung selten Wert legen werden. Warum diese Beschei-denheit? Die folgenden zwei Grunde mogen genugen.

20

Page 19: Skript Waack merged

– Der Befehlssatz aus Tabelle 7.1 ist sicher nur einer von vielen moglichen anderen. Wirkonnen jedoch unterstellen, daß sich jeder Befehl aus dem Befehlssatz eines beliebigenrealen Rechners durch eine Auswahl aus unserem Satz in konstanter Zeit simulierenlaßt.

Soll eine Laufzeitanalyse fur (fast) alle Rechner gelten, ist daher der Verzicht aufkonstante Faktoren methodisch nahezu unumganglich.

– Die mathematische Analyse der Laufzeit wird deutlich einfacher.

Wir sind vor allem an Polynomialzeitalgorithmen interssiert. Deren Laufzeit ist einO

(

nk)

fur eine moglichst kleine Konstante k. Zum Abschluß dieses Abschnittes geht esuns um die folgenden zwei Fragen:

– Warum gilt uns eine polynomial beschrankte Laufzeit als Ausweis der Effizienz?

– Warum lohnt es sich, bei einem Algorithmus mit O(

nk)

Laufzeit den Exponentenk so klein wie nur irgend moglich zu machen? Spezieller gefragt, warum ist es derMuhe wert, einen quadratischen Algorithmus (Laufzeit O (n2)) so zu verbessern, daßer nur noch O (n) Zeit benotigt?

Wir beantworten beide Frage zusammen. Ein Zeittakt unseres Einheitskostenmaßes laßtsich nicht unmittelbar in

”reale Zeit“ umrechnen. Eine grobe Naherung bietet die Anzahl

der Taktschritte auf einem Rechner. (Aus dem Grundkurs Informatik I/II wissen wir al-lerdings, daß ein Takt eines Rechners nicht ausreicht, um einen Befehl des Befehlssatzesauszufuhren.) Wir nehmen meinen alten Laptop (maL), also eine Taktfrequenz von 300MHz. (Damit mache ich ihn etwas schlechter, als er ist.)

Sei T = 1 Sekunde (oder T = 1Tag) auf maL. Was ist dann T 2, und was ist 2T ?

T 1 Sekunde = 300 Mio. Takte 1 Tag = 2, 592 · 1013 TakteT 2 9.5 Jahre = 9 · 1016 Takte 71 Mrd. Jahre = 6, 718 · 1026 Takte

2T unglaublich viele Jahre: 23·108

Takte fast unendlich viele Jahre: 22,592·1013

Takte

Bei der Beurteilung der vorstehenden Tabelle muß man beachten, daß maL pro Jahr nur9, 4608 · 1015 Takte ausfuhren kann.

7.3 Die Einheitskosten fur hohere Befehle

In diesem Abschnitt interessieren uns die Einheitskosten fur die Instruktionen einer (belie-bigen) objektorientierten Programmiersprache. Eine Laufzeitanalyse setzt voraus, daß dasProgramm in elementare Instruktionen zerlegt wurde.

Definition 7.2 Eine Instruktion heißt elementar, wenn sie in Zeit O (1) ausfuhrbar ist.

21

Page 20: Skript Waack merged

Bemerkung. Der Zeitbedarf einer elementaren Instruktion kann vom Algorithmus A

abhangen, im Rahmen dessen sie ausgefuhrt wird. Die Bezeichnung”O (1)“ besagt nur,

daß die Zeit nicht von der Große der Eingabe I abhangt, die das Programm A gerade zubearbeiten hat.

Eine objektorientierte Programmiersprache modelliert Datenobjekte, die durch zugehori-ge Prozeduren (Methoden) verandert werden. Ein Objekt fristet zur Laufzeit des Pro-gramms sein Dasein als Objektblatt auf der Halde. Dieses enthalt die Datenfelder des Ob-jekts. Ein Methodenaufruf fuhrt zur Ablage eines Inkarnationsblattes (Rahmen, Frame)dieser Methode auf dem Laufzeitstapel. Dieser Rahmen ist Trager aller Informationen, diezur Erledigung des in Rede stehenden Methodenaufrufs notig sind. Ist der Methodenaufrufbeendet, so wird sie abberufen: Das Inkarnationsblatt wird vom Laufzeitstapel enfernt.

In den Abschnitten 7.3.1 und 7.3.2 zeigen wir, daß die Objekterzeugung und derMethodenaufruf/-abruf elementare Instruktionen sind. Dazu unterstellen wir die Existenzeiner Klasse XYZ mit a Datenfeldern df1, df2, . . ., dfa und (mindestens) einer Methode

void proc(farg1,farg2,. . ., fargk)

mit k Formalargumenten. Wir nehmen weiter an, daß die Methode proc l lokale Variablenalpha1, alpha2, . . ., alphal habe.

Im Abschnitt 7.3.3 gehen wir kurz auf den”Rest“ der Programmiersprache ein.

7.3.1 Erzeugung eines Objektes auf der GRAM

Ein Objektblatt des Typs XYZ hat die folgende Gestalt:

df1 Zeiger auf den Wert des ersten Datenfeldesdf2 Zeiger auf den Wert des zweiten Datenfeldes...

...dfa Zeiger auf den Wert des letzten Datenfeldes

(7.4)

Wie sieht der GRAM–Assemblercode aus, der zur Ablage des Blattes (7.4) fuhrt?Der HP verweist auf die erste freie Zelle der Halde. Hier soll das neue Objekt beginnen.

Die Adresse dieser Zelle ist gleichzeitig die Adresse des gesamten Objekts. Wir nehmenan, daß die den Datenfeldern zu ubergebenden Objekte an die Register R1, R2, . . ., Ra

gebunden sind. Das zu erzeugende Objekt seinerseits soll an die Speicherzelle mit derAdresse addr gebunden werden. Von dieser Adresse nehmen wir an, sie stehe im RegisterRa+1.

-- Ubergabe der Objektadresse an die dafur vorgesehene Speicherzelle

STORE 0(Ra+1), HP

-- Speicheranforderung von der Halde

C-LOAD R27, a

ADD HP, HP, R27

-- Binden des ersten Wertes an df1

STORE -1(HP), R1

22

Page 21: Skript Waack merged

-- Binden des zweiten Wertes an df2

STORE -2(HP), R2...

-- Binden des a-ten Wertes an dfa

STORE -a(HP), Ra

Wir haben die folgende Aussage bewiesen:

Die Erzeugung und Initialisierung eines Objektes ist eine elementare Instruktion.

7.3.2 Methodenaufruf auf der GRAM

Wir betrachten den Zeitbedarf des Aufrufs und des Abrufs der Methode proc. Es geht unsalso um die Kosten fur den Anfang und das Ende der Instruktion

x.proc(arg1,arg2,. . ., argk),

wobei zum Zeitpunkt der Ausfuhrung an die Variable x ein Objekt vom Typ XYZ gebundenist, und die arg1,arg2,. . ., argk nunmehr Aktualargumente, in der Regel Ausdrucke,sind.

Annahmen.

1. In dem”Gesamtprogramm“ ist der GRAM–Assemblercode jeder Methode eine kon-

sekutive Folge. Die Startadresse (niederwertigste Adresse eines Befehls) der Methodeproc sei add(proc).

2. Die Aktualargumente arg1,arg2,. . ., argk seien Ausdrucke, die bereits ausgewertetsind. Die Adressen der zugehorigen Objekte stehen in den Register R1, R2, . . ., Rk.

3. Die Adresse des Objektes Ox vom Typ XYZ, das an die Variable x gebunden ist, stehtim Register Rk+1. (Naturlich darf k + 1 nicht zu groß sein, damit die Register auchausreichen.)

Die Ausfuhrung der Methode proc zerfallt in funf Teile.

Der Aufruf gehort zur rufenden Routine. Hier wird der Speicherplatz fur das aktuelle Ob-jekt und die Parameter der Methode proc vom Stapel angefordert und entsprechendinitialisiert. Anschließend erfolgt der Sprung zum Code der gerufenen Methode.

Der Vorspann ist schon Bestandteil der gerufenen Methode proc. Hier geschieht folgen-des:

– Retten der Register, die von der Methode proc benutzt werden. (Wir unterstel-len im weiteren, daß es sich dabei um die Register R1, R2, . . ., R26 handelt.)

– Retten der Rucksprungadresse und des aktuellen Framepointers.

– Anfordern und initialisieren von Speicherplatz fur die lokalen Variablen imRumpf der Methode.

23

Page 22: Skript Waack merged

Der Methodenrumpf ist der Haupteil des Methodenaufrufs. Er dient dazu, die Daten-felder des aktuellen Objekt gemaß den Absichten des Programmierers zu verandern.

Im Abspann wird zunachst das, was im Vorspann geschehen ist, ruckgangig gemacht. An-schließend erfolgt der Rucksprung zur rufenden Routine, nachdem der entsprechendeSpeicher (unterer und mittlerer Teil des Inkarnationsblattes) wieder freigegeben wur-de.

Der Abruf ist wieder Bestandteil der rufenden Routine. Durch Zurucksetzen der Stack-pointers wird der im Aufruf angeforderte Speicher des Laufzeitstapels wieder freige-geben.

Ein Inkarnationsblatt (Rahmen, Frame) der Methode proc sieht so aus:

this Zeiger auf Ox

farg1 Zeiger auf arg1farg2 Zeiger auf arg2

......

fargk Zeiger auf argk

R1 Inhalt von R1

R2 Inhalt von R2...

...R26 Inhalt von R26

return RucksprungadresseoldFP Zeiger auf die oldFP–Zeile des vorigen Rahmens

alpha1 0alpha2 0

......

alphal 0

(7.5)

Liegt der Rahmen (7.5) auf dem Laufzeitstapel, verweist der Framepointer FP auf die ZeileoldFP des mittleren Teils. Wie sieht der GRAM–Assemblercode aus, der zur Ablage desRahmens (7.5) fuhrt?

Zum Aufruf.

-- Anforderung des obereren Teils vom Stapel

C-LOAD R27, k+1

SUB SP, SP, R27

-- Binden von argk an fargk

STORE 1(SP), Rk

-- Binden von argk-1 an fargk-1

STORE 2(SP), Rk-1...

24

Page 23: Skript Waack merged

-- Binden von arg1 an farg1

STORE k(SP), R1

-- Binden von Ox an this

STORE k+1(SP), Rk+1

-- Sprung zum Code von proc und Sichern der Rucksprungadresse

C-LOAD R27, add(proc)

JAL R27

Zum Vorspann.

--- Anforderung und Initialisierung des mittleren Teils

--- Anforderung des mittleren Teils

C-LOAD R27, 28

SUB SP, SP, R27

--- Sichern des alten Frames, starten eines neuen

STORE 1(SP), FP

ADD FP, SP, 1

-- Retten der Rucksprungadresse

STORE 2(SP), R31

-- Retten der Register

STORE 3(SP), R26

STORE 4(SP), R25...

STORE 28(SP), R1

-- Anforderung und Initialisierung des unteren Teils

-- Anforderung des unteren Teils

C-LOAD R27, ℓ

SUB SP, SP, R27

-- Initialisierung des unteren Teils

STORE 1(SP), R0

STORE 2(SP), R0...

STORE l(SP), R0

Bemerkungen. Mit Hilfe des Framepointers FP ist es einem Garbage-Collector moglich,den Laufzeitstapel zu durchmustern.

Jenseits der letzten lokalen Variablen alphal beginnt der sogenannte temporare Spei-cher der Methodeninkarnation. Wir haben hier angenommen, daß die Auswertung vonAusdrucken mit Hilfe der Register geschieht. Es ist aber auch moglich, daß deren Adressenin Speicherzellen des temporaren Speichers stehen. Dieser ist sehr gut uber FP erreichbar.

Abspann und Abruf machen Vorspann und Aufruf ruckgangig. Es ist eine leichte Ubungs-aufgabe, den GRAM–Assemblercode dafur anzugeben.

25

Page 24: Skript Waack merged

Wir haben uns folgendes klargemacht:

Fur jede Methode sind Aufruf, Vorspann, Abspann und Abruf elementare Instruktionen.Insbesondere gilt fur jede Eingabe I:

timeproc(I) = O (1) + timeRumpf von proc(I).

7.3.3 Arithmetische Ausdrucke, Programmverzweigungen

Die Feinheiten einer hochentwickelten Programmiersprache sind im Rahmen dieser Vorle-sung ohne Interesse. Wir benotigen (fast) nur arithmetische Ausdrucke und Programmver-zweigungen.

Wir stellen fest:

1. Der Zeitbedarf zur Auswertung arithmetischer Ausdrucke ist ein O (op), wobei op

die Anzahl der arithmetischen Operationen in dem zur Auswertung anstehendenAusdruck ist.

2. Zur Umsetzung von bedingten Anweisungen und von Schleifen werden die Verzwei-gungsbefehle BNQ und BEQ verwendet, um den Kontrollfluß zu steuern. Diese Steue-rung (ohne die dafur notwendigen Evaluierungen von Verzweigungs– bzw. Abbruch-bedingungen) entspricht an jeder Gabelung einer elementaren Instruktion.

7.4 Bemerkungen zur Notation

Wir werden unsere Algorithmen in einem gepflegten Pseudocode niederschreiben, der furjeden, der bereits in C oder Java programmiert hat, selbsterklarend ist.

Sei beispielsweise ExampleClass eine Klasse mit den Datenfeldern df1, df2 und df3,so sind df1(), df2() und df3() die get-Methoden. Auf set-Methoden verzichten wir. Liegtbeispielsweise eine Methode

proc1() returns Integer

der Klasse ExampleClass bereits vor, und sind wir gerade dabei, eine Methode proc2()

zu schreiben, die das Integer-Datenfeld df1 unter Verwendung des Integer-Datenfeldesdf2 und der Methode proc1() modifiziert, so schreiben wir im Rumpf von proc2()

df1← proc1() df2(),

um anzuzeigen, daß sich der neue Wert des Datenfeldes df1 aus dem Produkt des Ruck-gabewertes der Methode proc1() mit dem Wert des Datenfeldes df2 ergibt.

Ferner treffen wir die folgenden Verabredungen:

26

Page 25: Skript Waack merged

Man beachte jetzt und spater die Semantik der folgenden Befehle:

return: Beende den aktuellen Methodenaufruf.

return exp: Werte den Ausdruck exp aus und gib den Wert an die rufende Methodezuruck. Anschließend beende den aktuellen Methodenaufruf.

Ist der Wert eines Ausdrucks ein Objekt, so erfolgt die Wertubergabe stets durch Uber-gabe der Objektadresse.

Wir werden die Nullreferenz vorzugsweise durch das Symbol”↑“ bezeichnen. Daneben

kann”null“ Anwendung finden.

27

Page 26: Skript Waack merged

Literaturverzeichnis

[Pap94] C. H. Papadimitriou. Computational Complexity. Addison–Wesley, 1994.

28

Page 27: Skript Waack merged

Kapitel 8

Internes Suchen und Sortieren

Wir werden in diesem Kapitel die interne Verwaltung (die Verwaltung im Arbeitsspeicherdes Rechners) von Datenobjekten aus einer Grundmenge U ×R studieren.

Unsere Daten bestehen aus

1. einem Schlussel aus einem sehr großen, aber endlichen Universum U von Schlusselndes zunachst generischen Typs Key;

2. dem eigentlichen Datum, das im Rahmen unserer Darstellung allerdings wenigerwichtig ist und deshalb Satellitendatum heißt, aus einer sehr großen, aber endlichenGrundgesamtheit R des generischen Typs Range.

Zur Laufzeit soll es sich bei den Schlusseln der gehaltenen Paare stets um Schlussel-informationen handeln: Es existieren auf der Halde niemals zwei Paare mit dem gleichenSchlussel.

Das Universum U ist total geordnet. Sind uns zwei Schlussel k1 und k2 gegeben, sosollen die Tests k1 < k2? und k1 = k2? effizient ausfuhrbar sein. In der Regel heißt dasLaufzeit O (1).

Beispiele.

• Das Universum U ist eine Menge von ganzen Zahlen [u, o] ⊂ Z und die Ordnung istdie gewohnliche Ordnung;

• Das Universum U ist eine Menge von Zeichenketten Σℓ uber einem endlichen Alpha-bet Σ mit der lexikographischen Ordnung.

Um welche Probleme geht es in diesem Kapitel?

1. Wie kann man Mengen von den in Rede stehenden Paaren effizienter als durch ver-kettete Listen implementieren? Es geht uns dabei um die Worterbuch– und die Ite-ratoroperationen (siehe Abschnitt 8.1).

2. Wie kann man Felder von Schlusseln schnell sortieren? (Naturlich treten Schlusselund Satellitendaten stets im Doppelpack auf. Aber fur unsere Algorithmen spielenletztere kaum eine Rolle.)

29

Page 28: Skript Waack merged

8.1 Spezifikation des Datentyps Dictionary und der

Iteratoroperationen

Unter einem Worterbuch von Elementen aus U ×R, wobei es sich bei den Schlusseln stetsum Schlusselinformationen handelt, verstehen wir eine Verwaltung von Teilmengen ausU ×R, welche die Operationen empty, insert, delete und lookUp unterstutzt.

Den Zustand eines Worterbuchs konnen wir durch eine partielle Funktion

f : U ⊇−→ R.

beschreiben. In unserem Worterbuch sind genau jene Paare (k, t) ∈ U ×R gespeichert, dieden Graphen graph f der partiellen Funktion ausmachen:

graph f := (k, r) ∈ U ×R | f(k) = r.

Anders ausgedruckt, das aktuelle Worterbuch wird durch eine solche Funktion bzw. derenGraphen vollstandig beschrieben.

Auf dieser Grundlage konnen wir die Worterbuchoperationen spezifizieren. (Wir spre-chen auch von Datentyp Dictionary.)

empty(). Erzeugt wird das leere Worterbuch. Dessen Zustand f hat den leeren Graphen:graph f = ∅.

lookUp(Key k) returns Range. Diese Operation verandert das aktuelle Worterbuch mitdem Zustand f nicht. Sie gibt f(k) zuruck, sofern die Funktion f auf k definiert ist.Andernfalls wird ↑ zuruckgegeben.

insert(Key k, Range r). Wird das aktuelle Worterbuch durch die Funktion f beschrie-ben, so verandert diese Operation f zu g mit

graph g :=

graph f ∪ (k, r) falls f auf k nicht definiert ist;

(graph f \ (k, f(k))) ∪ (k, r) sonst.

delete(Key k). Transformiert den Zustand f des aktuellen Worterbuchs zu g mit

graph g :=

graph f \ (k, f(k)) falls f auf k definiert ist;

graph f sonst.

Um aus einem Worterbuch eine Menge zu machen — wir spechen auch vom DatentypSet — benotigen wir eine Iterator-Klasse.

Fur unsere Zwecke reicht die Vorstellung, daß ein Iterator-Objekt zwei Hauptdatenfel-der hat:

30

Page 29: Skript Waack merged

partner Zeiger auf das zu durchmusternde Mengenobjektcursor Zeiger auf den

”Trager“ des aktuellen Elements

(8.1)

Der Wert des Datenfeldes cursor aus Gleichung 8.1 heißt auch Laufer. In den Bei-spielen dieses Kapitels handelt es sich stets um einen Knoten aus einem Graphen (binarerSuchbaum oder verkettete Liste). Der Knoten wiederum hat ein Datenfeld, das auf einElement-Objekt der Menge verweist.

Die Klassen dieses Kapitels, die den Datentyp Set implementieren, benotigen eine Me-thode

elements() returns Iterator,

die ein Iterator-Objekt erzeugt und initialisiert. Zu der Initialisierung gehort in jedem Falle,daß das Datenfeld partner auf das aktuelle Mengenobjekt verweist.

Ist die aktuelle Menge nichtleer, so ist der Laufer unmittelbar nach der Initialisierungderjenige Knoten des

”Tragers“, der das Datum mit dem kleinsten (oder großten) Schlussel

tragt. Anderfalls ist sein Wert gleich ↑Die Iterator-Klasse enthalt Methoden, vermoge derer die Elemente der Menge in auf-

steigender (oder auch in absteigender) Ordnung ihrer Schlussel durchlaufen werden konnen.Wir verlassen den Pfad der Tugend, indem wir diese Iterator-Operationen nicht ganz im-plementationsunabhangig spezifizieren. Nach den Regeln eines Weltweisen, dessen Nameleider in Vergessenheit geraten ist, kann man jedoch eine Sache ruhig falsch machen, wennman weiß, wie es richtig geht.

Die Methode firstElement() weist dem Laufer denjenigen Knoten des Tragers zu, derdas Element der aktuellen Menge mit dem kleinsten Schlussel tragt. Sie hat als Vor-bedingung, daß die aktuelle Menge nichtleer ist.

Die Methode lastElement() weist dem Laufer denjenigen Knoten des Tragers zu, derdas Element der aktuellen Menge mit dem großten Schlussel tragt. Sie hat als Vor-bedingung, daß die aktuelle Menge nichtleer ist.

Die Methode hasMoreElements() gibt an, ob das Datenfeld cursor einen Wert ver-schieden von ↑ hat.

Die Methode nextElement() gibt das zum Laufer gehorige Element zuruck. Der Lauferwird durch seinen Nachfolger ersetzt, sofern dieser existiert. Ist der Schlussel deszuruckgegebenen Elements jedoch der großte der aktuellen Menge, so erhalt das Da-tenfeld cursor den Wert ↑.Die Methode nextElement() hat hasMoreElements() = true zur Vorbedingung.

Die Methode previousElement() gibt das zum Laufer gehorige Element zuruck. DerLaufer wird durch seinen Vorganger ersetzt, sofern dieser existiert. Ist der Schlusseldes zuruckgegebenen Elements der kleinste der aktuellen Menge, so erhalt das Da-tenfeld cursor den Wert ↑.

31

Page 30: Skript Waack merged

Die Methode previousElement() hat hasMoreElements() = true zur Vorbedingung.

8.2 Binare Suchbaume

8.2.1 Der Begriff

In diesem Abschnitt nehmen wir an, daß das Universum U der moglichen Schlussel, dieim Abschnitt 8.1 erwahnt worden sind, ein (relativ großes) Teilinterval [u, o] der ganzenZahlen Z ist. Der Datentyp Key ist also gleich Integer. Was die Satellitendaten angeht, sobleibt es beim generischen Typ Range und der Menge R als der Gesamtheit aller moglichenDatenobjekte dieses Typs.

Wir verwenden vollig zwanglos die Begriffe und Bezeichnungen aus Abschnitt 1.5.2.

Definition 8.1 Ein nichtleerer binarer Suchbaum T (mit Knotenmenge V (T )) uber Z undR ist ein geordneter binarer Wurzelbaum (siehe Abschnitt 1.5.2), zu dem Markierungsfunk-tionen der Knotenmenge

key : V (T ) −→ Z

data : V (T ) −→ R

gehoren. Die Markierungsfunktion key erfullt die strenge Suchbaumeigenschaft : Fur jedenKnoten v ∈ V (T ) und alle Knoten w1 ∈ T

(left)v und w2 ∈ T

(right)v ist

key(w1) < key(v) < key(w2).

8.2.2 Die symmetrische Ordnung der Knoten eines Suchbaums

Wir betrachten den Suchbaum aus Abbildung 8.1. Wir wollen die Anordnung der Knotenbegrifflich fassen, bei der die zugehorigen Schlussel eine monoton wachsende Folge bilden:

Knoten v7 v11 v4 v8 v2 v5 v1 v3 v12 v9 v6 v14 v13 v15 v10

Schlussel 30 40 50 60 70 80 100 130 133 136 140 145 150 155 160

(8.2)

In Tabelle 8.2 wie auch in der folgende Definition erklaren wir die Ordnung der Knoten,indem wir sie anordnen. Fur das Beispiel aus Tabelle 8.2 heißt das:

v7 < v11 < v4 < v8 < v2 < v5 < v1 < v3 < v12 < v9 < v6 < v14 < v13 < v15 < v10.

Definition 8.2 Sei T = (T(left)r , r, T

(right)r ) ein nichtleerer binarer Suchbaum. Die symme-

trische Ordnung (engl. inorder) der Knoten von T definieren wir induktiv uber die Tiefe dvon T .

Induktionsanfang: d = 0. Dann besteht T genau aus der Wurzel r. Auf einer einelemen-tigen Menge gibt es genau eine Ordnung.

32

Page 31: Skript Waack merged

v1

v2

v4

v3

v6v5

v7 v8

v9 v10

v11

v12 v13

v14 v15

70

8050

6030

40

130

133

145 155

140

100

160

150

136

Abbildung 8.1: Ein Suchbaum mit 15 Knoten

Induktionsschritt: dր d + 1. Dann ist die symmetrische Ordnung (Anordnung) inorder Tder Knoten von T wie folgt definiert:

inorder T := inorder T (left)r

︸ ︷︷ ︸

bekannt nachInduktions-

voraussetzung

, r, inorder T (right)r

︸ ︷︷ ︸

bekannt nachInduktions-

voraussetzung

.

Bezeichnung: <inorder.

Die nun folgenden Lemmas 8.3, 8.4 und 8.5 sind leicht zu beweisen.

Lemma 8.3 Ist T ein nichtleerer binarer Suchbaum, dann gilt fur je zwei von einanderverschiedene Knoten u 6= v

u <inorder v ⇐⇒ key u < key v.

Lemma 8.3 zeigt, daß die Knoten des Baumes aus Abbildung 8.1 wie in Tabelle 8.2angegeben symmetrisch angeordnet sind.

Lemma 8.4 Ist T ein nichtleerer binarer Suchbaum, und ist Tu ein Teilbaum von T , soist die Knotenmenge von Tu bzgl. der symmetrischen Ordnung ein Intervall innerhalb dersymmetrischen Ordnung von T .

Daruber hinaus erhalt man die symmetrische Ordnung des Baumes Tu, indem man diesymmetrische Ordnung von T auf die Knotenmenge von Tu einschrankt.

33

Page 32: Skript Waack merged

Ist P eine nichtleere, endliche geordnete Menge. Wir sagen, ein Element v ∈ P uberdecktein Element u ∈ P , wenn v großer ist als u, aber das offene Intervall (u, v) von P leer ist.Wir sagen auch, das Element v sei der Nachfolger des Elements u in der Ordnung P .

Lemma 8.5 (Hauptlemma uber die symmetrische Ordnung) Sei T ein nichtleererbinarer Suchbaum.

Maximum. Man erhalt den maximalen Knoten der symmetrischen Ordnung der Knotenvon T , indem man von der Wurzel aus der jeweils rechten Kante solange folgt, bisdaß es eine solche Kante nicht mehr gibt.

Minimum. Man erhalt den minimalen Knoten der symmetrischen Ordnung der Knotenvon T , indem man von der Wurzel aus der jeweils linken Kante solange folgt, bis daßes eine solche Kante nicht mehr gibt.

Ordnungsrelation. Seien u 6= v ∈ T , und sei Tu,v = (T ′1, r

′, T ′2). Dann gilt:

1. Der Knoten u ist genau dann kleiner als der Knoten v, wenn eine der folgendendrei Bedingungen erfullt ist:

(a) u = r′ und v ∈ T ′2.

(b) u ∈ T ′1 und v = r′.

(c) u ∈ T ′1 und v ∈ T ′

2.

2. Der Knoten u wird genau dann vom Knoten v uberdeckt, wenn eine der beidenfolgenden Bedingungen erfullt ist:

(a) u = r′ und v ∈ T ′2 ist dort der kleinste Knoten.

(b) u ∈ T ′1 und v = r′, und u ist der großte Knoten in T ′

1.

Lemma 8.5 gibt uns die Moglichkeit, die Vorganger- bzw. Nachfolgerrelation der sym-metrischen Ordnung in einer Weise zu beschreiben, die eine effiziente algorithmische Um-setzung gestattet.

Lemma 8.6 Sei T ein nichtleerer binarer Suchbaum, und sei v ein Knoten von T . Danngilt fur die symmetrische Ordnung der Knoten von T :

Fall 1. Der Knoten v hat keinen Vorganger, weil er der kleinste Knoten ist. Das ist genaudann der Fall, wenn

– der Knoten v keinen linken Sohn hat, und

– v die Wurzel ist, oder alle Vorfahren von v mit Ausnahme der Wurzel von Tlinke Sohne sind.

Fall 2. Der Knoten v hat einen Vorganger p. Sei Tu := Tv,p der kleinste Teilbaum, der

v und p umfaßt. Sei Tu := (T(left)u , u, T

(right)u ). Dann sind die folgenden zwei Falle

moglich.

34

Page 33: Skript Waack merged

Fall 2.1. Es ist v = u und der Knoten p ist der maximale Knoten im TeilbaumT

(left)u . Das ist genau dann der Fall, wenn v einen linken Sohn hat.

Fall 2.2. Es ist p = u und der Knoten v ist minimaler Knoten im Teilbaum T(right)u .

Das ist genau dann der Fall, wenn

– der Knoten v keinen linken Sohn hat, und

– v rechter Sohn ist, oder es einen Vorfahren von v gibt, der rechter Sohn ist.

Eine zu Lemma 8.6 analoge Aussage uber den Nachfolger eines Knotens v des aktuellenSuchbaums T sieht so aus:

Lemma 8.7 Sei T ein nichtleerer binarer Suchbaum, und sei v ein Knoten von T . Danngilt fur die symmetrische Ordnung der Knoten von T .

Fall 1. Der Knoten v hat keinen Nachfolger, weil er der großte Knoten ist. Das ist genaudann der Fall, wenn

– der Knoten v keinen rechten Sohn hat, und

– v die Wurzel ist, oder alle Vorfahren von v mit Ausnahme der Wurzel von Trechte Sohne sind.

Fall 2. Der Knoten v hat einen Nachfolger s. Sei Tu := Tv,s der kleinste Teilbaum, der

v und s umfaßt. Sei Tu := (T(left)u , u, T

(right)u ). Dann sind die folgenden zwei Falle

moglich.

Fall 2.1. Es ist v = u und der Knoten s ist der minimale Knoten im TeilbaumT

(right)u . Das ist genau dann der Fall, wenn v einen rechten Sohn hat.

Fall 2.2. Es ist s = u und der Knoten v ist maximaler Knoten im Teilbaum T(left)u .

Das ist genau dann der Fall, wenn

– der Knoten v keinen rechten Sohn hat, und

– v linker Sohn ist, oder es einen Vorfahren von v gibt, der linker Sohn ist.

8.2.3 Bemerkungen zur Implementation

Die Knoten eines binaren Suchbaum werden durch Objekte des Typs Node dargestellt. EinObjektblatt hat im wesentlichen die folgende Gestalt:

key Schlussel aus dem Bereich der ganzen Zahlendata Zeiger auf ein Satellitendatum vom Typ Range

lson Zeiger auf das Knotenobjekt des linken Sohnes vom Typ Node

rson Zeiger auf das Knotenobjekt des rechten Sohnes vom Typ Node

father Zeiger auf das Knotenobjekt des Vaters vom Typ Node

(8.3)

35

Page 34: Skript Waack merged

Das Datenfeld father erlaubt es uns, den Baum auch in Richtung der Wurzel zu durch-laufen. Hat ein Datenfeld aus 8.3 den Wert ↑, so existiert das entsprechende Objekt nicht.

Der binare Suchbaum selbst ist eine Instanz der Klasse BinarySearchTree, derenHauptdatenfeld root vom Typ Node auf das Wurzelobjekt verweist. (Der dargestellte binareSuchbaum ist genau dann leer, wenn root = ↑ ist.)

Die Iterator-Klasse fur binare Suchbaume hat als Wert des partner-Datenfeldes einObjekt der Klasse BinarySearchTree, als Wert des cursor-Datenfeldes einen Knoten desPartners.

Alle Methoden, die wir im folgenden besprechen werden, gehoren entweder zur KlasseBinarySearchTree oder zur Iterator-Klasse fur binare Suchbaume. Folglich konnen wirbei der Besprechnung der Algorithmen insbesondere von dem aktuellen binaren Suchbaumsprechen.

8.2.4 Die Iterator-Operationen

Die Aussagen von Abschnitt 8.2.2 bilden die Grundlage fur die Implementation der Iterator-Operationen firstElement(), lastElement(), nextElement() und previousElement().(Alle anderen im Zusammenhang mit Iteratoren stehenden Methoden sind algorithmischuninteressant.)

Wir schreiben zunachst Hilfsmethoden, die den bzgl. der symmetrischen Ordnung klein-sten bzw. großten Knoten des im ubergebenen Knoten wurzelnden Teilbaums berechnen.Beide gehoren zur Klasse BinarySearchTree.

Die Algorithmen 8.8 und 8.9 sind wegen Lemma 8.5 korrekt.

Algorithmus 8.8 (Suche nach dem kleinsten Knoten im aktuellen Suchbaum)

Methodenkopf:least

(Node u

)returns Node

Vorbedingung:Der Knoten u gehort zum aktuellen Suchbaum T .

Nachbedingung:Es wird der kleinste Knoten aus Tu zuruckgegeben.

Rumpf:Falls u.lson() = ↑,return u

return least(u.lson())

Der folgende Algorithmus ist das Dual zu Algorithmus 8.8.

Algorithmus 8.9 (Suche nach dem großten Knoten im aktuellen Suchbaum)

36

Page 35: Skript Waack merged

Methodenkopf:greatest

(Node u

)returns Node

Vorbedingung:Der Knoten u gehort zum aktuellen Suchbaum T .

Nachbedingung:Es wird der großte Knoten aus Tu zuruckgegeben.

Rumpf:Falls u.rson() = ↑,return u

return greatest(u.rson())

Die folgende Aussage ist offensichtlich.

Aussage 8.10 Die Laufzeit fur die Aufrufe von greatest(u) bzw. least(u) ist einO (depth Tu), wobei T der aktuelle Suchbaum ist.

Unter Verwendung von greatest(u) und least(u) ist die Implementation der Metho-den firstElement() bzw. lastElement() der Iteratorklasse fur binare Suchbaume leicht.Wir beschranken uns auf firstElement().

Algorithmus 8.11 (Erstes Element einer Menge)

Methodenkopf:firstElement()

Rumpf:cursor← partner().least(partner().root())return

Aus Aussage 8.10 folgt, daß die Laufzeit von Algorithmus 8.11 und vom analogen Al-gorithmus fur lastElement() ein O (depth T ) ist. Dabei ist T der Wert des partner-Datenfeldes.

Die nun folgenden Hilfsmethoden previous(u) (Algorithmus 8.12) und next(u) (Algo-rithmus 8.13) bilden die Grundlage fur die Iterator-Operationen previousElement() bzw.nextElement(). Sie gehoren zur Klasse BinarySearchTree und berechnen den Vorganger–bzw. den Nachfolgerknoten des ubergebenen Knotens im aktuellen Suchbaum T bzgl. dersymmetrischen Ordnung. Algorithmus 8.12 setzt Lemma 8.6 um, Algorithmus 8.13 dagegenLemma 8.7.

Algorithmus 8.12 (Berechnung des Vorgangerknotens im Suchbaum)

37

Page 36: Skript Waack merged

Methodenkopf:previous

(node u

)returns Node

Vorbedingung:Der ubergebene Knoten u gehort zum aktuellen Suchbaum T .

Nachbedingung:Falls least(root()) 6= u, so wird der Vorganger von u zuruckgegeben.Falls least(root()) = u, so wird ↑ zuruckgegeben.

Großschritt 1. [Fall 2.1 von Lemma 8.6]Falls u.lson() 6= ↑return greatest(u.lson())

Großschritt 2. [Falle 1 und 2.2 von Lemma 8.6]Gehe vermoge der father-Referenz von u in Richtung root.Suche den ersten Vorfahren p von u, so daß p.rson() gleich u oder Vorfahre von u ist.Falls ein solcher Vorfahre nicht existiert,return ↑

Anderfallsreturn p

Algorithmus 8.13 (Berechnung des Nachfolgerknotens im Suchbaum)

Methodenkopf:next

(node u

)returns Node

Vorbedingung:Der ubergebene Knoten u gehort zum aktuellen Suchbaum T .

Nachbedingung:Falls greatest(root()) 6= u, so wird der Nachfolger von u zuruckgegeben.Falls greatest(root()) = u, so wird ↑ zuruckgegeben.

Großschritt 1. [Fall 2.1 von Lemma 8.7]Falls u.rson() 6=↑return least(u.rson())

Großschritt 2. [Falle 1 und 2.2 von Lemma 8.7]Gehe vermoge der father-Referenz von u in Richtung root.Suche den ersten Vorfahren p von u, so daß p.lson() gleich u oder Vorfahre von u ist.Falls ein solcher Vorfahre nicht existiert,return ↑

Anderfallsreturn p

Offensichtlich gilt:

Aussage 8.14 Die Laufzeit fur die Aufrufe von previous(u) bzw. next(u) ist ein O (depth T ),wobei T der aktuelle Suchbaum ist.

38

Page 37: Skript Waack merged

Unter Verwendung von previous(u) und next(u) sind die Methoden previousElement()

bzw. nextElement() der Iterator-Klasse leicht zu implementieren. Wir beschranken unsauf previousElement().

Algorithmus 8.15 (Vorganger-Element einer Menge)

Methodenkopf:previousElement() returns Integer× Range

Rumpf:c← partner().cursor()cursor← partner().previous(c)k← c.key()r← c.data()return (k, r)

Aus Aussage 8.14 folgt, daß die Laufzeit von Algorithmus 8.15 und dem analogen Al-gorithmus fur nextElement() ein O (depth T ) ist. Dabei ist T der Wert des partner-Datenfeldes.

Wir fassen zusammen.

Satz 8.16 Die Laufzeit der Iterator-Operationen ist ein O (depth T ). Dabei ist T der zudurchlaufende Suchbaum.

8.2.5 Die Worterbuch-Operationen

Alle Methoden des folgenden Abschnitts gehoren zur Klasse BinarySearchTree.Der folgende Begriff ist in diesem Abschnitt von zentraler Bedeutung.

Definition 8.17 Sei T ein binarer Suchbaum. Fur jeden Schlussel k ∈ U ist der SuchpfadsearchpathT k in T nach k wie folgt induktiv definiert.

Tiefe −1. Der Suchpfad searchpathT k ist leer. (Ein binarer Suchbaum der Tiefe −1 istja selbst leer.)

Tiefe 0. Es ist searchpathT k = r(T ). (Ein binarer Suchbaum T der Tiefe 0 besteht nuraus der Wurzel r(T ).)

dր (d + 1). Ist

T = (T (left)r , r, T (right)

r )

ein binarer Suchbaum der Tiefe d + 1, so ist

searchpathT k =

r falls key r = k;

r, searchpathT

(left)r

k falls key r > k;

r, searchpathT

(right)r

k falls key r < k.

39

Page 38: Skript Waack merged

Uns interessiert der Endknoten von searchpathT k. Das folgende Lemma ist offensicht-lich.

Lemma 8.18 Sei T ein nichtleerer binarer Suchbaum, sei k ein Schlussel und sei searchpathT kder Suchpfad nach k in T .

Ist k in T nicht gespeichert, so ist ein Knoten v des Suchpfades searchpathT k genaudann dessen Endknoten, wenn folgendes gilt:

– Ist k < key v, so hat der Knoten v keinen linken Sohn.

– Ist key v < k, so hat der Knoten v keinen rechten Sohn.

Ist k in T gespeichert, so ist ein Knoten v des Suchpfades searchpathT k genau danndessen Endknoten, wenn key v = k ist.

Beispiel. In Abbildung 8.1 ist v7 der Endknoten des Suchpfades nach 27, Knoten v9 derEndknoten des Suchpfades nach 137. Der Knoten v13 der Endknoten des Suchpfades nach150.

Wir schreiben eine Hilfsmethode, die uns zu jedem Schlussel k den Endknoten desSuchpfades nach k berechnet.

Algorithmus 8.19 (Berechnung des letzten Knotens eines Suchpfades)

Methodenkopf:searchPath

(Integer k, Node v

)returns Node

Vorbedingung:Der ubergebene Knoten v gehort zum aktuellen Suchbaum T .

Nachbedingung:Ruckgabe des letzten Knotens des Suchpfades nach k in Tv.

Großschritt 1. [Basis]Fuhrereturn v

aus, falls eine der folgenden drei Bedingungen erfullt ist:- v.key() = k

- v.key() < k und v.rson() = ↑- v.key() > k und v.lson() = ↑

Großschritt 2. [Rekursion]Falls (v.key() > k)return searchPath

(k, v.lson()

)

Falls (v.key() < k)return searchPath

(k, v.rson()

)

Aussage 8.20 Die Laufzeit von Algorithmus 8.19 ist ein O (depth T ), wobei T der aktuellebinare Suchbaum ist.

40

Page 39: Skript Waack merged

Unter Verwendung von Algorithmus 8.19 konnen wir die Operationen lookUp imple-mentieren, die zum Datentyp Dictionary gehort.

Algorithmus 8.21 (Suche im aktuellen Worterbuch)

Methodenkopf:lookUp

(Integer k

)returns Range

Nachbedingungen:Gibt es einen Knoten u im aktuellen Suchbaum T mit u.key() = k, so

Ruckgabe von u.data().Andernfalls Ruckgabe von ↑.

Rumpf:Falls root() = ↑,return ↑

v← searchPath(k, root()

)

Falls (v.key() = k)return v.data()

return ↑

Aussage 8.22 Die Laufzeit von Algorithmus 8.21 ist ein O (depth T ), wobei T der aktuellebinare Suchbaum ist.

Wir kommen zum Einfugen eines Paares (k, r) ∈ U ×R in einen binaren Suchbaum T .Ist T leer, so muß der Wurzelknoten erzeugt und geeignet initialisiert werden.

Ist T nichtleer, so machen wir den Endknoten v des Suchpfades in T nach k ausfindig.Ist v der Trager des Schlussels k, so wird das Satellitendatum aktualisiert. Ist das nichtder Fall, so machen wir uns Lemma 8.18 zu Nutze:

Ist k < key v, so erzeugen wir einen neuen Knoten u als Trager fur das Paar (k, r) undmachen ihn zum linken Sohn von v. (Der neue Knoten u ist ein Blatt.)

Ist key v < k, so erzeugen wir einen neuen Knoten u als Trager fur das Paar (k, r) undmachen ihn zum rechten Sohn von v. (Der neue Knoten u ist ein Blatt.)

Algorithmus 8.23 (Einfugen)

Methodenkopf:insert

(Integer k, Range r

)

Großschritt 1. [Der aktuelle Suchbaum T ist leer.]Falls root() = ↑root← neues Objekt vom Typ Node

root().father ← root().lson← root().rson←↑root().key← k, root().data← r

return

41

Page 40: Skript Waack merged

Großschritt 2. [Der aktuelle Suchbaum T ist nichtleer.]v← searchPath(k, root())Falls v.key() = k

v.data← r

return

u← neues Objekt vom Typ Node

u.key← k, u.data← ru.lson← u.rson←↑u.father← v

Falls v.key() > k

v.lson← u

return

Falls v.key() < k

v.rson← u

Aussage 8.24 Die Laufzeit von Algorithmus 8.23 ist ein O (depth T ), wobei T der aktuellebinare Suchbaum ist.

Etwas anspruchsvoller ist der folgende Algorithmus.

Algorithmus 8.25 (Streichen)

Methodenkopf:delete

(Integer k

)

Großschritt 1. [Basis.]Falls root() = ↑, so fuhre aus:return

v← searchPath(k, root())Falls v.key() 6= k, so fuhre aus:return

Großschritt 2. [Der Knoten v ist Blatt.]Falls v.lson() = v.rson() = ↑, so fuhre aus:

Falls v = root(), so fuhre aus: root←↑Andernfalls fuhre aus:w← v.father()Falls w.rson() = v, so fuhre aus: w.rson()←↑Andernfalls fuhre aus: w.lson()←↑

return

Großschritt 3. [Der Knoten v hat genau einen Sohn.]Falls entweder v.lson() = ↑ oder v.rson() = ↑, so fuhre aus:w← einziger Sohn von v

Falls v = root(), so fuhre aus:

42

Page 41: Skript Waack merged

w.father←↑, root← w

return

u← v.father()Falls u.rson() = v, so fuhre aus: u.rson← w

Anderfalls fuhre aus: u.lson← w

w.father← u

return

Großschritt 4. [Der Knoten v hat zwei Sohne.]w← previous(v)Vertausche v.key mit w.key.Streiche w gemaß Großschritt 2 oder 3.Kommentar: w hat keinen rechten Sohn.

Die Großschritte 3 und 4 von Algorithmus 8.25 werden in den Abbildungen 8.2 und 8.3graphisch verdeutlicht.

w

w

u u

w

k

einziger Sohn von v

w = root

v = root

v

einziger Sohn von v

k

Vater von v

Abbildung 8.2: Illustration zu Algorithmus 8.25, Großschritt 3

43

Page 42: Skript Waack merged

k v

wk′

v

w

k′

kStreichen nach GS 3

Abbildung 8.3: Illustration zu Algorithmus 8.25, Großschritt 4

Aussage 8.26 Die Laufzeit von Algorithmus 8.25 ist ein O (depth T ), wobei T der aktuellebinare Suchbaum ist.

Wir erhalten.

Satz 8.27 Die Laufzeit der Worterbuch-Operationen lookUp, insert und delete ist einO (depth T ). Dabei ist T der aktuelle Suchbaum.

Bemerkungen.

• Wir haben in diesem Abschnitt einige rekursive Algorithmen betrachtet. Deren Vor-teil besteht in ihrer großen Ubersichtlichkeit. Insbesondere kann man den Korrekt-heitsbeweis durch vollstandige Induktion besonders einfach fuhren.

• Der Nachteil rekursiver Algorithmen im Vergleich zu einer analog arbeitenden ite-rativen Variante ist die vergleichsweise großere Laufzeit. Die Großenordnungen sindzwar gleich, aber ein Methodenaufruf ist deutlich aufwendiger als z.B. das Durchlau-fen einer Kante.

8.2.6 Die mittlere Tiefe kanonischer binarer Suchbaume

Wir bemerken, daß man sich beim Studium der Eigenschaften eines binaren Suchbaumesmit n Knoten o.B.d.A. auf den Fall beschranken kann, daß die Menge der verwendetenSchlussel gleich 1, 2, . . . , n ist: Bei n paarweise verschiedenen Schlusseln kommt es nichtauf die absolute Große des einzelnen Schlussel, sondern auf deren Großenverhaltnis unter-einander an.

Die Satellitendaten sind fur uns in diesem Abschnitt ohne Bedeutung und werden des-halb in der Notation unterdruckt.

44

Page 43: Skript Waack merged

Definition 8.28 Fur jede Permutation π der Schlusselmenge 1, 2, . . . , n erhalt man denkanonischen Suchbaum Tπ durch die Folge der Einfugeoperationen

T∅.insert(π(1)).insert(π(2)). . . . .insert(π(n)) (8.4)

Die Gesamtheit der Permutationen von n Elementen bezeichnen wir mit Sn. Formalgesehen ist eine Permutation π der Menge 1, 2, . . . , n eine bijektive Abbildung von1, 2, . . . , n nach 1, 2, . . . , n. Wir verwenden fur solche Permutationen π die folgendenNotationen:

(1 2 . . . n

π(1) π(2) . . . π(n)

)

oder gerne auch(π(1) π(2) . . . π(n)

).

Beispiel. Fur n = 6 und π =(2 3 5 6 4 1

)sieht der kanonische Suchbaum Tπ wie

in Abbildung 8.4 angegeben aus.

3

5

1

4 6

2

Abbildung 8.4: Der kanonischer Suchbaum Tπ fur π =(2 3 5 6 4 1

)

In diesem Abschnitt geht es uns darum, den Term

1

n!

π∈σn

depth Tπ

nach oben abzuschatzen. Zur Vereinfachung der Notation fuhren wir die folgenden Bezeich-nungen ein:

d(π) := depth Tπ (π ∈ Sn)

d(n) :=1

n!

π∈Sn

d(π)

45

Page 44: Skript Waack merged

Statt d(π) und d(n) werden wir die folgenden Großen studieren:

D(π) :=∑

v ist Blattvon Tπ

2depthTπ(v)

D(n) :=1

n!

π∈Sn

D(π)

Lemma 8.29 Es ist

d(n) ≤ log2 D(n). (8.5)

Beweis. Es gilt:

d(n) =∑

π∈Sn

1

n!log2

(2d(π)

)

≤ log2

(∑

π∈Sn

1

n!2d(π)

)

(Satz 2.9: Jensensche Ungleichung)

≤ log2

1

n!

π∈Sn

v ist Blattvon Tπ

2depthTπ(v)

= log2 D(n).

Lemma 8.30 Die Funktion D erfullt die folgende Rekursion.

D(0) = 0 (8.6)

D(1) = 1 (8.7)

D(n) =4

n

n−1∑

i=0

D(i) (n ≥ 2) (8.8)

Beweis.

Schritt 1. Der Induktionsanfang fur n = 0 und n = 1 folgt daraus, daß eine leere Summenach Definition gleich null ist, bzw. ein Baum mit genau einen Knoten auch genau einBlatt der Tiefe null hat.

Schritt 2. Um den Induktionsschritt ausfuhren zu konnen, fuhren wir die folgenden Be-zeichnungen ein:

– Die Menge Sn,i besteht aus allen Permutation π aus Sn mit π(1) = i. Das heißt,ein π aus Sn,i hat die Gestalt

(i π(2) π(3) . . . π(n)

). (8.9)

46

Page 45: Skript Waack merged

– Fur jedes π aus Sn,i definieren wir die Permutation π<i der Menge 1, 2, . . . , i−1,indem wir aus der Folge aus Gleichnung 8.9 alle Schlussel k mit k ≥ i streichen.(Beispiel: Ist n = 8, i = 4 und π gleich

(4 6 2 1 8 7 5 3

), so ist π<4 gleich

(2 1 3

).) Die Menge all dieser Permutationen ist Si−1.

– Fur jedes π aus Sn,i definieren wir die Permutation π>i der Menge i + 1, i +2, . . . , n, indem wir aus der Folge aus Gleichnung 8.9 alle Schlussel k mit k ≤ istreichen. (Beispiel: Ist n = 8, i = 4 und π gleich

(4 6 2 1 8 7 5 3

), so

ist π>4 gleich(6 8 7 5

).) Die Menge all dieser Permutationen bezeichnen wir

nicht ganz korrekt Sn−i. (Die Elemente, die permutiert werden, kommen ja nichtaus der Menge 1, 2, . . . , n − i sondern der Menge i + 1, i + 2, . . . , n gleicherMachtigkeit.)

– Die Abbildung ρn,i ordnet jeder Permutation π aus Sn,i das Paar (π<i, π>i) ausSi−1 × Sn−i zu.

Wir beobachten, daß fur jedes π ∈ Sn,i der kanonische Suchbaum

Tπ = (Tπ<i, r, Tπ>i

) (8.10)

ist, wobei der Wurzelknoten r mit dem Schlussel i markiert ist. Es folgt:

D(π) = 2 · (D(π<i) + D(π>i)) . (8.11)

Gleichung 8.11 ist der Grund dafur, daß man statt der Tiefe d(π) den Wert D(π)betrachtet.

Schritt 3. Wir zeigen, daß fur je zwei Permuationen π′ ∈ Si−1 und π′′ ∈ Sn−i die Anzahlderjenigen Permutationen π aus Sn,i, fur die ρn,i(π) = (π′, π′′) ist, gleich

(n−1i−1

)ist:

#ρ−1n,i(π

′, π′′) =

(n− 1

i− 1

)

. (8.12)

Wieviele Moglichkeiten hat man, aus einem Paar (π′, π′′) ∈ Si−1×Sn−i eine Permutationπ ∈ Sn,i zu konstruieren, fur die π<i = π′ und π>i = π′′ ist?

Die innere Ordnung der Permutationen der Elemente sowohl aus 1, 2, . . . , i − 1 alsauch aus i + 1, i + 2, . . . , n steht durch die Vorgabe von π′ bzw. π′′ fest. Ferner kannnur ein solches π gewahlt werden, fur das π(1) = i ist. Folglich konnen wir lediglich dieTeilmenge j1, j2, . . . , ji−1 mit j1 < j2 < . . . < ji−1 aus 1, 2, . . . , n \ 1 frei wahlen,fur die dann π(ik) = π′(k) (k = 1, 2, . . . i−1) ist. Da die Anzahl der (i−1)–Teilmengeneiner (n− 1)–Menge gleich dem Binomialkoeffizienten

(n−1i−1

)ist, folgt die Behauptung.

Schritt 4. Fur i = 1, 2, . . . , n betrachten wir den folgenden paaren Multigraphen Gi.

Die linke Knotenmenge Vi,1 ist gleich Sn,i. Die rechte Knotenmenge Vi,2 ist Si−1×Sn−i.

Die Kantenmenge Ei ⊆ Vi,1×Vi,2 von Gi ist wie folgt definiert: Ein Knoten π aus Vi,1 =Sn,i und ein (π′, π′′) aus Vi,2 = Si−1×Sn−i sind durch genau D(π) = 2 · (D(π′)+D(π′′))

47

Page 46: Skript Waack merged

(siehe Gleichung 8.11) Kanten verbunden, wenn π<i = π′ und π>i = π′′ ist. Andernfallsgibt es zwischen den beiden Knoten keine Kante.

Wir wenden das wohlbekannte Prinzip des Zahlens langs zweier Wege an. Es gilt:

|Ei| =∑

v∈Vi,1

degree v (Zahlung von links)

=∑

w∈Vi,2

degree w (Zahlung von rechts)

Angewendet auf unsere spezielle Situation erhalten wir fur die Zahlung von links undrechts:

|Ei| =∑

π∈Sn,i

D(π) (8.13)

bzw. unter Verwendung von Gleichung 8.11 und 8.12

|Ei| = 2 ·∑

π′∈Si−1

π′′∈Sn−i

(n− 1

i− 1

)

(D(π′) + D(π′′))

= 2 · (n− 1)!∑

π′∈Si−1

π′′∈Sn−i

(D(π′)

(i− 1)! · (n− i)!+

D(π′′)

(i− 1)! · (n− i)!

)

= 2 · (n− 1)!

1

(i− 1)!

π′∈Si−1

D(π′) +1

(n− i)!

π′′∈Sn−i

D(π′′)

= 2 · (n− 1)!(D(i− 1) + D(n− i)

)(8.14)

Wir erhalten aus den Gleichungen 8.13 und 8.14 durch Summation uber i = 1, 2 . . . , n:

n∑

i=1

|Ei| =n∑

i=1

π∈Sn,i

D(π)

= n! · D(n) (Summe uber die Gleichungen 8.13) (8.15)

= 2 · (n− 1)!n∑

i=1

(D(i− 1) + D(n− i)

)

= 4 · (n− 1)!n−1∑

i=1

D(i) (Summe uber die Gleichungen 8.14) (8.16)

Die Gleichungen 8.15 und 8.16 ergeben unsere Behauptung:

D(n) =4

n−1∑

i=1

D(i)

48

Page 47: Skript Waack merged

Lemma 8.30 bildet die Grundlage fur den Beweis des folgenden Lemmas:

Lemma 8.31 Fur k ≥ 2 gilt:

D(k) =(k + 3) · (k + 2) · (k + 1)

30(8.17)

Beweis. Man uberpruft ferner leicht, daß D(2) = 2 ist.Sei k ≥ 3. Wir ziehen die mit k multiplizierte Gleichung 8.8 fur n = k von der mit

(k − 1) multiplizierten Gleichung 8.8 fur n = k − 1 ab und erhalten:

k · D(k) − (k − 1) · D(k − 1) = 4 · D(k − 1) (8.18)

Es folgt:

D(k) =k + 3

k· D(k − 1) (8.19)

Indem wir Gleichung 8.19 iteriert in sich selbst einsetzen, erhalten wir:

D(k) =(k + 3) · (k + 2) · (k + 1) · k · (k − 1) · . . . · 6

k · (k − 1) · . . . · 3 · D(2)

=(k + 3) · (k + 2) · (k + 1)

3 · 4 · 5 · D(2) (8.20)

Aus Gleichung 8.20 folgt unter Verwendung von D(2) = 2 die Behauptung.

Aus Gleichung 8.5 und Lemma 8.31 folgt Satz 8.32.

Satz 8.32 Es gilt:

1

n!

π∈σn

depth Tπ = O (log n) .

Satz 8.32 scheint die folgende Aussage zu rechtfertigen: Die erwartete Laufzeit fur dieWorterbuch–Operationen lookUp(k), insert(k), delete(k) und die IteratormethodennextElement(), previousElement() und hasElements() auf binaren Suchbaumen mit nKnoten ist ein O (log n).

Wie sind wir vorgegangen? Wir haben auf den binaren Suchbaumen mit fester Knoten-zahl, die ja der Großenparameter ist, eine Verteilung festgelegt. (Gleichung 8.12 zeigt, daßin unserem Modell

”buschige“ Suchbaume deutlich wahrscheinlicher sind, als langgestreck-

te.) Die Laufzeit unserer Algorithmen auf einen konkreten Suchbaum wurde mit dessenWahrscheinlichkeit gewichtet.

Das Problem ist, daß wir dadurch ein Nutzerverhalten unterstellt haben. Wenn das realeNutzerverhalten mit dem angenommen schlecht ubereinstimmt, beschreiben Aussagen wieSatz 8.32 die in der Praxis vorkommenden Laufzeiten nicht. Fur diesen Fall gibt es zweiAuswege:

49

Page 48: Skript Waack merged

1. Die binaren Suchbaume lassen sich zu den sogenannten Rot-Schwarz-Baumen auf-rusten. Diese werden in jedem Schritt rebalanciert, so daß die Tiefe stets ein O (log n)ist (siehe [CLRS01]).

2. Im Abschnitt 8.3 werden wir die Algorithmen randomisieren: Im Verlauf der Rech-nung werden Zufallsexperimente ausgefuhrt. Die Laufzeit des Algorithmus auf eineEingabe wird zur zufalligen Variablen, deren Erwartungswert wir abschatzen werden.Der praktische Wert dieser Ergebnisse ist nicht mehr vom Nutzerverhalten abhangig.

8.3 Hashing

Im Abschnitt 8.2 haben wir eine Datenstruktur studiert, bei der sowohl die Worterbuch-als auch die Iterator-Operationen mittlere Laufzeit O (log n) haben, wobei n die Anzahlder aktuell gehaltenen Datensatze ist. In diesem Abschnitt werden wir eine Technik ken-nenlernen, die es uns gestattet, die Worterbuch-Operationen in mittlerer Zeit O (1) durch-zufuhren. Ja, wir werden dahin gelangen, daß wir diese Zeit auch stets erwarten konnen.Der Preis dafur ist, daß sich die Effektivitat der Iterator-Operationen verschlechtert. Hiererhalten wir nur Laufzeiten der Großenordnung O (n).

8.3.1 Der Ansatz

Im Abschnitt 8.2 war das Universum U der moglichen Schlussel ein Intervall [u, o] aus denganzen Zahlen Z. In unserem einleitenden Beispiel ist U gleich der Menge aller Worter derLange λ ∈ [3, ℓmax] uber dem Standardalphabet a, . . . z, A, . . .Z.

Wir wollen in unserem Worterbuch eine Menge S ⊂ U der Große n halten. Das sollvermoge einer Hashfunktion

hm = h : U −→ 0, 1, . . . , m− 1

geschehen, welche die Schlussel aus der Menge S auf m Buckets B0, B1, . . ., Bm−1 in derWeise verteilt, daß

Bi = x ∈ S | h(x) = i (i = 0, 1, . . . , m− 1)

gilt.Dazu ordnen wir zunachst jedem Buchstaben aus a, . . . z, A, . . .Z einen numerischen

Wert zu:

num a = num A = 0

num b = num B = 1

. . . . . .

num z = num Z = 25

50

Page 49: Skript Waack merged

Nun betrachten wir als Beispiel den Fall m = 13 und definieren unsere Hashfunktion

h(b0b1b2 . . . bλ−1) := num b2 mod 13. (8.21)

Ist nun S := Januar, Februar, Maerz, . . . , Dezember diejenige Schlusselmenge derGroße n = 12, die es vermoge h auf die 13 Buckets zu verteilen gilt, so erhalt man:

B0 = Januar, Juni B1 = Februar B2 = SeptemberB3 = ∅ B4 = Maerz, April B5 = ∅B6 = August, Oktober B7 = ∅ B8 = Mai, NovemberB9 = ∅ B10 = ∅ B11 = JuliB12 = Dezember

Die Buckets werden als Array B[0, m) der Lange m implementiert. Wir sprechen voneiner Hashtabelle. (Die Bezeichnung

”[0, m)“ fur die Grenzen der Feldindizes lehnt sich an

die ubliche Benennung halboffener Intervalle an: Die Zahl 0 ist der erste Feldindex, dieZahl m ist keiner mehr. Der Vorteil dieser Notation besteht darin, daß sich die Feldlangeaus der Differenz des oberen und des unteren Index ergibt.)

In unserem Beispiel gibt es Buckets, B0 = B[0] zum Beispiel, die zwei Schlussel ent-halten. Wir sprechen von einer Kollision. Im Idealfall liegen keine Kollisionen vor. Das istoffensichtlich genau dann der Fall, wenn die Hashfunktion h eingeschrankt auf die zu spei-chernde Schlusselmenge S injektiv ist. Eine solche Hashfunktion nennen wir fur S perfekt.

Naturlich stellen Kollisionen ein Problem dar, das man moglichst klein halten will. Sielassen sich nur dann definitiv ausschließen, wenn es immer soviele Buckets wie Schlussel imUniversum U gibt. Das ist keine praktikable Losung. Aber vielleicht kann man erreichen,daß Kollisionen sehr selten sind, wenn man sich nur geschickt genug bei der Festlegung derAnzahl der Buckets in Abhangigkeit von der Anzahl der zu speichernden Schlussel und beider Auswahl der Hashfunktion verhalt. Wir werden diese Frage im folgenden diskutieren.

Wir benotigen den folgenden Begriff.

Definition 8.33 Ist h : U → [0, m) eine Hashfunktion, langs derer wir eine SchlusselmengeS, die aus n Elementen besteht, auf die Buckets B0, B1, . . ., Bm−1 verteilt haben. Dannheißt die Zahl

α :=n

m

der (aktuelle) Auslastungsfaktor der Hashtabelle B[0, m).

Im vorstehenden Beispiel betragt der Auslastungsfaktor 1213

, ist also fast gleich eins.Vielleicht muß der Auslastungfaktor nur um einige Großenordnungen kleiner sein, um Kol-lisionen sehr unwahrscheinlich zu machen?

Um uberhaupt von einer Kollisionswahrscheinlichkeit reden zu konnen, benotigen wirein stochastisches Modell, das beschreibt, wie die zu speichernde Schlusselmenge S zufalligaus dem Universum ausgewahlt wird. Folgendes setzen wir stets voraus.

Grundannahmen (GA).

51

Page 50: Skript Waack merged

1. Die Machtigkeit n der auszuwahlenden Schlusselmenge S ⊂ U ist kleiner oder gleichder Anzahl der Buckets m. Beide Zahlen sind deutlich kleiner als die Große desUniversums U :

n ≤ m≪ |U|. (8.22)

2. Der Auslastungsfaktor α = nm

ist durch eine universelle reelle Konstante α0 ∈ (0, 1)nach unten beschrankt:

α0 < α ≤ 1, (8.23)

Der linke Teil von Ungleichung 8.23 zeigt an, daß wir keinen Platz im Hauptspeicherzu vergeuden haben und eine lineare Auslastung der Hashtabelle wunschen.

3. Die Hashfunktion h : U → [0, m) partitioniert das Universum U in Blocke Ui :=x | h(x) = i. Wir wollen nicht soweit gehen zu fordern, daß all diese Blocke nahe-rungsweise die gleiche Große haben mussen. Es muß aber wenigstens gesichert sein,daß alle Schlussel auch aus einem Block gewahlt werden konnen:

n≪ |Ui| (i = 0, 1, . . . , m− 1). (8.24)

Wie soll die zufallige Auswahl der Schlussel erfolgen? Wir betrachten eine Folge von Zu-fallselementen X0, X1, . . . , Xn−1 aus dem Universum U , welche die folgenden Eigenschaftenhaben.

Uniformitatsannahme (UF).

1. Es wird eine Menge ausgewahlt: Fur i 6= j gilt: Xj 6= Xi.

2. Die vermoge der Hashfunktion h transformierten Zufallsschlusselh(X0), h(X1), . . . , h(Xn−1) sind eine Folge von unabhangigen Zufallsvariablenaus 0, 1, . . . , m − 1. Daruber hinaus ist fur alle i = 0, 1, . . . , n − 1 die zufalligeVariable h(Xi) uber 0, 1, . . . , m− 1 gleichverteilt :

P (h(Xi) = j) = 1/m, fur alle j ∈ 0, 1, . . . , m− 1.Informatiker sprechen bei einer Folge unabhangiger gleichverteilter Zufallselemente ger-

ne von dem reinen Zufall. (UF) besagt in dieser Terminologie, daß keine zwei Schlusselgleich und die Hashwerte der Schlussel rein zufallig sind.

Zur Risikoabschatzung von Kollisionen erscheint ein stochastisches Modell mit (UF) alssinnvoll. Aber gibt es ein solches Modell uberhaupt? Der folgende stochastische Prozeß isteine mogliche Umsetzung. Wir beschreiben ihn in Algorithmus 8.34.

Algorithmus 8.34 (Auswahl zufalliger Schlussel unter (GA) und (UF))

52

Page 51: Skript Waack merged

Großschritt 1.Initialisiere die Blocke Uj = h−1(j) (j = 0, 1, . . . , m− 1).

Großschritt 2.Fur i = 0, 1, . . . , n− 1 fuhre aus:

Wahle ein j ∈ 0, 1, . . . , m− 1 zufallig aus.Wahle zufallig einen Schlussel xi ∈ Uj aus.Vermindere Uj um den soeben gezogenen Schlussel xi.Berechne h(xi)

Kommentar:Die soeben beschriebene Folge zufalliger Schlussel ist nicht unabhangig.

Warum sind die h(X0), h(X1), . . . , h(Xn−1) eine Folge unabhangiger gleichverteilter Zu-fallselemente aus 0, 1, . . . , m − 1? Algorithmus 8.34 ist so angelegt, daß fur alle i =1, 2, . . . , n− 1 und alle j0, . . . , ji, j ∈ 0, 1, . . . , m− 1

P (h(X0) = j) = P (h(Xi+1) = j | h(X0) = j0, . . . , h(Xi) = ji ) = 1/m

ist. Die Behauptung folgt aus den Aussagen des Abschnitts 3.1.Man beachte, daß Algorithmus 8.34 wenigstens im Rahmen unserer Darstellung nicht

dazu gedacht ist, implementiert und ausgefuhrt zu werden. Er ist vielmehr der Nachweis derExistenz unseres Modells des Nutzerverhaltens fur die Abschatzung des Kollisionsrisikos.

Lemma 8.35 Aus (UF) folgt, daß

P (h ist fur X0, X1, . . . , Xn−1 perfekt) ≤ e−(α0/2)·(n−1). (8.25)

Beweisskizze. Wir betrachten den stochastischen Prozesses der Wertannahmen der Fol-ge h(X0), h(X1), . . . , h(Xn−1). Es gilt:

P (h ist fur X0, X1, . . . , Xn−1 perfekt) =m

m· m− 1

m· . . . · m− i

m· . . . · m− n + 1

m,

denn fur i = 0, 1, . . . , n−1 sind bei fur h(Xi) m Falle moglich und alle gleichwahrscheinlich,aber nur m− i Falle gunstig. Naturlich ist

m

m· . . . · m− i

m· . . . · m− n + 1

m=

(

1− 1

m

)

· . . . ·(

1− i

m

)

· . . . ·(

1− n− 1

m

)

.

Wegen 1 + x < ex fur x 6= 0 erhalten wir:

(

1− 1

m

)

· . . . ·(

1− n− 1

m

)

< e−1/m·Pn−1

i=1 i = e−(n/2m)·(n−1) ≤ e−(α0/2)·(n−1).

53

Page 52: Skript Waack merged

Lemma 8.35 zeigt uns, daß wir uns mit Kollisionen arrangieren mussen, denn die Wahr-scheinlichkeit, daß h fur S perfekt ist, geht gemaß Gleichung 8.25 exponentiell in n = |S|gegen null.

Fur n = 365 und m = 23 ist die linke Seite von Gleichung 8.25 die Wahrscheinlich-keit dafur, daß unter 23 zufallig ausgewahlten Personen wenigstens zwei an demselben TagGeburtstag haben. Diese Wahrscheinlichkeit ist großer als 1

2. Man spricht vom

”Geburts-

tagsparadoxon“.

8.3.2 Offenes Hashing

Die wohl naheliegendste Kollisionsbewaltigung besteht darin, die Buckets als verketteteListen zu implementieren:

B[0, m) of LinkedList

Jedes Bucket B[i] ist also eine verkettete Liste und eine neu auftretende Kollision wirddadurch aufgelost, daß die Liste des entsprechenden Buckets um eins verlangert wird.

Im Sinne der objektorientierten Programmierung schreibt man eine Klasse, der manden Namen OpenHashTable geben kann, die als Hauptdatenfeld hashTable ein Array vonverketteten Listen enthalt. (Uber den Aufruf hashTable.length() haben wir den Zugriffauf die Anzahl der Buckets m.) Wir allerdings werden die Bezeichnung hashTable seltenverwenden und die mathematische Bezeichnung B bevorzugen.

Eine Methode zur Berechnung von hm(x) = h(x), sofern es sich nicht um Standardfunk-tionen handelt, gehort ebenso zu dieser Klasse wie alle anderen Methoden, die in diesemAbschnitt folgen.

Wir nehmen an, daß die Knoten unserer Listen die Schlussel (z.B. bei einem Schlusse-luniversum aus dem Bereich der ganzen Zahlen) oder die Zeiger auf die Schlussel (z.B.bei Zeichenketten als Schlusseln) und die Zeiger auf die Satellitendaten in derselben Weiseverwalten, wie es bei den Knoten binarer Suchbaume der Fall war: Halt man den Knoten,so kostet der Zugriff auf den Schlussel und das Satellitendatum Zeit O (1).

Annahme. Die Natur des Datentyps Key des Universums der Schlussel U und die Strukturder Hashfunktionen — wir haben ja fur jedes m eine — h : U → [0, m) gestatten es, furjeden Schlussel x aus U den Hashwert h(x) in Zeit O (1) zu berechnen.

Die nun folgenden Algorithmen sind besonders einfach.

Algorithmus 8.36 (Erzeugen einer leeren Hashtabelle mit m Buckets)

Methodenkopf:empty

(Integer m

)

Rumpf:Erzeuge ein Feld von leeren verketteten Listen der Lange m.Initialisiere das Datenfeld hashTable mit diesem Feld.

54

Page 53: Skript Waack merged

Algorithmus 8.37 (Einfugen in die Hashtabelle)

Methodenkopf:insert

(Key k, Range r

)

Nachbedingungen:Das Paar (k, r) ∈ U ×R ist in B[0, m) gespeichert.

Großschritt 1.Berechne i← h(k)

Großschritt 2.Falls k in B[i] mit Satellitendatum r′ vorkommt,

uberschreibe r′ durch rreturn.

Fuge einen neuen Knoten, der (k, r) tragt, der Liste B[i] hinzu.

Algorithmus 8.38 (Streichen aus der Hashtabelle)

Methodenkopf:delete

(Key k

)

Nachbedingungen:Kein Paar (k, r) ∈ U ×R ist in B[0, m) gespeichert.

Großschritt 1.Berechne i← h(k)

Großschritt 2.Falls k in B[i] vorkommt,

streiche den Tragerknoten aus der Liste B[i].

Algorithmus 8.39 (Suche in der Hashtabelle)

Methodenkopf:lookUp

(Key k

)returns Range

Nachbedingungen:Ist ein Paar (k, r) ∈ U ×R in B[0, m) gespeichert, so Ruckgabe von r.Andernfalls Ruckgabe von ↑.

Großschritt 1.Berechne i← h(k)

Großschritt 2.Falls k in B[i] mit Satellitendatum r vorkommt,return r.

return ↑

55

Page 54: Skript Waack merged

Die folgende Aussage ist offensichtlich.

Aussage 8.40 Die Laufzeit von Algorithmus 8.36 ist ein O (m), wobei m die ubergebeneAnzahl von Buckets ist.

Die Algorithmen 8.37, 8.38 und 8.39 haben eine Laufzeit von

O (1 + Anzahl der Schlusselvergleiche) .

Die Anzahl der Schlusselvergleiche wiederum ist nach oben durch die Lange |B[h(k)]| derh(k)-ten Liste beschrankt, wobei k der an die jeweilige Methode ubergebene Schlussel ist.

Der Kern einer mittleren Laufzeitanalyse ist nach Aussage 8.40 die Bestimmung dermittleren Listenlange. Eine Inspektion der Algorithmen 8.37, 8.38 und 8.39 zeigt, daß dieentscheidenden Kosten durch die Suche nach dem Schlussel x verursacht werden, welcherder jeweiligen Methode ubergeben worden ist. Wir wollen diesen

”Teilalgorithmus“ mit

search(x) bezeichnen. Bei unserer Analyse unterscheiden wir drei Falle. Dazu benotigenwir die folgenden Bezeichnungen:

Zufallige Hashtabelle B(X0, X1, . . . , Xn−1). Sei X0, X1, . . . , Xn−1, Xn eine Folge von Zu-fallselementen aus U . Dann ist B(X0, X1, . . . , Xn−1) die Hashtabelle, die man erhalt,wenn man die Schlussel X0, X1, . . . , Xn−1 in die leere Hashtabelle mit m Bucketslangs der Hashfunktion h = hm nacheinander einfugt.

Erfolglose Suche. Wir fragen nach der erwarteten Anzahl von Schlusselvergleichen furdie Operation

B(X0, X1, . . . , Xn−1).search(Xn). (8.26)

Erfolgreiche Suche nach einem festen Schlussel aus der Hashtabelle. Wir suchennach einem der Schlussel Xi, wobei i ∈ 0, 1, . . . , n − 1 beliebig aber fest ist. Unsinteressiert also die erwartete Anzahl von Schlusselvergleichen fur die Operation

B(X0, X1, . . . , Xn−1).search(Xi). (8.27)

Erfolgreiche Suche nach einem rein zufalligen Schlussel aus der Hashtabelle. Ge-sucht wird nach XI , wobei der Index I aus 0, 1, . . . , n− 1 rein zufallig ist. Es gehtum die erwartete Anzahl von Schlusselvergleichen fur die Operation

B(X0, X1, . . . , Xn−1).search(XI). (8.28)

Wir benotigen das folgende sehr einfache Lemma.

Lemma 8.41 Es ist

P (h(Xν) = h(Xµ)) =1

m(ν 6= µ).

56

Page 55: Skript Waack merged

Beweis. Die Aussage ist eine unmittelbare Folge dessen, daß die h(X0), h(X1), . . . , h(Xk)eine Folge von unabhangigen und gleichverteilten Zufallsvariablen aus 0, 1, . . . , m−1 sind.

Wir schwachen fur unsere Zufallsschlussel die Uniformitatsforderung (UF) ab. Fur denspateren Ubergang zum universellen Hashing ist das methodisch gunstig.

Eine Folge X0, X1, . . . , Xk aus U erfullt die abgeschwachte Uniformitatsbedingung(UFab), wenn

P (Xν = Xµ) = 0 und P (h(Xν) = h(Xµ)) ≤1

m(ν 6= µ). (8.29)

ist.

Lemma 8.41 sichert, daß eine Folge zufalliger Schlussel mit (UF) auch die abgeschwachteUniformitatsbedingung (UFab) erfullt. Wir nehmen bis zum Ende dieses Abschnittes an,daß fur die Schlusselfolge X0, X1, . . . , Xn die abgeschwachte Uniformitatsbedingung (UFab)gilt.

Lemma 8.42 Sei B := B(X0, X1, . . . , Xn−1).Die erwartete Anzahl der Schlusselvergleiche fur die erfolglose Suche in B (siehe Glei-

chung 8.26) ist kleiner oder gleich

α =n

m.

Die erwartete Anzahl der Schlusselvergleiche fur die erfolgreiche Suche in B nach einemfesten Schlussel aus der Hashtabelle (siehe Gleichung 8.27) ist nach oben durch

1 +n− 1

m< 1 + α

beschrankt.Die erwartete Anzahl der Schlusselvergleiche fur die erfolgreiche Suche in B nach einem

rein zufalligen Schlussel aus der Hashtabelle (siehe Gleichung 8.28) ist nach oben durch

1 +n− 1

2m< 1 +

α

2

beschrankt.

Beweis. Fur alle i, j ∈ 0, 1, . . . , n mit i 6= j definieren wir die Zufallsvariable Yij wiefolgt:

Yij =

1 falls h(Xi) = h(Xj);

0 andernfalls.

57

Page 56: Skript Waack merged

Aus Gleichung 8.29 erhalten wir unmittelbar.

E Yij = P (Yij = 1) = P (h(Xi) = h(Xj)) ≤1

m

Um die in Rede stehenden Anzahlen abschatzen zu konnen, benotigen wir n + 1 weiterezufallige Variablen.

Zi := #j | 0 ≤ j ≤ n− 1, h(Xi) = h(Xj) (i = 0, 1, . . . , n)

Fur i = 0, 1, . . . , n ist Zi die Lange der Liste von B(X0, X1, . . . , Xn−1), in der sich Xi

befindet. Der Wert von Zn ist die Lange der Liste von B(X0, X1, . . . , Xn−1), in die man Xn

einordnen mußte.

Bei der erfolglosen Suche ist Zn die Lange derjenigen Liste, die wir nach Xn vollstandig,aber vergeblich durchsuchen mussen. Wir mussen den Erwartungswert von Zn ausrechnen,um den ersten Teil des Lemmas zu beweisen. Offenbar ist

Zn =

n−1∑

j=0

Yjn.

Aus der Linearitat der Erwartung erhalten wir

E Zn =n−1∑

j=0

E Yjn ≤n

m.

Bei der erfolgreichen Suche nach Xi ist Zi (i = 0, 1, . . . , n− 1) die Lange der Liste, in derwir nach dem Schlussel suchen werden. Da in dieser Liste in jedem Falle der Schlussel Xi

enthalten ist, ist fur i = 0, 1, . . . , n− 1

Zi = 1 +

n−1∑

j=1j 6=i

Yji.

Die Linearitat der Erwartung liefert in diesem Falle

E Zi = 1 +n−1∑

j=1j 6=i

E Yji ≤ 1 +n− 1

m< 1 +

n

m.

Fur die Abschatzung der erwarteten Anzahl von Schlusselvergleichen bei der erfolgrei-chen Suche nach einem rein zufalligen Schlussel aus der Hashtabelle mussen wir eine etwasfeinere Klinge schlagen. Die zufallige Variable

Li := #j | h(Xj) = i, fur ein j mit 0 ≤ j ≤ n− 1 (i = 0, 1, . . . , m− 1) (8.30)

58

Page 57: Skript Waack merged

beschreibt die Lange des i-ten Buckets von B(X0, X1, . . . , Xn−1). Sucht man nach jedemdieser Li Schlussel, so braucht man

1 + 2 + . . . + Li =

(Li + 1

2

)

=

(Li

2

)

+ Li

Vergleiche. Der gesuchte Erwartungswert ist folglich gleich

1

n

m−1∑

i=0

((Li

2

)

+ Li

)

=1

n

m−1∑

i=0

(Li

2

)

+1

n

m−1∑

i=0

Li

︸ ︷︷ ︸

=n

.

Wegen

m−1∑

i=0

(Li

2

)

=∑

i6=j

Yij

und (UFab) ist er gleich

1 +1

n

i6=j

E Yij ≤ 1 +1

n

n(n− 1)

2

1

m= 1 +

n− 1

2m< 1 +

α

2.

Nun ist der Beweis des folgenden Satzes kein Problem mehr. Er folgt direkt aus Aussage8.40 und Lemma 8.42.

Satz 8.43 Ist α der aktuelle Auslastungsfaktor der Hashtabelle, so ist in einem stochasti-schen Modell mit (UFab) die erwartete Laufzeit jeder der Operationen insert, delete undlookUp ein O (1 + α).

8.3.3 Uber die Laufzeit im schlechtesten Fall

Eine Aussage uber den Erwartungswert einer zufalligen Variablen X beinhaltet zunachstnichts uber die Abweichung von X von E X. Das leistet z.B. die Tschebyschewsche Unglei-chung (siehe Satz 3.8):

P (|X − E X| ≥ α) ≤ VarX

α2,

wobei VarX die Varianz von X ist (siehe Definition 3.6). Leider haben wir mit den Zu-fallsvariablen timeinsert, timedelete und timelookUp aus Satz 8.43 ein Problem: Wir kennenihre Varianzen nicht.

Im Satz 8.44 werden wir fur zufallige Schlussel X0, X1, . . . , Xn−1 mit (UF) — die Bedin-gung (UFab) reicht dazu leider nicht aus — Abhilfe schaffen. Wie ublich, bezeichnen wir

59

Page 58: Skript Waack merged

mit B(X0, X1, . . . , Xn−1) die zufallige Hashtabelle mit m Buckets, die dadurch entsteht,daß man diese Schlussel von links nach rechts in die leere Hashtabelle mit m Buckets langsder Hashfunktion h = hm einordnet. Wir werden die Lange des langsten Buckets studieren.Das rechtfertigt auch die Uberschrift dieses Abschnitts.

Uns interessiert das schlechteste Bucket von B(X0, X1, . . . , Xn−1). Dessen Lange wirddurch die zufallige Variable

L := maxLi | i = 0, 1, . . . , m− 1beschrieben, wobei die Zufallsvariablen Li fur i = 0, 1, . . . , m−1 in Gleichung 8.30 definiertworden sind.

Schließlich benotigen wir die großte monoton wachsende zahlentheoretische Linksinverse— siehe Abschnitt 1.3 fur allgemeine Betrachtungen zu diesem Thema — der Fakultats-funktion fak r := r!, die wir hier mit λ bezeichnen wollen:

λ(m) := minr | r! ≥ m.

Naturlich heißt das insbesondere

λ(m)! ≥ m. (8.31)

Man weiß, daß λ(m) zu der Funktion lnmln lnm

asymptotisch aquivalent ist:

limm→∞

ln m

λ(m) · ln ln m= 1.

Satz 8.44 Unter den vorstehend genannten Voraussetzungen ist

P (L ≥ 3 · λ(m)) <1

m2. (8.32)

Beweis.

Schritt 1. Sei zunachst i ∈ 0, 1, . . . , m fixiert. Wir zeigen, daß fur jedes naturliche r > 1

P (Li ≥ r) <1

r!(8.33)

ist. In der Tat, es ist

Li ≥ r ⇐⇒ ∃T ⊆ 0, 1, . . . , n− 1 : |T | = r und h(xj) = i, fur alle j ∈ T .

Es folgt:

P (Li ≥ r) ≤∑

T⊆0,1,...,n−1|T |=r

P (h(Xj) = i, fur alle j ∈ T )︸ ︷︷ ︸

= 1mr (wegen (UF))

≤(

n

r

)

· 1

mr=

n · (n− 1) · . . . · (n− r + 1)

r! ·mr<

nr

mr· 1

r!

≤ 1

r!(wegen n ≤ m).

60

Page 59: Skript Waack merged

Schritt 2. Nun zeigen wir, daß

P (L ≥ r) <m

r!(8.34)

ist. Wegen

L ≥ r ⇐⇒ ∃i ∈ 0, 1, . . . , m− 1 mit Li ≥ r

folgt Gleichung 8.34 aus Gleichung 8.33, da die Wahrscheinlichkeit der Alternative vonEreignissen durch die Summe der Wahrscheinlichkeiten der Einzelereignisse nach obenabgeschatzt werden kann (siehe Ungleichung 3.7).

Schritt 3. Schließlich ist

P (L ≥ 3 · λ(m)) <m

(3 · λ(m))!(Gleichung 8.34)

=m

λ(m)!︸ ︷︷ ︸

≤1

· 1

(λ(m) + 1) · (λ(m) + 2) · . . . · (3λ(m))︸ ︷︷ ︸

< 1λ(m)!·λ(m)!

≤ 1m2 (Gl. 8.31)

<1

m2.

8.3.4 Die Verdopplungsstrategie

In den Anwendungen kann es sein, daß die Anzahl der zu speichernden Schlussel nurgeringfugig um einen bekannten Mittelwert schwankt. Dann ist klar, mit welcher Großeman die Hashtabelle anzulegen hat.

Kann die Große der Tabelle nicht abgeschatzt werden, oder sind gar große Schwan-kungen abzusehen, so benutzt man die Verdopplungsstrategie. Um sie implementieren zukonnen, halt man in einem Datenfeld pegel die Anzahl der aktuell gespeicherten Schlusseln. Die Lange m der Hashtabelle ist uber eine Methode length() des Feldes B jederzeitabrufbar.

– Am Anfang wird eine Hashtabelle mit einer passenden Lange m0 angelegt.

– Hat der aktuelle Auslastungsfaktor α = pegel

B.length()eine vorher festgelegte untere

Schranke α0 ∈ (0, 1) erreicht, so wird eine neue Hashtabelle mit halbierter Langeangelegt und der Inhalt der alten Hashtabelle Eintrag fur Eintrag umgespeichert.(Es ist sinnvoll, die Lange der Hashtabelle nicht unter eine globale untere Schrankefallen zulassen.)

– Hat der aktuelle Auslastungsfaktor α = pegel

B.length()eine vorher festgelegte obere Schran-

ke α1 ∈ (α0, 1] erreicht, so wird eine neue Hashtabelle mit verdoppelter Lange ange-legt und der Inhalt der alten Hashtabelle Eintrag fur Eintrag umgespeichert.

61

Page 60: Skript Waack merged

Wie sieht es mit der Laufzeitanalyse in diesem Fall aus? Wir haben es mit zwei unter-schiedlichen Arten der Operationsausfuhrung zu tun.

1. Im”gewohnlichen Geschaftsgang“— wenn nach der Operationsausfuhrung der Aus-

lastungsfaktor α ∈ (α0, α1) ist – ist Satz 8.43 anwendbar: Alle Operationen kostenkonstante Zeit.

2. Von Zeit zu Zeit muß jedoch umgespeichert werden. Verglichen mit dem konstantenZeitaufwand fur die Operationsausfuhrung im gewohnlichen Geschaftsgang sind dieseOperationen außerst kostspielig: Θ(n), wobei n die aktuelle Anzahl der gespeichertenElemente ist.

Unter Verwendung der sogenannten Tilgungskostenanalyse (siehe Abschnitt 11.2)werden wir sehen, daß wenn wir dennoch im Mittel je Operation nur einen Zeitbedarfvon O (1) haben.

8.3.5 Einige einfache Hashfunktionen

Die Kriterien fur die Qualitat von Hashfunktionen h sind

1. die schnelle Berechenbarkeit von h(x) (moglichst in Zeit O (1)) und

2. die gute Streuung”oft“ vorkommender Schlusselmengen uber die Buckets.

Das Universum besteht aus naturliche Zahlen

Wir betrachten Hashfunktionen

h : U = 0, 1, . . . , u− 1 → 0, 1, . . . , m− 1.Die Divisionsrestmethode. h(x) := x mod m, fur eine Primzahl m.

Diese Hashfunktionen sind sehr einfach und effizient. Allerdings gibt es Beispiele ka-nonisch auftretender Schlusselmengen (z.B. in Zahlen ubertragene Strings, bei denengroße Buckets auftreten konnen.)

Die Multiplikationsmethode. h(x) := ⌊((ϑ · x) mod 1) ·m⌋, fur ein 0 < ϑ < 1 (idealist ein irrationales ϑ). Dabei ist (ϑ · x) mod 1 der gebrochene Anteil von ϑ · x, alsogleich ϑ · x− ⌊ϑ · x⌋.Beispiel. Fur ϑ = 1

2(√

5− 1) ≈ 0, 6180 und m = 100 ist

h(100) = ⌊(100ϑ mod 1) · 100⌋= ⌊(61, 80 . . . mod 1) · 100⌋= 80

h(101) = ⌊(101ϑ mod 1) · 100⌋= ⌊(62, 42 . . . mod 1) · 100⌋= 42

62

Page 61: Skript Waack merged

Man kann zeigen, daß die Hashfunktion mit diesem ϑ konsekutive Schlussel sehr gutverteilt.

Das Universum besteht aus Strings

Ist U = Σℓ fur ein Alphabet Σ (z.B. die ASCII-Zeichen), dann gibt es stets eine kanonischeFunktion

num : Σ→ 0, 1, . . . , |Σ| − 1,

die jedem Buchstaben seinen numerischen Wert zuordnet. Wir betrachten Hashfunktionen

h : Σℓ → 0, 1, . . . , m− 1.

Lineare Funktionen uber Zp. Dazu muß m = p > |Σ| eine Primzahl sein. Die Bedin-gung p > |Σ| sichert, daß der numerische Wert num σ jedes Buchstabens σ ∈ Σ imkanonischen Reprasentantensystem 0, 1, . . . , p− 1 mod p liegt. Man wahlt Koef-fizienten a0, . . . , aℓ−1 ∈ 0, 1, . . . , p− 1 und setzt

h(σ0σ1 . . . σℓ−1) :=

(ℓ−1∑

i=0

ai · num σi

)

mod p (8.35)

Ein nachweisbar gutes Verhalten liegt fur den Fall vor, daß die Koeffizienten zufalliggewahlt sind.

Lineare Funktionen uber 0, 1β. Hier ist β die Verarbeitungsbreite des Rechners undm = 2κ fur κ ≤ β. Viele Rechner und Programmiersprachen bieten fur eine Bitfolgeder Lange β das bitweise XOR (wir schreiben lieber ⊕) an.

Beispiel. 110011⊕ 110101 = 000110.

Wir wahlen ein Feld T[0, ℓ)[0, |Σ| − 1) von Wortern aus 0, 1β und setzen

h(σ0σ1 . . . σℓ−1) := ν

(ℓ−1⊕

i=0

T[i][num σi]

)

mod 2κ (8.36)

Wir erinnern uns, daß ν(w) fur die naturliche Zahl steht, die kanonisch durch dieBitfolge w reprasentiert wird.

Man beachte, daß fur eine Bitfolge w der Lange ≥ κ die Operation ν(w) mod 2κ

keine echte Division ist. Im Ergebnis werden lediglich alle Bits links von den κ nie-derwertigsten abgetrennt.

Das Zeichen”

⊕“ steht zu Zeichen

”⊕“ in demselben Verhaltnis wie das Zeichen

∑“

zum Zeichen”+“.

63

Page 62: Skript Waack merged

Die durch Gleichung 8.36 definierte Hashfunktion hat fur eine zufallig gewahlte Ma-trix T[0, ℓ)[0, |Σ|) nachweisbar ausgezeichnete Eigenschaften.

Bemerkung. Handelt es sich bei Σ zum Beispiel um alle 1-Byte-Zeichen, steht ein 64-Bit-Rechner zur Verfugung, und stehen Schlusselworter der Lange ℓ = 20 in Rede,so beansprucht die Matrix T 20 · 256 · 8 = 40.960 Bytes, eine Kleinigkeit.

Fazit. Die vorstehenden Hashfunktionen lassen unter bestimmten anwendungsbezoge-nen Umstanden die Uniformitatsannahme (UF) oder die abgeschwachte Uniformitatsan-nahme (UFab) — sie sollen das Nutzerverhalten simulieren — als vernunftig erscheinen.Das Nutzerverhalten kann jedoch anders sein. Dann aber sind unsere Satze 8.43 und 8.44fur das praktische Verhalten unserer Hashtabellen nicht aussagekraftig. Einen Ausweg stelltdas universelle Hashing aus Abschnitt 8.3.6 dar.

8.3.6 Universelles Hashing

Kern des universellen Hashings stellt die Randomisierung des Algorithmus empty(Integerm) zur Erzeugung einer leeren Hashtabelle und damit auch die Randomisierung der Um-speicherung der ganzen Tabelle (siehe Abschnitt 8.3.4) dar. Die Algorithmen 8.37, 8.38und 8.39 bleiben im Wesentlichen unverandert.

Wir nehmen an, daß wir uber einen (Pseudo-)Zufallsgenerator verfugen, der in der Rou-tine

random() returns Real

implementiert ist. (Ein Purist der objektorientierten Programmierung mag sich vorstel-len, daß sie zu einer Serviceklasse Math gehort. Trotzdem verwenden wir in unserem Pseu-docode den qualifizierten Aufruf Math.random() nicht und schreiben nur random().)Diese Routine setzt auf dem Intervall [0, 1] ⊂ R die Gleichverteilung um: Ist [a, b] ⊆ [0, 1]ein Teilintervall, so gibt ein Aufruf von random() mit Wahrscheinlichkeit b−a eine Zahlaus diesem Intervall zuruck. Mit Wahrscheinlichkeit 1− (b − a) liegt der Ruckgabewertin [0, 1] \ [a, b].Die Laufzeit eines Aufrufs von random() sei ein O (1).

Um zu randomisieren, benotigen wir eine unabhangige Folge

Υ0, Υ1, . . . , Υk

von gleichverteilten Zufallselementen aus 0, 1, eine Folge zufalliger Bits. Der folgendeAlgorithmus erzeugt eine Folge zufalliger Bits und gibt sie als Feld zuruck.

Algorithmus 8.45 (Erzeugen von zufalligen Bits)

64

Page 63: Skript Waack merged

Methodenkopf:randomBits

(Integer k

)returns Array r[0, k) of 0, 1

Großschritt 1:Erzeuge Feld r[0, k).

Großschritt 2:Fur i = 0, 1, . . . k − 1 fuhre aus:z← random()Falls z ≤ 1

2, so r[i]← 0.

Andernfalls r[i]← 1.Großschritt 3:return r.

Warum ist die durch Algorithmus 8.45 erzeugte Folge zufalliger Bits unabhangig? Manuberlegt sich leicht, daß die Ausfuhrung von Großschritt 2 Gleichung 3.19 aus Kapitel 3sichert.

Aussage 8.46 Algorithmus 8.45 arbeitet in Zeit O (k), wobei k die ubergebene naturlicheZahl ist.

Wir folgen der von Carter und Wegman 1979 vorgeschlagenen Vorgehensweise. Zunachstmussen Klassen von Hashfunktionen

H = Hm := h | h : U → 0, 1, . . . , m− 1 (8.37)

festgelegt werden, auf denen wir gleichverteilte Zufallselemente H betrachten:

P (H = h) =1

|H| (∀h ∈ H) (8.38)

Bemerkung. Bei der Analyse des offenen Hashings war die Hashfunktion h fest, derSchlussel X jedoch zufallig. Folglich war der Bucketindex h(X) eine zufallige Variable aus0, 1, . . . , m−1. Jetzt ist die Hashfunktion H ein Zufallselement ausH, und jeder beliebige,aber feste Schlussel k ∈ U definiert eine Zufallsvariable H(k) aus 0, 1, . . . , m − 1. Eshandelt sich dabei, wie auch im Falle des offenen Hashings, um eine Transformation desZufallselements H im Sinne von Abschnitt 3.1.2.

Wir konnen wiederum eine Rahmenklasse schreiben, die z. B. UniversalHashTableheißt. Sie enthalt als Hauptdatenfeld eine Variable hashTable vom Typ Array von verket-teten Listen. Daneben muß es Datenfelder geben, die eine Identifikation und Berechnungder aktuellen Hashfunktion h ∈ Hm ermoglichen.

Der Algorithmus zur Erzeugung einer leeren Hashtabelle sieht nun so aus.

Algorithmus 8.47 (Erzeugen einer leeren Hashtabelle mit m Buckets)

65

Page 64: Skript Waack merged

Methodenkopf:empty

(Integer m

)

Großschritt 1:Wahle ein h ∈ Hm zufallig und mit gleicher Wahrscheinlichkeit.Initialisiere die Datenfelder zur Beschreibung von h entsprechend.

Großschritt 2:Erzeuge ein Feld der Lange m von leeren verketteten Listen.Initialisiere das Datenfeld hashTable mit diesem Feld.

Die Mengen von Hashfunktionen aus Gleichung 8.37 mussen zwei Eigenschaften haben.

1. Das Kollisionsrisiko laßt sich explizit begrenzen.

2. Großschritt 1 von Algorithmus 8.47 ist effizient ausfuhrbar: Die Elemente aus Hm

sind durch wenige Parameter beschreibbar, die dann als Datenfelder gehalten wer-den. Genauer gesagt, mussen O (log2 |U|) Bits genugen, um ein h aus Hm, so zubeschreiben, daß fur jedes x ∈ U der Wert h(x) wenn schon nicht immer in ZeitO (1), so doch wenigstens in Zeit O (log2 |U|) berechnet werden kann.

Diese Bits werden in Goßschritt 1 von Algorithmus 8.47 mithilfe von Algorithmus8.45 ausgewurfelt.

Um das Kollisionsrisiko beschranken zu konnen, ist uns der folgende Begriff unentbehr-lich.

Definition 8.48 Sei c eine positive reelle Konstante. Eine Menge von Hashfunktionen Hm

aus Gleichung 8.37 heißt c–universelle Klasse von Hashfunktionen, wenn fur je zwei festeSchlussel k1 6= k2 aus dem Universum und ein Zufallselement H aus H

P (H(k1) = H(k2)) ≤c

m(8.39)

ist.

Wir kommen zur Analyse der Anzahl der Schlusselvergleiche beim universellen Hashing.Da im Vergleich zum offenen Hashing die Algorithmen kaum verandert sind, ist die Aus-gangssituation der aus Abschnitt 8.3.2 sehr ahnlich. Wir analysieren wieder die erfolgreicheund die erfolglose Suche. Es gibt jedoch einen fundamentalen Unterschied: Jetzt sind dieSchlussel beliebig aber fest, wohingegen die Hashfunktion ein rein zufalliges Element ausH ist.

Bezeichnungen. Sei x0, x1, . . . , xn−1, xn eine beliebige aber feste Folge von paarweise ver-schiedenen Schlusseln aus U , und sei h ∈ Hm eine beliebige aber feste Hashfunktion.Dann bezeichnet

Bh = Bh(x0, x1, . . . , xn−1)

66

Page 65: Skript Waack merged

die Hashtabelle, die man erhalt, wenn man die Schlussel x0, x1, . . . , xn−1 in die leereHashtabelle unter Verwendung von h nacheinander einfugt.

Ist H ∈ Hm dagegen eine zufallige Hashfunktion, so bezeichnet

BH = BH(x0, x1, . . . , xn−1)

die zufallige Hashtabelle, die man erhalt, wenn man die Schlussel x0, x1, . . . , xn−1 indie leere Hashtabelle unter Verwendung von H nacheinander einfugt.

Der”Teilalgorithmus“ search(x) (x ∈ U beliebig, aber fest) ist genauso definiert,

wie im Abschnitt 8.3.2. Fur ein zufalliges H ist die Anzahl der SchlusselvergleichekeyComp (BH .search(x)) eine zufallige Variable, die durch Transformation aus Hensteht.

Die erfolglose Suche. Wir fragen nach der erwarteten Anzahl von Schlusselvergleichenbei der Suche nach xn in BH(x0, x1, . . . , xn−1), wobei H eine zufallige Hashfunktionaus H ist:

E (keyComp (BH .search(xn))) :=1

|H|∑

h∈H

keyComp (Bh.search(xn)) . (8.40)

Erfolgreiche Suche nach einem festen Schlussel aus der Hashtabelle. Wir fragennach der erwarteten Anzahl von Schlusselvergleichen bei der Suche nach xi (fur eini ∈ 0, 1, . . . , n−1) in BH(x0, x1, . . . , xn−1), wobei H eine rein zufallige Hashfunktionaus H ist:

E (keyComp (BH .search(xi))) :=1

|H|∑

h∈H

keyComp (Bh.search(xi)) . (8.41)

Erfolgreiche Suche nach einem rein zufalligen Schlussel aus der Hashtabelle. Ge-sucht wird nach xI , wobei der Index I aus 0, 1, . . . , n − 1 rein zufallig ist. Unsinteressiert

E (keyComp (BH .search(xI))) :=1

|H|n∑

h∈H

n−1∑

i=0

keyComp (Bh.search(xi)) . (8.42)

Das folgende Lemma gleicht Lemma 8.42 aus Abschnitt 8.3.2 fast wie ein Ei demanderen.

Lemma 8.49 Sei H = Hm eine c–universelle Klasse von Hashfunktionen (c > 0).Die erwartete Anzahl der Schlusselvergleiche fur die erfolglose Suche in BH (siehe Glei-

chung 8.40) ist kleiner oder gleich c · α.Die erwartete Anzahl der Schlusselvergleiche fur die erfolgreiche Suche in BH nach

einem festen Schlussel aus dieser Hashtabelle (siehe Gleichung 8.41) ist kleiner als 1+c ·α.Die erwartete Anzahl der Schlusselvergleiche fur die erfolgreiche Suche in BH nach

einem rein zufalligen Schlussel aus dieser Hashtabelle (siehe Gleichung 8.42) ist kleiner als1 + c · α/2.

67

Page 66: Skript Waack merged

Auf den Beweis von Lemma 8.49 konnen wir verzichten. Er ist fast identisch mit demBeweis von Lemma 8.42. An Stelle der abgeschwachten Uniformitatsbedingung (UFab) wirdim Beweis von Lemma 8.49 Gleichung 8.39 aus Definition 8.48 verwendet.

Wir erhalten:

Satz 8.50 Unter den Voraussetzungen von Lemma 8.49 ist die erwartete Laufzeit jederder Operationen insert, delete und lookUp ein O (1 + α), wobei α der aktuelle Ausla-stungsfaktor der Hashtabelle ist.

8.3.7 Die Verdopplungsstrategie fur das universelle Hashing

Die Verdopplungsstrategie des universellen Hashings ist derjenigen aus Abschnitt 8.3.4 sehrahnlich.

– Am Anfang wird eine leere Hashtabelle mit einer passenden Lange m0 vermoge desAlgorithmus 8.47 angelegt.

– Hat der aktuelle Auslastungsfaktor α = pegel

B.length()eine vorher festgelegte obere Schran-

ke erreicht, so wird mit Hilfe von Algorithmus 8.47 eine neue Hashtabelle mit ver-doppelter Lange angelegt und der Inhalt der alten Hashtabelle Eintrag fur Eintragumgespeichert.

– Hat der aktuelle Auslastungsfaktor α = pegel

B.length()eine vorher festgelegte untere

Schranke erreicht, so wird mit Hilfe von Algorithmus 8.47 eine neue Hashtabellemit halbierter Lange angelegt und der Inhalt der alten Hashtabelle Eintrag fur Ein-trag umgespeichert. (Auch hier ist es naturlich sinnvoll, die Lange der Hashtabellenicht unter eine globale untere Schranke fallen zulassen.)

Alles, worauf es jetzt ankommt, ist die Konstruktion vernunftiger universeller Klassenvon Hashfunktionen.

8.3.8 Einige universelle Klassen von Hashfunktionen

Wir uberlegen uns, daß die Menge H = 0, 1, . . . , m − 1U aller Funktionen von U nach0, 1, . . . , m − 1 1-universell ist. Dazu fixieren wir zwei Schlussel k1 6= k2 aus dem Uni-versum. Da wir uns auf gleichverteilte Zufallselemente aus H beschranken, reicht es, denBruch

|h ∈ H | h(k1) = h(k2)||H| =

|h ∈ H | h(k1) = h(k2)|m|U|

zu betrachten. Die Machtigkeit der Menge im Nenner ist genau m|U|−1:

|h ∈ H | h(k1) = h(k2)||H| =

m|U|−1

m|U|=

1

m.

68

Page 67: Skript Waack merged

Die praktische Anwendung der Klasse H = 0, 1, . . . , m − 1U , d.h., die effizienteAusfuhrbarkeit von Großschritt 1 aus Algorithmus 8.47, stoßt auf zwei unuberwindlicheHindernisse:

1. Man benotigt mindestens log2 m · |U| zufallige Bits, um ein h ∈ U”auszuwurfeln“.

2. Das Problem der effizienten Speicherung der gewahlten Hashfunktion ist fur die Klas-se aller Funktionen genausowenig losbar.

Es folgen einige universelle Klassen von Hashfunktionen, fur die Großschritt 1 vonAlgorithmus 8.47 effizient ausfuhrbar ist.

Beispiel 1.

Es sei m (die Anzahl der Buckets) eine Primzahl und U = 0, 1, . . . , m− 1r fur ein r ≥ 1.Wir definieren

Hipm,r := ha | a = (a0, a1, . . . , ar−1) ∈ U (8.43)

wobei

ha : U → 0, 1, . . . , m− 1

wie folgt definiert ist.

ha(x) :=

(r−1∑

i=0

ai · xi

)

mod m (x = (x0, . . . , xr−1) ∈ U).

An dieser Stelle sei daran erinnert, daß es sich fur jede ganze Zahl z bei z mod m um denkanonischen Reprasentanten von z modulo m handelt, um eine Zahl aus 0, 1, . . . , m− 1also, die man als Rest erhalt, wenn man z durch m ganzzahlig dividiert (siehe Definition1.4 und Aussage 1.6).

Satz 8.51 Die Klasse Hipm,r ist 1–universell.

Beweis. Der Beweis ist außerordentlich einfach, sofern man mit elementaren Aussagender linearen Algebra vertraut ist.

Wir identifizieren jedes Element des Korpers Fm mit seinem kanonischen Representan-ten mod m. (Das ist erlaubt, weil wir reprasentantenunabhangig rechnen konnen.) Dannist das Universum U im vorliegenden Falle gleich dem r-dimensionalen Vektorraum Fr

m

uber dem Korper Fm, und ha(x) ist gleich dem Wert der kanonischen Bilinearform

〈·, ·〉 : Frm × Fr

m → Fm

69

Page 68: Skript Waack merged

an der Stelle (a, x):

ha(x) = 〈a, x〉.Sind nun k1 und k2 zwei voneinander verschiedene Schlussel aus Fr

m, so ist deren Differenzx := k1 − k2 ein von Null verschiedener Vektor in Fr

m. Folglich hat der Kern der linearenAbbildung

〈·, x〉 : Frm → Fm

a 7→ 〈a, x〉 = (ha(k1)− ha(k2)) mod m

die Dimension r − 1. Anders ausgedruckt, es ist

|a | ha(k1) = ha(k2)| = mr−1,

woraus die Behauptung folgt.

Beispiel 2.

Sei U = 0, 1, . . . , p− 1, wobei p eine (große) Primzahl ist.

Hmultp,m := ha | a ∈ 1, 2 . . . , p− 1 (8.44)

wobei fur jedes in Rede stehende a die Hashfunktion

ha : U → 0, 1, . . . , m− 1

wie folgt

ha(x) := ((a · x) mod p) mod m

definiert ist.

Satz 8.52 Die Klasse Hmultp,m ist 2–universell.

Beweis. Seien k1 6= k2 zwei beliebige, aber feste Schlussel aus U = 0, 1, . . . , p− 1. Wirbetrachten fur jedes in Rede stehende a ∈ 1, 2, . . . , p− 1 die Zahl

δ(a) :=((a · k1) mod p

)−((a · k2) mod p

)

die wegen a 6= 0 und k1 6= k2 offenbar in der Menge −(p − 1),−(p − 2), . . . ,−1 ∪1, 2, . . . , p− 1 liegt. Man sieht sofort, daß fur alle a′, a′′ ∈ 1, 2, . . . , p− 1 mit a′ 6= a′′

δ(a′) 6= δ(a′′)

ist. Von den 2(p−1) moglichen Werten fur δ(a) wird also einerseits keiner doppelt vergeben.Andererseits ist hochstens jeder m-te von ihnen durch m teilbar. Es folgt

|a ∈ 1, 2, . . . , p− 1 | ha(k1) = ha(k2)| ≤2

m· (p− 1),

woraus sofort die Behauptung folgt.

70

Page 69: Skript Waack merged

Beispiel 3.

Seien U = 0, 1, . . . , 2k − 1 und m = 2l.

Hlink,l := ha | a ∈ 0, 1 . . . , 2k − 1, a ungerade (8.45)

wobei

ha : U → 0, 1, . . . , m− 1

wie folgt definiert ist.

ha(x) := ((a · x) mod 2k) div 2k−l.

Satz 8.53 Die Klasse Hlink,l ist 2–universell.

Fazit. Bisher haben wir bei der Analyse die Eingaben als zufallig angesehen. Beimuniversellen Hashings dagegen wahlen wir die Hashfunktion zufallig aus. Infolgedessengibt es keine schlechten Eingaben mehr. Fur jede Eingabe gibt es nun gute und wenigergute Rechengange, je nachdem auf welche Hashfunktion die zufallige Wahl gefallen ist.Die Laufzeit streut fur alle Eingaben um denselben Erwartungswert: O (1 + α). Sofern wiruber gute Pseudozufallsgeneratoren verfugen, konnen wir uns auf unsere Analyseaussagenin der Praxis voll und ganz in dem Sinne verlassen, daß die theoretisch erwartete gleichder in der Praxis zu erwartende Laufzeit ist.

Manche Hashfunktionenklassen setzen voraus, daß die Anzahl der Buckets eine Prim-zahl ist. Das macht die Verdopplungsstrategie im engeren Sinne unmoglich. Es ist eineleichte Ubungsaufgabe, sich Auswege zu uberlegen.

Wir mussen uns auch hier der Frage stellen, was eine Aussage des Typs”Die erwartete

Laufzeit fur eine Eingabe ist ein O (1 + α)“ fur den Einzelfall bedeutet:

– Wird die zufallige Hashfunktion haufig neu zufallig ausgewahlt, so wird mit hoherWahrscheinlichkeit die benotigte Laufzeit linear in der Anzahl der ausgefuhrten Ope-rationen sein. Das ist eine Folgerung aus der Hoeffdingschen Ungleichung (siehe Bei-spiel nach Satz 3.10). Allerdings hat man dann das Problem der hohen Umspeicher-kosten.

– Bei einmaliger Wahl einer Hashfunktion kann die Wahrscheinlichkeit fur das Auf-treten einer inakzeptablen Laufzeit recht groß sein. Die Laufzeit kann breit streuen,obwohl ihr Erwartungswert nach Satz 8.50 konstant ist. Leider laßt sich Satz 8.44nicht auf den Fall des universellen Hashings ubertragen, da im Beweis die Unifor-mitatsbedingung (UF) und nicht deren Abschwachung (UFab) benotigt wird. Helfenwurden Aussagen des Typs

P (n Operationen dauern mindestens c · n Schritte) ≤ 1

n2,

71

Page 70: Skript Waack merged

wobei c eine positive reelle Konstante ist.

Es gibt Hashklassen, die solche Aussagen zulassen. Ein Beispiel fur

U = 0, 1, . . . , p− 1 (p prim)

und

m = die Bucketgroße

ist

H3m := ha,b,c,d | a, b, c, d ∈ 0, 1, . . . , p− 1,

wobei

ha,b,c,d(x) = ((ax3 + bx2 + cx + d) mod p) mod m

ist.

8.3.9 Geschlossenes Hashing

Begriff. Lineares Sondieren

Das Wesen des geschlossenen Hashings besteht darin, niemals zwei Schlussel in ein Bucketzu legen. Die Hashtabelle ist ein Feld von Paaren aus Schlusseln und Satellitendaten:

B[0, m) of Key×Range.

Man verwendet Hashfunktionen

h : U× [0, m)→ [0, m), (8.46)

die fur jeden Schlussel x eine Sondierungspermutation

(h(x, 0), h(x, 1), . . . , h(x, m− 1))

der Bucketindizes liefern. Ist der Schlussel X zufallig, so ist auch

(h(X, 0), h(X, 1), . . . , h(X, m− 1)) (8.47)

eine zufallige Permutation der Bucketindizes 0, 1, . . . , m− 1. Die Kollisionsbewaltigungbeim Einfugen eines Schlussels besteht nun darin, die Sondierungsfolge von links nachrechts auf der Suche nach einem freien Bucket fur diesen Schlussel zu durchlaufen. Mansagt, man sondiere. Man bricht das Sondieren ab, wenn man ein freies Bucket gefundenhat. In dieses legt man den Schlussel ab. Um stets ein freies Bucket finden zu konnen,

72

Page 71: Skript Waack merged

stellt man sicher, daß der Auslastungsfaktor α immer kleiner 1 ist. Ggf. muß nach derVerdopplungsstrategie umgespeichert werden.

Sucht man noch einem Schlussel in der Tabelle, so verfahrt man genauso wie beimEinfugen: Man sondiert von links nach rechts langs der Sondierungsfolge, bis daß manden Schlussel gefunden hat (erfolgreiche Suche) oder auf ein leeres Bucket trifft (erfolgloseSuche). Das funktioniert nur, wenn man nicht wirklich streicht. Stattdessen markiert manBuckets, aus denen der Schlussel gestrichen wurde, mit deleted. Will man dann einenSchlussel einfugen, so verhalt sich dieser Eintrag wie ↑. Sucht man nach einem Schlussel k,so verhalt dieser sich wie ein von k verschiedener Schlussel.

Die einfachste Auspragung des geschlossenen Hashings (man sagt auch open addres-sing) ist das lineare Sondieren. Man verwendet eine Prahashfunktion h : U → [0, m). DieSondierungspermutation ist gleich

(h(x) + 0) mod m, (h(x) + 1) mod m, . . . , (h(x) + m− 1) mod m.

Dieses vielangewendete Verfahren hat das die folgenden Vorteile:

– Es ist einfach.

– Es wird kein Platz fur Zeiger und leere Platze im Zeiger-Array”verschwendet“.

– Es vermeidet den Zeitaufwand fur die Erzeugung von Listenelementen zur Laufzeit.

Wir modifizieren das Beispiel aus Abschnitt 8.3.1 ein wenig. Sei U wiederum gleich derMenge aller Worter der Lange λ ∈ [3, ℓmax] uber dem Standardalphabet a, . . . z, A, . . .Z,sei m = 13 und sei

num a = num A = 0

num b = num B = 1

. . . . . .

num z = num Z = 25.

Wir modifizieren die Definition der Hashfunktion aus Gleichung 8.21 wie folgt:

h(b0b1b2 . . . bλ−1) := (num b2 + 4) mod 13. (8.48)

Fugen wir die Monate Juli, Dezember, Januar, Februar, Juni, September, Maerz, April,August, Oktober, Mai und November in dieser Reihenfolge in die leere Hashtabelle ein, soerhalten wir das folgende Bild, wobei die Werte der Prahashfunktion in Klammern stehen.

B0 = November(12) B1 = ∅ B2 = Juli(2)B3 = Dezember(3) B4 = Januar(4) B5 = Februar(5)B6 = Juni(4) B7 = September(6) B8 = Maerz(8)B9 = April(8) B10 = August(10) B11 = Oktober(10)B12 = Mai(12)

73

Page 72: Skript Waack merged

Das folgende Analyseergebnis, dessen Beweis wir schuldig bleiben, basiert auf der Uni-formitatsannahme (UF) von Seite 8.3.1.

Satz 8.54 Bei linearem Sondieren in einer Hashtabelle der Große m mit Auslastungsfaktorα < 1 gilt unter der Uniformitatsannahme (UF):

1. Die erwartete Anzahl von Schlusselvergleichen bei erfolgloser Suche (siehe Gleichung8.26) geht bei festem α fur m→∞ gegen 1

2(1 + 1

(1−α)2).

2. Die erwartete Anzahl von Schlusselvergleichen bei erfolgreicher Suche nach einemrein zufalligen Schlussel aus der Tabelle (siehe Gleichung 8.28) geht bei festem α furm→∞ gegen 1

2(1 + 1

1−α).

Die erwartete Anzahl von Schlusselvergleichen beim linearen Sondieren gemaß Satz 8.54ist fur verschiedene Auslastungsfaktoren α in der folgenden Tabelle dargestellt.

”erfolglos“

”erfolgreich nach rein zufalligem Schlussel“

α 12· (1 + 1

(1−α)2) 1

2· (1 + 1

1−α)

0,5 2,5 1,50,6 3,625 1,750,7 6,06 2,160,75 8,5 2,50,8 13 30,9 50,5 5,50,95 200,5 20

Ideales Hashing

Das lineare Sondieren zeigt nicht immer befriedigende Ergebnisse. Wir gehen der Fragenach, was man im Idealfall erwarten kann. Die fur das geschlossene Hashing besten Bedin-gungen liegen offensichtlich dann vor, wenn fur zufallige Schlussel X die Sondierungspermu-tation (8.47) eine rein zufallige Permutation der Menge der Bucketindizes 0, 1, . . . , m−1ist. Wir sprechen dann vom uniformen oder idealen Hashing.

Die reine Zufalligkeit der Sondierungspermutation ist zu der folgenden Bedingung gleich-wertig: Fur jede beliebige, aber feste Permutation (b0, b1, . . . , bm−1) der Bucketindizes undjedes i = 0, 1, 2, . . . , m− 1 ist

P (h(X, i) = bi | h(X, 0) = b0, . . . , h(X, i− 1) = bi−1 ) =m− i + 1

m. (8.49)

Fur den Beweis des nachsten Satzes brauchen wir die folgende (leicht zu beweisende)Aussage. Ist Z ∈ 0, 1, 2, . . . eine zufallige Variable, so ist

E Z =

∞∑

i=0

P (Z ≥ i) . (8.50)

74

Page 73: Skript Waack merged

Satz 8.55 Unter Gleichung 8.49 ist die erwartete Anzahl von Schlusselvergleichen bei er-folgloser Suche (siehe Gleichung 8.26) nach oben durch 1

1−αbeschrankt.

Beweis. Ist Z die Anzahl der in Rede stehenden Schlusselvergleiche, und ist Ai dasEreignis, daß die vermoge der zufalligen Sondierungspermutation (8.47) inspezierten ersteni Slots alle besetzt sind, dann ist einerseits

P (Z ≥ i) = P (A1 ∩ A2 ∩ . . . ∩Ai−1)

und andererseits nach Gleichung 3.18

P (A1 ∩ A2 ∩ . . . ∩ Ai−1) = P (A1) · P (A2 | A1 ) · . . . · P (Ai−1 | A1 ∩ . . . ∩ Ai−2 ) .

Wegen Gleichung 8.49 ist die rechte Seite der vorstehenden Gleichung gleich

n

m· n− 1

m− 1. . .

n− i + 2

m− i + 2<( n

m

)i−1

= αi−1.

Unter Verwendung von Gleichung 8.50 folgt

EZ <

∞∑

i=0

αi =1

1− α.

Ohne Beweis nehmen wir zur Kenntnis.

Satz 8.56 Unter Gleichung 8.49 ist die erwartete Anzahl von Schlusselvergleichen bei er-folgreicher Suche nach einem rein zufalligen Schlussel aus der Tabelle (siehe Gleichung8.28) nach oben durch 1

αln 1

1−αbeschrankt.

Quadratisches Sondieren

Sei h : U → [0, m) gewohnliche Hashfunktion, eine Prahashfunktion, wie wir indiesemAbschnitt sagen.

Wird die Sondierungsfolge wie folgt berechnet, sprechen wir vom quadratischen Son-dieren.

h(x, 0) = h(x)

h(x, 1) = (h(x) + 1) mod m

h(x, 2) = (h(x)− 1) mod m

h(x, 3) = (h(x) + 4) mod m

h(x, 4) = (h(x)− 4) mod m

h(x, 5) = (h(x) + 9) mod m

h(x, 6) = (h(x)− 9) mod m...

h(x, k) =(

h(x) +

⌈k

2

⌉2

· (−1)k+1)

mod m.

75

Page 74: Skript Waack merged

Man kann mit Methoden der elementaren Zahlentheorie folgendes zeigen:

Lemma 8.57 Ist m Primzahl, m = 4j + 3 fur ein j ∈ N, so ist h(x, k) | 0 ≤ k < m =[0, m), d.h. die Sondierungsfolge ist eine Permutation.

Bemerkung. Quadratisches Sondieren verhalt sich der Erfahrung nach sehr gut, nichtviel schlechter als ideales Hashing (h gut verteilend, Auslastungsfaktor ≤ 0,9.)

Doppel-Hashing

Man benutzt zwei (unabhangig berechnete) Hashfunktionen

h1 : U → [0, m)

h2 : U → [0, m− 1)

und setze, fur k = 0, 1, 2, . . .:

h(x, k) := (h1(x) + k · (1 + h2(x))) mod m

Wiederum kann man mit elementaren Methoden zeigen, daß das folgende Lemma gilt:

Lemma 8.58 Ist m Primzahl, so ist h(x, k) | 0 ≤ k < m = [0, m), d.h. die Sondie-rungsfolge ist eine Permutation.

Bemerkung. Man kann zeigen, daß wenn m prim ist und h1(X) und h2(X) rein zufalligsind, sich Doppel-Hashing ausgezeichnet verhalt, fast wie ideales Hashing.

8.4 Vergleichsorientiertes Sortieren

Die Spezifikation von vergleichsorientierten Sortieralgorithmen sieht so aus:

Eingabe: ein Feld A[0, n) paarweise verschiedener ganzer Zahlen, den Schlusseln.

Ausgabe: das gleiche Feld, dessen Eintrage so permutiert wurden, daß nunmehr

A[0] < A[1] < . . . < A[n− 1]

gilt.

Einschrankung. Einem Algorithmus ist es nur erlaubt, aus einem Schlussel in der Wei-se Informationen zu gewinnen, daß er ihn mit einem anderen Schlussel vergleicht.(Beispielsweise ist die Analyse des Bitmusters eines Schlussels nicht erlaubt. Mandarf nicht einmal einen Schlussel aus dem Feld A mit einem nicht zu A gehorigenReferenzschlussel vergleichen.)

76

Page 75: Skript Waack merged

Im Sinne der objektorientierten Programmierung nehmen wir stets an, daß wir eineRahmenklasse haben, die als Hauptdatenfeld das zu sortierende Array A hat. Die ver-gleichsorientierten Sortieralgorithmen, die wir nun besprechen werden, gehoren zu dieserKlasse.

Wie bei den binaren Suchbaumen auch schon, kommt es beim vergleichsorientiertenSortieren nicht auf die absolute Große der Schlussel, sondern nur auf deren Verhaltnisuntereinander an. Folglich konnen wir, wenn es um die Analyse geht, stets annehmen, daßfur das Eingabefeld A[0, n)

A[0] = π(0), A[1] = π(1), . . . , A[n− 1] = π(n− 1)

ist. Dabei is π eine Permutation aus der Menge Sn aller Permutationen der Schlusselmenge[0, n) := 0, 1, . . . , n−1. Wir konnen also, wenn wir es wollen, zu Beginn unserer Rechnungdas Feld A mit der Permutation π identifizieren.

Bei der Analyse eines vergleichsorientierten Sortieralgorithmus A werden wir zwei Kom-plexitatsmaße im Auge behalten:

Die Anzahl der Schlusselvergleiche keyCompA π (π ∈ Sn) ist fur uns von besondererBedeutung. Zwar haben wir soeben angenommen, daß es sich bei unseren Schlusselnstets um ganze Zahlen handeln soll. Das ist aber nur um der lieben Einfachheit willengeschehen. Schlussel konnen auch Zeichenketten, ja ganze Objekte sein. Zwar soll dieLaufzeit fur einen Schlusselvergleich ein O (1) sein, aber dieser kann deutlich teurerwerden, als beispielsweise eine Addition. Deshalb ist es gerechtfertigt, die Anzahl derSchlusselvergleiche separat aufzufuhren.

Die Laufzeit timeA π (π ∈ Sn) wird bei unseren Algorithmen stets ein O (keyCompA π)sein.

Die in diesem Abschnitt zu studierenden Sortieralgorithmen sollen im Arbeitsspeicherablaufen. Dieser ist beschrankt. Folglich sollen unsere Algorithmen zusatzlich zur Eingabenur ein geringes Quantum an Speicherplatz benotigen.

Definition 8.59 Ein Sortieralgorithmus arbeitet in situ, wenn er zum Sortieren des Ein-gabefeldes A[0, n) nur O (log n) zusatzlichen Speicher benotigt.

Man darf bei der Beurteilung des Speicherplatzbedarfs eines Algorithmus den Laufzeit-stapel nicht vergessen. Dessen Hohe ist insbesondere dann nicht zu vernachlassigen, wennes sich um einen rekursiven Algorithmus handelt: Im Rumpf des Algorithmus wird dieserselbst fur ein Teilproblem des zu bearbeitenden Problems aufgerufen.

Der Prozeß, der bei der Ausfuhrung eines rekursiven Algorithmus rekAlg auf eineEingabe ablauft, kann man sich gut veranschaulichen, indem man sich den Baum derrekursiven Aufrufe der Methode rekAlg vor Augen halt.

Wir betrachten ein generisches Beispiel. Angenommen, im Rumpf von rekAlg auf eineEingabe der Große n — wir schreiben dafur rekAlgn — gibt es zwei rekursive Aufrufe

77

Page 76: Skript Waack merged

rekAlgn1und rekAlgn2

mit n1 + n2 = n− 1 und n1 ≤ n2, wobei rekAlgn2endstandig ist:

Der rekursive Aufruf von rekAlgn2steht unmittelbar vor dem Ende der rufenden Routine.

Ansonsten gibt es im Rumpf von rekAlg keine Methodenaufrufe.Der Baum Tn der rekursiven Aufrufe von rekAlg auf eine Eingabe der Große n ist in

Gleichung 8.51 dargestellt.

Tn =

n

n1 n2

n11 n12 n21 n22

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

(8.51)

Da bei jedem Aufruf von rekAlg ein Inkarnationsblatt auf den Laufzeitstapel gelegt wird,ist dessen maximale Hohe gleich der Tiefe des Baumes.

Ist n1 = ⌊(n− 1)/2⌋ und n2 = ⌈(n− 1)/2⌉, so ist depth Tn = O (log n). Diese Tiefe istfur uns akzeptabel.

Leider konnen wir nicht immer voraussetzen, daß die Eingabe schon halbiert wird. Istim Extremfall n1 = 0 und n2 = n− 1, so gilt depth Tn = O (n). Wenn wir einen am Platze(Definition 8.59) arbeitenden Algorithmus im Auge haben, ist das zuviel.

Der Ausweg ist uberraschend einfach. Wir haben gesagt, die großere Rekursion seiendstandig. Das heißt zur Laufzeit, daß unmittelbar nachdem der Rahmen fur rekAlgn2

vom Laufzeitstapel entfernt worden ist, auch der Frame von rekAlgn beseitigt wird. Daman nach dem Ende von rekAlgn2

keinerlei Vorteil mehr aus der Existenz des Rahmensvon rekAlgn zieht, kann er schon bei Aufruf von rekAlgn2

vom Laufzeitstapel entferntwerden. Wir sprechen von der Beseitigung der Endrekursion.

Die Umsetzung dieser Idee scheint ein dynamisches Problem zu sein, das zur Lauf-zeit gelost werden muß. Doch der Schein trugt. Die Erkennung der Endstandigkeit einesrekursiven Aufrufs und die Beseitigung der Endrekursion kann schon zur Compile–Zeitvorgenommen werden. Ein Compiler, der soetwas leistet, heißt endrekursiv.

Wenn wir unterstellen, daß bei der Abarbeitung von rekAlg Endrekursionen beseitigtwerden, so ist es um die Hohe des Laufzeitstapels bei der Abarbeitung von rekAlgn besserbestellt.

Lemma 8.60 Unter den genannten Voraussetzungen ist die maximale Hohe des Laufzeit-stapels bei Abarbeitung von rekAlgn ein O (log n).

Beweis. Fur einen Pfad π in Tn sei |π|, wie ublich, dessen Lange.Die maximale Hohe des Laufzeitstapel ist

maxπ ist Pfad in Tn

(|π| − |v |Der Knoten v des Pfades π gehort zu einer Endrekursion|) ,

denn wir mussen fur jeden Pfad nur diejenigen Knoten berucksichtigen, die zu den nicht-endstandigen Rekursionen gehoren. Sie bearbeiten die

”kleinere Halfte“. Wir rekapitulieren

78

Page 77: Skript Waack merged

Gleichung 1.3 aus Aussage 1.11 fur den Fall b = 2:

⌊log2 n⌋ = mini | ⌊n/2i⌋ = 1.

Nun folgt die Behauptung.

8.4.1 Quicksort

Gute Darstellungen von Quicksort finden sich in [MR95] und [CLRS01].Alle Quicksort–Algorithmen beruhen auf einer rekursiven Methode

quicksort(left, right),die als Vorbedingung die Ungleichungskette 0 ≤ left ≤ right ≤ n hat. Die Methodepermutiert die Schlussel des Teilfeldes A[left, right). Sie garantiert (Nachbedingung),daß dieses Teilfeld nach ihrem Ende aufsteigend sortiert ist.

Es gibt mehrere Varianten von Quicksort. Der grundsatzliche Aufbau ist bei allen gleich:

Teile das Teilfeld A[left, right) durch einen Pivotindex π ∈ [left, right) in zwei TeileA[left, π) und A[π + 1, right). Sichere bei der Teilung, die den Pivotindex in derRegel modifizieren wird, daß sich das Pivotelement p = A[π] nach Abschluß derTeilung an seinem endgultigen Platz befindet, und A[i] ≤ A[π] ≤ A[j] fur alle i <π < j gilt.

Beherrsche das Gesamtproblem durch rekursives Sortieren der Felder A[left, π) undA[π + 1, right). (Aufwand fur das Zusammensetzen fallt offenbar nicht an.)

Es gibt mehrere Strategien, den Pivotindex zu Beginn des Teilungsprozesses zu initia-lisieren:

Die einfache deterministische Strategie. Setze zum Beispiel

π ←⌊left + right

2

.

(Jede andere Regel leistet den gleichen Dienst.)

Die einfache randomisierte Strategie. Wahle π zufallig und mit gleicher Wahrschein-lichkeit aus dem halboffenen Intervall [left, right).

Verfeinerte deterministische oder randomisierte Strategien. Wahle drei oder auchfunf Indexkandidaten aus [left, right). Nimm denjenigen Index unter den drei (funf)Kandidaten als Pivotindex, dessen Feldeintrag der Median der drei (funf) zugehorigenFeldeintrage ist.

Algorithmus 8.61 (Generisches Quicksort)

79

Page 78: Skript Waack merged

Methodenkopf:quicksort

(left, right)

Großschritt 1. [Basis]Falls right − left ≤ 1, so fuhre aus: return.

Großschritt 2. [Teilung]π ← initialer Pivotindex nach einer der genannten Strategienp← A[π]– Initialisierung der Grenzen des Suchintervalls fur die Vertauschungsindizesλ← left, ρ← right− 1Fuhre aus

Großschritt 2.1. [Bestimmung der Vertauschungsindizes im Suchintervall]λλ← minj ∈ [λ, ρ] |A[j] ≥ pρρ← maxj ∈ [λ, ρ] |A[j] ≤ p

Großschritt 2.2. [Vertauschung und Aktualisierung des Pivotindex]Vertausche die Feldeintrage A[λλ] und A[ρρ] miteinander.//Falls das Pivot soeben nach rechts bewegt wurde, fuhre seinen Index nach:Falls π = λλ, so π ← ρρ//Falls das Pivot soeben nach links bewegt wurde, fuhre seinen Index nach:Falls π = ρρ, so π ← λλ

Großschritt 2.3. [Aktualisierung der Grenzen des Suchintervalls]Falls λλ < π < ρρ, so λ← λλ + 1, ρ← ρρ− 1Falls λλ = π < ρρ, so λ← λλ, ρ← ρρ− 1Falls λλ < π = ρρ, so λ← λλ + 1, ρ← ρρFalls λλ = π = ρρ, so λ← λλ, ρ← ρρ

bis daß ρ− λ = 0 ist.Großschritt 3. [Rekursion.]

Falls π − left < right − π so fuhre aus.left1 ← left, right1 ← πleft2 ← π + 1, right2 ← right

Anderfalls fuhre aus:left1 ← π + 1, right1 ← right

left2 ← left, right2 ← πquicksort(left1, right1)quicksort(left2, right2)

Bemerkung zu Großschritt 2.1. Die Berechnung der Vertauschungsindizes λλ und ρρerfolgt, indem man einen Zeiger j von links nach rechts bzw. rechts nach links uber dasabgeschlossene Suchintervall [λ, ρ] laufen laßt und den entsprechenden Index durch Ver-gleich von A[j] mit p sucht. Dabei achtet man durch Indexvergleich mit π darauf, daß dasPivotelement nicht mit sich selbst verglichen wird. Beide Suchen sind erfolgreich, da derPivotindex π immer zum Suchintervall gehort (siehe Lemma 8.62). Daraus folgt fur dieberechneten Vertauschungsindizes λλ und ρρ insbesondere λλ ≤ ρρ.

80

Page 79: Skript Waack merged

Beispiel. Sei n = 13, π = 6, p = 53, left = 0, right = 13. Am Anfang ist λ = 0 undρ = 12. Im folgenden bezeichnet ↓ die Position des Pivotelements, ⊲ ist der Zeiger left

und ⊳ der Zeiger right − 1. Ein Feldelement a, auf das der Zeiger λλ oder der Zeiger ρρverweist, ist eingerahmt: a . Verweisen sowohl λλ als auch ρρ auf a, zeigen wir das so an:

a . In jeder Zeile von (8.52) sehen wir den Zustand des Feldes und der genannten Zeiger

unmittelbar vor Großschritt 2.2.

⊲ ↓ ⊳

15 47 33 87 98 17 53 76 82 2 52 27 44⊲ ↓ ⊳

15 47 33 44 98 17 53 76 82 2 52 27 87⊲ ↓ ⊳

15 47 33 44 27 17 53 76 82 2 52 98 87⊲ ↓⊳

15 47 33 44 27 17 52 76 82 2 53 98 87⊲↓ ⊳

15 47 33 44 27 17 52 53 82 2 76 98 87⊲ ↓⊳

15 47 33 44 27 17 52 2 82 53 76 98 87⊲↓⊳

15 47 33 44 27 17 52 2 53 82 76 98 87

(8.52)

Wir erinnern uns daran, daß eine Schleifeninvariante eine logische Aussage ist, die vorder ersten und nach jeder folgenden Iteration des Rumpfes der in Rede stehenden Schleifeden Wahrheitswert true hat.

Lemma 8.62 Algorithmus 8.61 arbeitet korrekt.

Beweis. Sei p das Pivotelement und π der Pivotindex. Entscheidend ist, daß die folgende,aus drei Klauseln bestehende Bedingung

Klausel 1. Fur alle Indizes j”links“ vom Suchintervall ist das zugehorige Feldelement

kleiner als das Pivot:

∀j (j < λ ⇒ A[j] < p) .

Klausel 2. Fur alle Indizes j”rechts“ vom Suchintervall ist das zugehorige Feldelement

großer als das Pivot:

∀j (j > ρ ⇒ A[j] > p) .

Klausel 3. Der Pivotindex π gehort zum Suchintervall:

π ∈ [λ, ρ].

eine Invariante der Schleife innerhalb von Großschritt 2, dem Teilungsschritt, ist.

81

Page 80: Skript Waack merged

Bemerkung zur Laufzeit

Eine einfache Inspektion von Algorithmus 8.61 ergibt, daß fur jede der bereits erwahntenund noch zu studierenden Quicksort-Varianten A und jede Permutation σ der Schlussel-menge [0, n) gilt:

timeA σ = O (keyCompA σ) . (8.53)

Wir begnugen uns im folgenden mit der Analyse der Anzahl der Schlusselvergleiche.

Analyse der einfachen deterministischen Variante

Die einfache deterministische Variante von Quicksort — simple quicksort (sq) — erhaltman aus Algorithmus 8.61, indem man den ersten Schritt des Großschritts 2 z.B. durch

π ←⌊

left + right

2

konkretisiert.Wie bei den binaren Suchbaumen auch schon, konnen wir bei der Analyse von Quicksort

annehmen, daß die Schlusselmenge gleich 0, 1, . . . , n− 1 ist. Fur jede Permutation π ausder Menge Sn aller Permutationen der Schlusselmenge 0, 1, . . . , n− 1 sei

Q(π(0), π(1), . . . , π(n− 1)) = Q(π)

die Anzahl der Schlusselvergleiche von sq auf die Eingabe A[0] = π(0), A[1] = π(1), . . . , A[n−1] = π(n− 1).

Die mittlere Anzahl von Schlusselvergleichen auf Eingaben der Lange n ist wie folgtdefiniert:

Q(n) :=1

n!

π∈Sn

Q(π)

Herzstuck der Analyse von sq sind Lemma 8.63 und Lemma 8.64, deren Beweise denenvon Lemma 8.30 und Lemma 8.31 aus dem Abschnitt 8.2.6 fur binare Suchbaume so ahnlichsind, daß wir sie hier weglassen wollen. (Die Ahnlichkeit ist kein Zufall. Ein Lauf vonAlgorithmus 8.61 baut implizit einen binaren Suchbaum auf.)

Lemma 8.63 Fur die Funktion Q(n) gilt die folgende Rekursion.

Q(n) =

0 falls n ≤ 1;

(n− 1) + 2n

∑n−1i=0 Q(i) andernfalls.

Lemma 8.64 Fur die Funktion Q(n) gilt.

Q(n) = 2 ln 2 · n log2 n − Θ(n)

82

Page 81: Skript Waack merged

Wir erhalten.

Satz 8.65 Die mittlere Anzahl von Schlusselvergleichen von sq auf Eingabefelder der Langen ist gleich

2 ln 2︸ ︷︷ ︸

=1,386...

·n log2 n − Θ(n).

Die Laufzeit im schlechtesten Fall auf Eingaben der Lange n ist ein Ω(n2).

Bemerkung zu verfeinerten deterministischen Varianten

Wahlt man drei Pivotindex-Kandidaten aus und entscheidet sich dann fur denjenigen In-dex, dessen zugehoriger Feldeintrag der Median der drei Eintrage ist, so erhalt man alsmittlere Laufzeit auf auf Eingabefelder der Lange n

1, 188 . . . · n log2(n− 1) − Θ(n).

Die Laufzeit im schlechtesten Fall auf Eingaben der Lange n bleibt ein Ω(n2).

Analyse der einfachen randomisierten Variante

Die einfache randomisierte Variante von Quicksort — simple randomized quicksort (srq) —erhalt man aus Algorithmus 8.61, indem man den ersten Schritt des Großschritts 2 durch

π ← gleichverteiltes Zufallselement aus[left, right

)

konkretisiert.Fur jede Permutation σ der Schlusselmenge 0, 1, . . . , n − 1 wird die Anzahl der

Schlusselvergleiche zur Zufallsvariablen

keyCompsrq σ ∈ 1, 2, . . . , n2.

Satz 8.66 Fur alle Permutationen σ der Schlusselmenge 0, 1, . . . , n− 1 ist

E(keyCompsrq σ

)= 2 ln 2︸ ︷︷ ︸

=1,38...

·n log2 n− Ω(n). (8.54)

Beweis. Sei σ eine beliebige, aber feste Permutation der Schlusselmenge 0, 1, . . . , n−1.Wir beschreiben keyCompsrq σ als Summe von Bernoulli-Variablen. Fur jedes Paar (i, j)von Schlusseln aus 0, 1, . . . , n− 1 mit i < j sei

Xij =

1 i wird mit j wahrend einer Rechnung auf σ verglichen;

0 andernfalls.

83

Page 82: Skript Waack merged

Es ist

keyCompsrq σ =∑

0≤i<j<n

Xij .

Nach dem Satz uber die Linearitat der Erwartung (Satz 3.5) mussen wir uns fur 0 ≤ i <j < n um die Erwartungswerte E Xij kummern.

Ein Lauf von srq auf eine Eingabe σ ist ein zufalliger Prozeß, bei dem ein zufalligerSuchbaum entsteht, dessen Teilbaume die zufallig ausgewahlten Pivots in ihren Wurzelntragen. Wir numerieren die Knoten dieses zufalligen Suchbaums in Level-Ordnung vonvon 0 bis n − 1 durch: Beginnend mit der Wurzel, werden die Ordnungszahlen von obennach unten und auf jedem Tiefenniveau von links nach rechts vergeben. (Die Knoten desSuchbaumes aus Abbildung 8.1 sind in Level-Ordnung numeriert, allerdings mit dem Indexeins beginnend.) Sei Z0, Z1, . . . , Zn−1 diejenige Folge zufalliger Schlussel, die man aus derFolge der Knoten in Level-Ordnung erhalt, wenn man jeden Knoten durch den Schlusselersetzt, mit dem er markiert ist.

Nun fixieren wir ein Paar (i, j) von Schlusseln mit i < j und definieren eine zufalligeOrdnungszahl S := S(i, j), eine sogenannte Stoppzeit, fur den Zufallsprozeß Z0, Z1, . . . , Zn−1.Ob S einen Wert ℓ ∈ N annimmt, hangt nur von Z0, Z1, . . . , Zℓ ab:

S = ℓ ⇐⇒ Z0 6∈ [i, j], Z1 6∈ [i, j], . . . , Zℓ−1 6∈ [i, j], Zℓ ∈ [i, j]. (8.55)

Die Zufallsvariable S ist die erste Ordnungszahl eines Knotens unseres zufalligen Such-baums, der einen Schlussel aus [i, j] tragt. Es ist klar, daß

S ∈ 0, 1, . . . , n− (j − i)

ist.Nun betrachten wir den zufalligen Schlussel ZS, das sogenannte gestoppte Ereignis.

ZS ist der erste Schlussel aus [i, j], den man erhalt, wenn man die Knoten des zufalligenSuchbaums in Level-Ordnung aufreiht. Insbesondere folgen alle Schlussel aus dem Intervall[i, j] in dem zufalligen Suchbaum dem Weg von der Quelle bis zu dem Knoten, der mit ZS

markiert ist. Genau an diesem Knoten wird das Intervall aufgeteilt. Folglich ist

Xij = 1 ⇐⇒ ZS ∈ i, j, (8.56)

denn ist ZS = i oder ZS = j, so werden bei der Aufteilung des zu sortierenden Teilintervallsi und j mit einander verglichen. Anderfalls werden i und j mit einem Wert k aus demoffenen Intervall (i, j) verglichen. Ihre Wege trennen sich wegen i < k < j, und es kann zukeinem Vergleich zwischen ihnen mehr kommen.

Nun zeigen wir, daß fur jedes k aus [i, j]

P (ZS = k) =1

j − i + 1(8.57)

ist. Wir behaupten also, ZS sei auf [i, j] gleichverteilt.

84

Page 83: Skript Waack merged

Bei

S = ℓ (ℓ = 0, 1, . . . , n− j + i)

handelt es sich um ein vollstandiges System von Ereignissen: Es muß genau eines eintreten.Folglich genugt es fur den Nachweis von Gleichung 8.57 nach Lemma 3.4, die folgendeGleichung zu beweisen:

P (ZS = k | S = ℓ) =1

j − i + 1. (8.58)

Aus der Definitiongleichung 8.55 von S folgt:

P (ZS = k | S = ℓ) = P (Zℓ = k | Z0 6∈ [i, j], Z1 6∈ [i, j], . . . , Zℓ−1 6∈ [i, j], Zℓ ∈ [i, j] )(8.59)

Die Teilbedingung”Z0 6∈ [i, j], . . . , Zℓ−1 6∈ [i, j]“ auf der rechten Seite von Gleichung 8.59

bedeutet, daß das aktuelle Teilintervall [left, right), aus dem Zℓ zufallig und mit gleicherWahrscheinlichkeit gemaß dem Algorithmus gezogen wird, [i, j] enthalt. Die Teilbedingung

”Zℓ ∈ [i, j]“ heißt, daß zum Zeitpunkt ℓ ein Schlussel aus [i, j] ausgewurfelt wird. Aus

Gleichung 3.21 erhalten wir nun wie folgt Gleichung 8.58:

P (ZS = k | S = ℓ) =1

right− left

/j − i + 1

right− left=

1

j − i + 1

Aus den Gleichungen 8.56 und 8.57 folgt

E Xij = P (Xij = 1) =2

j − i + 1.

Wir erhalten.

E∑

i<j

Xij =∑

i<j

E Xij = 2 ·∑

i<j

1

j − i + 1︸ ︷︷ ︸

Vermoge Gleichung 2.5definierte Summe.

Diese Summe haben wir bereits im Lemma 2.5 des Abschnitts 2.1 analysiert:

≤ 2 · n ln n − 2 · (n− ln n− 1) (Gleichung 2.6)

= 2 ln 2 · n log2 n− Ω(n).

85

Page 84: Skript Waack merged

Bemerkung zu verfeinerten randomisierten Varianten

Wahlt man drei Pivotindex-Kandidaten zufallig aus und entscheidet sich dann fur denjeni-gen Index, dessen zugehoriger Feldeintrag der Median der drei Eintrage ist, so erhalt manfur jede Eingabe der Lange n

1, 188 . . . · n log2(n− 1) − Ω(n) (8.60)

als obere Schranke fur die erwartete Laufzeit.

8.4.2 Heapsort

In diesem Abschnitt studieren wir einen Sortieralgorithmus, dessen Laufzeit im schlechte-sten Fall ein O (n · log n) ist. Er beruht auf dem Heap als grundlegender Datenstruktur.Obwohl eine gute Implementation von Quicksort auch die schnelleren Varianten von Heap-sort fur gewohnlich schlagt, ist Heapsort sehr interessant. Das ist inbesondere deshalb derFall, weil der Heap uber die Sortieralgorithmen hinaus eine sehr nutzliche Datenstrukturist.

Ein nichtleerer Heap T (mit Knotenmenge V (T )) uber Z und R ist ein geordneterbinarer Wurzelbaum, zu dem Markierungsfunktionen der Knotenmenge

key : V (T ) −→ Z

data : V (T ) −→ Rgehoren. Die Markierungsfunktion key erfullt die Heapbedingung : Fur je zwei Knoten (v, v′),wobei v der Vater von v′ ist, gilt

key(v′) ≤ key(v). (8.61)

Wie im Falle von Quicksort auch schon, beschranken wir uns bei der Besprechung der heap-basierten Sortierverfahren auf den Fall, daß die Schlussel paarweise verschieden sind, ob-wohl andernfalls alles beim Alten bliebe. Bei spateren Anwendungen des Heaps als Daten-struktur (siehe Abschnitte 8.4.4 und 10.3.2) kommen Heaps vor, bei denen die

”Schlussel“,

die dann Prioritaten heißen, zu einem Zeitpunkt mehrfach vorkommen.Ein Beispiel fur einen Heap zeigt Abbildung 8.5, wobei wir naturlich auf die Satelliten-

daten verzichtet haben. Die Knoten sind durchnumeriert. Es handelt sich um die Level-ordnung oder auch Niveauordnung, die wir bereits in Abschnitt 8.4.1 bei der Analyse deseinfachen randomisierten Quicksort verwendet haben.

Wir fordern von einem Heap zusatzlich, daß er nahezu vollstandig ist. Alle Tiefenniveausbis auf das letzte sind vollstandig. Was dieses angeht, so ist es von links nach rechts bis zueiner bestimmten Stelle vollstandig.

Wollten wir Heaps so implementieren, wie wir es mit binaren Suchbaumen getan haben,so wurden wir die Laufzeit unnotig vergroßern. Da Heaps nahezu vollstandig sind, konnenwir sie als Felder

A[0, n) of Integer (8.62)

86

Page 85: Skript Waack merged

Niveau 0

Niveau 1

Niveau 2

Niveau 3

9

8 5

7 6 4 1

3 2 4

0

1 2

3 4 5 6

7 8 9

Abbildung 8.5: Beispiel fur einen Heap

implementieren. Die Knoten werden durch ihren Index in der Niveauordnung dargestellt.Die Schlussel, die sie halten, sind die Feldeintrage. (Der Knoten aus Abbildung 8.5, derden Schlussel 8 tragt, wird beispielsweise durch den Index 1 reprasentiert.) Wir werden imweiteren das Feld A aus (8.62) als Heap A (mit n Knoten) bezeichnen. Um die Heapgroßezu dynamisieren, fuhren wir in der Rahmenklasse, die A als Datenfeld hat, zusatzlich einDatenfeld heapsize ein, das anzeigt, bis zu welchem Index der aktuelle Heap reicht:

A[0, heapsize)

ist der aktuelle Heap. Die Feldgroße n ist die maximale Große des Heaps. Alle Methoden,die nun folgen, gehoren zu dieser Rahmenklasse.

Diese Art der Implementation hat das folgende Lemma zur Grundlage.

Lemma 8.67 Sei A ein Heap mit n Knoten, und sei i ∈ 0, 1, . . . , n− 1 ein Knoten vonA. Dann gilt.

1. Der Knoten i hat genau dann keinen Sohn in A, wenn 2i + 1 ≥ n ist.

2. Der Knoten i hat genau einen Sohn in A, wenn 2i + 1 = n− 1 ist.

3. Der Knoten i hat genau zwei Sohne in A, wenn 2i + 2 ≤ n− 1 ist.

4. Es gilt:

(a) Falls der linke Sohn von Knoten i existiert, so ist es 2i + 1.

(b) Falls der rechte Sohn von Knoten i existiert, so ist es 2i + 2.

(c) Falls Knoten i nicht die Wurzel des Heaps ist (i > 0), so ist der Vater von igleich ⌊(i− 1)/2⌋.

87

Page 86: Skript Waack merged

5. depth A = ⌊log2 n⌋.

Beweisskizze. Alle Aussagen unseres Lemmas folgen mehr oder minder aus der folgen-den sehr einfachen Uberlegung:

Ist das d−1-Tiefenniveau vollstandig vorhanden, so handelt es sich dabei um die Knoten2d−1−1, 2d−1, . . ., 2d−1 +(k−1), . . ., 2d−2. Deren Sohne, soweit vorhanden, sind wie folgtangeordnet:

2d−1 − 1 . . . 2d−1 + (k − 1) . . . 2d − 2

2d − 1 2d. . . 2d + 2k − 1 2d + 2k . . . 2d+1 − 3 2d+1 − 2

Die Abbildungen 8.6, 8.7, 8.8, 8.9, 8.10 und 8.11 zeigen die Arbeitsweise von Standard-heapsort auf die Eingabe A[0, 7) = (5, 6, 3, 4, 1, 0, 2).

5

6 3

4 1 20

6

5

2

3

014

heapsize

Vertauschung

buildHeap[]

8 Vergleiche

Abbildung 8.6: Der Aufbau des Heaps

heapsize heapsize

5 3

014 6

2

62 1 0

5

34

Vertauschung

4 Vergleiche

Abbildung 8.7: Die Auswahlphase: Schritt 1

Abbildung 8.6 zeigt die Wirkung von Algorithmus 8.72 zur Heaperzeugung auf A[0, 7):Das Eingabefeld aufgefaßt als Baum ist noch kein Heap. Dieser muß erst aufgebaut werden.

Die darauf folgenden Schritte 8.7, 8.8, 8.9, 8.10 und 8.11 — sie zeigen den Zustanddes Heaps in der solange-Schleife von Algorithmus 8.76 unmittelbar vor und unmittelbar

88

Page 87: Skript Waack merged

heapsize heapsize

61

3

5

4

2

0

Vertauschung

62 1

34

5

0

4 Vergleiche

Abbildung 8.8: Die Auswahlphasephase: Schritt 2

heapsize heapsize

6

3

5

2

0

1

4 6

2

0 4 5

3

1

Vertauschung

2 Vergleiche

Abbildung 8.9: Die Auswahlphase: Schritt 3

nach der Ausfuhrung der Instruktion reheap(0, heapsize) — verlaufen alle nach demsel-ben Muster: Die Schlussel A[0] und A[heapsize− 1] tauschen die Platze. Anschließend istder Heap an der Wurzel gestort. Die Methode reheap (Algorithmus 8.68) stellt die Heapei-genschaft wieder her. Das geschieht auf die folgende Weise: Der Schlussel an der Wurzel istmoglicherweise zu klein. Man laßt ihn an seinen Platz

”sickern“. Dazu wird das Maximum

der Schlussel der beiden Sohne der Wurzel mit dem Schlussel verglichen, den diese tragt.Ist der

”maximale Sohn“ großer als der Vater, so tauschen beide die Schlussel und der Pro-

zeß iteriert mit dem maximalen Sohn als neuem Vater. Anderfalls ist die Heapeigenschaftwiederhergestellt.

Um auch etwas formaler noch vernunftig arbeiten zu konnen, sei zunachst A[0, ℓ) (ℓ ≤ n)derjenige Teilbaum von A[0, n), aus dem wir alle Knoten i ≥ ℓ entfernt haben. Sei k einKnoten von A[0, ℓ). Die Bedingung HB(k, ℓ) hat zwei Klauseln:

Klausel 1. Wenn 2k + 1 < ℓ ist, so ist A[k] ≥ A[2k + 1].

Klausel 2. Wenn 2k + 2 < ℓ ist, so ist A[k] ≥ A[2k + 2].

Die Notation HB(k, ℓ) bedeutet, daß beide Klauseln von HB(k, ℓ) wahr sind: AmKnoten k von A[0, ℓ) ist die Heapbedingung (8.61) erfullt.

89

Page 88: Skript Waack merged

6

2

4 5

1

0

3 64 5

1

Vertauschung

3

2

0

2 Vergleiche

Abbildung 8.10: Die Auswahlphase: Schritt 4

64 53

2

64 53

2

1

0 1

0

1 Vergleich

Abbildung 8.11: Die Auswahlphase: Schritt 5

Folglich ist A[0, ℓ) genau dann ein Heap, wenn fur alle Knoten gilt: k < ℓ HB(k, ℓ).

Algorithmus 8.68 (Wiederherstellung des Heaps)

Methodenkopf:reheap(k, ℓ)

Vorbedingung:Fur alle Nachfahren k′ von k in A[0, ℓ) gilt HB(k′, ℓ).

Nachbedingung:Ist k′ gleich k oder ein Nachfahre von k in A[0, ℓ), so ist HB(k′, ℓ).

Großschritt 1. [Basis.]1.1. [Knoten k ist das

”Sickerziel“, weil er keinen Sohn in A[0, ℓ) hat.]

Falls (2k + 1) ≥ ℓ, soreturn

1.2. [Berechnung des maximalen Sohns von k in A[0, ℓ).]Falls (2k + 1) = ℓ− 1, so fuhre aus:maxson← 2k + 1

Andernfalls fuhre aus:Falls A[2k + 1] > A[2k + 2], so maxson← 2k + 1Andernfalls maxson← 2k + 2

90

Page 89: Skript Waack merged

1.3. [Knoten k ist das”Sickerziel“, obwohl er einen Sohn in A[0, ℓ) hat.]

Falls A[k] ≥ A[maxson], soreturn

Großschritt 2. [Rekursion]A[k] A[maxson]reheap(maxson, ℓ)

Bemerkung. Wir haben Algorithmus 8.68 der großeren Ubersichtlichkeit halber rekur-siv aufgeschrieben. Wenn es wirklich darauf ankommt, koste es, was es wolle, mit jedemMaschinenbefehl zu sparen, sollte man der iterativen Variante, bei der die Folge der rekur-siven Aufrufe durch eine Schleife ersetzt wird, den Vorzug geben.

Der Beweis des folgenden Lemmas durch vollstandige Induktion uber die Anzahl derKnoten von A[0, ℓ) ist eine leichte Ubungsaufgabe.

Lemma 8.69 Algorithmus 8.68 arbeitet korrekt.

Wir kommen zur Anzahl der Schlusselvergleiche und damit zur Laufzeit von Algorith-mus 8.68.

Lemma 8.70 Es ist keyComp(reheap(k, ℓ)) = 2 ·⌊log2

ℓk+1

⌋.

Beweis. Die Inspektion des Pseudocodes von Algorithmus 8.68 zeigt fur den Aufrufvon reheap(k, ℓ) folgendes.

”Sickert“ der Schlussel A[k] bis zu einem Blatt durch, wobei

stets der linke Sohn maximal ist, liegt ein schlechtester Fall vor. Der Abbruch erfolgt inGroßschritt 1.1. Bei diesem letzten Aufruf kommt es zu keinem Schlusselvergleich mehr.

Wie groß ist in diesem schlechtesten Fall die Anzahl r0 der rekursiven Aufrufe ein-schließlich des ersten, bei denen es zu Schlusselvergleichen kommt? Es sind genau jene, beidenen Großschritt 1.1 nicht zum Abbruch fuhrt. Folglich gilt:

r0 = max

r | 2rk + 2r−1 + 2r−2 + . . . + 1

︸ ︷︷ ︸

2r−1

≤ ℓ− 1

= max r | 2r(k + 1) ≤ ℓ = max

r | 2r ≤ ℓ

k + 1

Aus der Gleichung 1.3 erhalten wir

r0 =

log2

k + 1

.

Da es in jedem dieser r0 Aufrufe zu hochstens zwei Vergleichen kommt, folgt die Behaup-tung.

Korollar 8.71 Es ist time(reheap(k, ℓ)) = O(log ℓ

k+1

).

91

Page 90: Skript Waack merged

Nun ist klar, wie man Algorithmus 8.68 einsetzen kann, um den Heap am Anfangaufzubauen: Man wendet ihn in reverser Level-Ordnung, beginnend mit dem vorletztenTiefenniveau, von unten nach oben an. (Der erste Knoten, fur den etwas zu tun ist, istdann der Vater ⌊(n − 2)/2⌋ = ⌊n/2⌋ − 1 des letzten Knotens n− 1.) Das sichert stets dieGultigkeit der Vorbedingung.

Algorithmus 8.72 (Aufbau des Heaps)

Methodenkopf:buildheap()

Rumpf:Fur j = ⌊n/2⌋ − 1, . . . , 0 fuhre aus.reheap(j, n)

Uber den Beweis von Lemma 8.73 laßt sich dasselbe sagen wie uber den Beweis vonLemma 8.69.

Lemma 8.73 Algorithmus 8.72 arbeitet korrekt.

Wir kommen zur Anzahl der Schlusselvergleiche und damit zur Laufzeit von Algorith-mus 8.72.

Lemma 8.74 Es ist keyComp(buildheap()) < 2 · n.

Beweis. Nach Lemma 8.70 laßt sich die Anzahl der Schlusselvergleiche von buildheap()wie folgt nach oben beschranken.

keyComp(buildheap()) ≤ 2

⌊n/2⌋−1∑

k=0

log2

n

k + 1

= 2

⌊n/2⌋∑

k=1

log2

n

k

= 2

⌊log2 n⌋∑

d=1

d · card

k | d =⌊

log2

n

k

= 2

⌊log2 n⌋∑

d=1

d · card

k | d ≤ log2

n

k< d + 1

= 2

⌊log2 n⌋∑

d=1

card

k | d ≤ log2

n

k

= 2

⌊log2 n⌋∑

d=1

cardk | 2dk ≤ n

︸ ︷︷ ︸

≤n/2d

≤ 2

⌊log2 n⌋∑

d=1

n/2d < 2 · n.

92

Page 91: Skript Waack merged

Korollar 8.75 Es ist time(buildheap()) = O (n) .

Nun sind wir in der Lage, den Standard-Heapsortalgorithmus aufzuschreiben.

Algorithmus 8.76 (Standard-Heapsort)

Methodenkopf:heapsort()

Nachbedingung:Das Eingabefeld A[0, n) ist aufsteigend sortiert.

Großschritt 0.Falls n ≤ 1, so return.

Großschritt 1. [Aufbauphase des Heaps.]buildheap()

Großschritt 2. [Auswahlphase.]heapsize← nSolange heapsize ≥ 2 fuhre aus.

A[0] A[heapsize − 1]heapsize← heapsize − 1reheap(0, heapsize)

Aus Lemma 8.69 und Lemma 8.73 folgt sofort die Korrektheit von Algorithmus 8.76.Lemma 8.70, Lemma 8.74, Korollar 8.71 und Korollar 8.75 fuhren unmittelbar zu demfolgenden Satz uber die Laufzeit von Standard-Heapsort.

Satz 8.77 Die Anzahl der Schlusselvergleiche von Algorithmus 8.76 auf jede Eingabe derLange n ist durch 2n (⌊log2 n⌋+ 1) nach oben beschrankt.

Die Laufzeit ist ein O (n log n) .

8.4.3 Bottom-Up Heapsort

Selbst die einfachste Variante von Quicksort schlagt Algorithmus 8.76 fur eine zufalligeEingabe mit hoher Wahrscheinlichkeit. Der Grund dafur liegt darin, daß die Konstantedes fuhrenden Terms der Schlusselvergleichsanalyse fur Quicksort (siehe Satz 8.65) mit1, 386 . . . deutlich niedriger ist als bei Standard-Heapsort (siehe Satz 8.77). Will man Ab-hilfe schaffen, kommt nur eine Verbesserung der Methode reheap fur die Anwendung inGroßschritt 2 von Algorithmus 8.76 in Betracht. (Der Einsatz der verbesserten Variante inGroßschritt 1 lohnt sich kaum.) Es kommt darauf an, die Anzahl der Vergleiche je

”Sicker-

schritt“ zu veringern. Wir konnen uns auf den Fall beschranken, daß in A[0, heapsize) dieHeapbedingung nur an der Wurzel gestort ist. Die folgenden zwei Beobachtungen sind furunsere Verbesserungsbemuhungen maßgebend:

93

Page 92: Skript Waack merged

1. Eine grundliche Analyse dessen, was in Algorithmus 8.76 geschieht, zeigt, daß derPfad, langs dessen ein zu kleines Element von der Wurzel aus versickert, von diesemunabhangig ist und vorab berechnet werden kann: Man muß einen Pfad maximalerSohne nehmen.

2. Wir wissen, daß mehr als die Halfte der Knoten eines vollstandigen binaren BaumesBlatter sind, mehr als 75% in den untersten beiden Niveaus liegen usw. Deshalbwird es sehr haufig vorkommen, daß der Schlussel der Wurzel bis fast ganz nachunten versickern wird. Dann aber ist es vernunftig, den Wurzelschlussel von untenan seinen Platz aufsteigen zu lassen.

Definition 8.78 Sei A[0, m) ein hochstens an der Wurzel gestorter Heap.Eine Folge (b0, b1, b2, . . . , bλ) von Knoten aus A heißt Pfad maximaler Sohne in A, wenn

1. Knoten b0 gleich der Wurzel 0 ist;

2. fur jedes j = 1, 2, . . . , λ der Knoten bj ein maximaler Sohn des Knotens bj−1 ist:

bj =

argmaxA[2bj−1 + 1], A[2bj−1 + 2] falls 2bj−1 + 2 < m;

2bj−1 + 1 sonst;

wobei argmax in Abschitt 1.7, Gleichung 1.49 definiert ist;

3. Knoten bλ ein Blatt ist.

Bemerkung. Ist

(b0, b1, b2, . . . , bλ)

ein Pfad maximaler Sohne, so gilt fur die zugehorigen Schlussel sj := A[bj ] (j = 1, 2, . . . , λ)

s1 ≥ s2 ≥ . . . ≥ sλ

Aus Bequemlichkeit setzen wir sλ+1 := −∞.

Algorithmus 8.79 (Generische Wiederherstellung des Heaps an der Spitze)

Vorbedingung:Fur alle Nachfahren k von 0 in A[0, heapsize) gilt HB(k, heapsize)).

Nachbedingung:Fur alle k in A[0, heapsize) gilt HB(k, heapsize)).

Großschritt 1. [Berechnung eines Pfades maximaler Sohne]Mache einen Pfad maximaler Sohne

p := (b0, b1, b2, . . . , bλ)verfugbar.

94

Page 93: Skript Waack merged

Großschritt 2. [Verschiebung der Schlussel langs des Pfades maximaler Sohne.]2.1.[Auffinden des Verschiebeziel.]

Ist s1 ≥ s2 ≥ . . . ≥ sλ die Schlusselfolge auf p ohne die Wurzel, sobestimme einen Index i ∈ 0, 1, . . . , λ mit si ≥ s0 ≥ si+1.

2.2.[Verschiebung der Schlussel zum Verschiebeziel.]Falls i = 0, soreturn

Fur j = 0, 1, . . . , i− 1 fuhre aus.A[bj ]← sj+1

A[bi]← s0

Bemerkung. Wir beobachten, daß auch reheap(1, heapsize) (spezieller Aufruf vonAlgorithmus 8.68) eine konkrete Auspragung des generischen Algorithmus 8.79 ist: DieVerfugbarmachung des Pfades maximaler Sohne heißt naturlich nicht die Vorabberechnungaller seiner Knoten. Deshalb ist die Korrektheit von Algorithmus 8.79 genauso zu beweisenwie die Korrektheit von Algorithmus 8.68.

Folglich ist jede andere konkrete Implementation von Algorithmus 8.79 korrekt.

Wir spezialisieren Algorithmus 8.79 zu dem folgenden generischen Bottom-Up-Reheap-Algorithmus.

Algorithmus 8.80 (Generisches Bottom-Up-Reheap)

Vorbedingung:Fur alle Nachfahren k von 0 in A[0, heapsize) gilt HB(k, heapsize)).

Nachbedingung:Fur alle k in A[0, heapsize) gilt HB(k, heapsize)).

Großschritt 1. [Ablage eines Pfades der maximalen Sohne in einem Feld]B[0]← 0λ← ⌊log2 heapsize⌋Fur j = 1, 2, . . . , λ fuhre aus.

Berechne maxson von B[j − 1] wie in Algorithmus 8.68.B[j]← maxson

Großschritt 2. [Verschiebung der Schlussel langs des Pfades maximaler Sohne.]2.1.[Auffinden des Verschiebeziels (generischer Teilschritt).]

Bestimme einen Index i ∈ 0, 1, . . . , λ mitA[B[i]] ≥ A[0] ≥ A[B[i + 1]].

2.2.[Verschiebung der Schlussel zum Verschiebeziel.]Falls i = 0, soreturn

S ← A[0]Fur j = 0, 1, . . . , i− 1 fuhre aus.

A[B[j]]← A[B[j + 1]]A[B[i]]← S

95

Page 94: Skript Waack merged

Bemerkung. Man kann die Ablage eines Pfades der maximalen Sohne in einem Feld ver-meiden. Bei unserer Definition eines in-situ Algorithmus ist sie jedoch unschadlich.

Nun liegen zwei konkrete Implementationen von Algorithmus 8.80, genauer gesagt, vondessen Großschritt 2.1, auf der Hand.

Lineares Sondieren von unten.

i← λSolange A[0] > A[B[i]]

i← i− 1.

Binare Suche. Ermittle das Verschiebeziel i durch binare Suche.

Satz 8.81 Die Anzahl der Schlusselvergleiche von Bottom-Up Heapsort mit binarer Sucheauf jede Eingabe der Lange n ist durch n log2 n+n log2 log2 n+O (n) nach oben beschrankt.

Die Laufzeit ist ein O (n log n) .

Beweis. Ist der Logarithmus zur Basis zwei der aktuellen Große des Heaps gleich λ, sokostet ein Aufruf von Algorithmus 8.80 mit binarer Suche fur Großschritt 2.1 λ + log2 λSchlusselvergleiche: λ Vergleiche fur die Berechnung des Feldes der maximalen Sohne undlog2 λ Vergleiche fur die binare Suche.

Bemerkung. Obwohl Bottom-Up Heapsort mit binarer Suche das, was die Schlussel-vergleiche angeht, asymptotisch beste Verfahren ist, zeigen Experimente, daß es nur einegeringe praktische Bedeutung hat: Es ist besser als das einfache Quicksort, falls n ≥ 400und besser als die verfeinerte Variante von Quicksort, bei der drei Pivotkandidaten insAuge gefaßt und dann der Median ausgewahlt wird, falls n ≥ 16.000 ist.

Ohne Beweis nehmen wir zur Kenntnis.

Satz 8.82 Die Anzahl der Schlusselvergleiche von Bottom-Up Heapsort mit linearer Suchevon unten auf jede Eingabe der Lange n ist durch 3

2n log2 n +O (n) nach oben beschrankt.

Die Laufzeit ist ein O (n log n) .

8.4.4 Der Heap als Datenstruktur

Wir verwenden nun den Heap, um die Prioritatswarteschlange zu implementieren: Es wer-den Mengen von Datenobjekten eines in unserem Falle naturlich generischen Typs GT

verwaltet, der ein ganzzahliges Datenfeld priority hat. Je großer der Wert dieses Da-tenfeldes, desto großer die Prioritat des Objektes. Das kann man dadurch erreichen, daßin jedem stabilen Zustand der Prioritatswarteschlange das Element, das an der Reihe ist,unter allen, die warten, hochste Prioritat hat.

Die folgenden Operationen werden von der Klasse MaxPriorityQueue unterstutzt:

96

Page 95: Skript Waack merged

create(Integer n). Erzeugt wird die leere Prioritatswarteschlange mit einer Aufnahme-kapazitat fur n Objekte.

empty() returns boolean. Es wird uberpruft, ob die aktuelle Warteschlange leer ist.

top() returns GT. Diese Operation verandert die Warteschlange nicht. Sie gibt einenZeiger auf ein Objekt hochster Prioritat unter den gespeicherten Objekten zuruck,sofern die Warteschlange nichtleer ist. Andernfalls erfolgt eine Fehlermeldung.

add(GT g). Das Objekt g wird der aktuellen Warteschlange hinzugefugt, sofern diese nochnicht voll ist.

remove(). Falls die aktuelle Warteschlage nichtleer ist, wird das Objekt aus der Warte-schlange entfernt, das top() zuruckgibt.

siftup(GT g, Integer newpriority). Versieht das in der aktuellen Warteschlange ge-speichertes Objekt g mit der neuen Prioritat newpriority, sofern diese großer ist alsdie alte. Ist das Objekt g nicht in der aktuellen Warteschlange gespeichert oder aberdie neue Prioritat kleiner als die alte, so wird mit einer Fehlermeldung abgebrochen.

Bemerkung. In vollig analoger Weise laßt sich die Klasse MinPriorityQueue spezifizie-ren (und implementieren), bei der kleinere Werte des Datenfeldes priority den Vorranganzeigen.

Wie sieht unsere konkrete Implementation der Klasse MaxPriorityQueue aus? Wirsetzen einen Heap

C[0, n) of GT (8.63)

als die eigentliche Warteschlange ein. Naturlich gibt es auch das Datenfeld heapsize, dasdie Große der aktuellen Warteschlange unterhalb der maximalen Große n halt.

Wir sind im weiteren an Algorithmus 8.68 interessiert. Er bleibt verwendbar, wobei nundie Prioritat C[i].priority() die Rolle der Schlusselwerte A[i] spielt.

Ist ein Objekt g des Typs GT in einer Warteschlange gespeichert, die das Feld C aus(8.63) zur Grundlage hat, wurden wir viel an Effizienz aufgeben, wenn wir fur g nichtseinen

”Tragerindex“ in C verfugbar machten. Dazu nehmen wir an, daß die Klasse GT

ein Datenfeld carrier hat, so daß fur jedes Objekt g des Typs GT zur Laufzeit stetsgilt: Es ist genau dann g.carrier() = i ≥ 0, wenn C[i] = g ist. (Um das zu sichern,muß Algorithmus 8.68 an geeigneter Stelle um Instruktionen angereichert werden, die dascarrier-Datenfeld aktualisieren.) Bei diesem Ansatz kann zur Laufzeit kein Objekt g inzwei Prioritatswarteschlangen gleichzeitig sein. In unseren Anwendungen kommt letzteresjedoch nicht vor.

Wir mussen Algorithmus 8.68 um die Pflege der Tragerindizes anreichern: Immer dann,wenn zwei Objekte die Platze tauschen, mussen auch die Werte ihrer carrier-Datenfeldervertauscht werden.

97

Page 96: Skript Waack merged

Die Implementation mit Hilfe eines Feldes setzt dem Einfugen Grenzen. Naturlich konn-te man, wie beim Hashing, eine Verdopplungsstrategie vorsehen. Aber das ist fur unsereAnwendungen nicht notwendig.

Wir kommen zu den Algorithmen fur die Operationen. Wir beschranken uns auf add,remove und siftup. (Der Rest ist algorithmisch uninteressant.) Unsere Kenntnisse uberdie Heapsortalgorithmen machen deren Korrektheitsbeweise und Laufzeitanalysen zu einerleichten Ubungsaufgabe.

Algorithmus 8.83 (Entfernen)

Methodenkopf:remove()

Großschritt 1. [Abbruch, falls Schlange leer.]Falls heapsize = 0

Fehlermeldung, beispielsweise:”Schlange leer, oh Du Saule der Informatik.“

return

Großschritt 2.C[0]← C[heapsize − 1]C[0].carrier← 0heapsize← heapsize − 1reheap(0, heapsize)

Bei dem nun folgenden Beforderungsalgorithmus wird das Objekt, dessen Prioritaterhoht worden ist, langs des eindeutig bestimmten Weges von der Wurzel zu seinemTragerindex nach oben geschoben.

Algorithmus 8.84 (Beforderung)

Methodenkopf:siftup(g, newpriority)

Großschritt 1. [Abbruch bei falscher Eingabe.]i← g.carrier()Falls (i 6∈ [0, heapsize)) oder (i ∈ [0, heapsize) und C[i] 6= g)

Fehlermeldungreturn

Falls C[i].priority() > newpriority

Fehlermeldung:”Du willst mich degradieren? Nichtsda!“

return

Großschritt 2.C[i].priority← newpriority

Solange (i > 0 und C[i].priority() > C[(i− 1)/2].priority()) fuhre aus.C[i] C[(i− 1)/2]C[i].carrier C[(i− 1)/2].carrier

98

Page 97: Skript Waack merged

i← ⌊(i− 1)/2⌋

Hinzugefugt wird, indem das in Rede stehende Objekt an die letzte Position mit derkleinstmoglichen Prioritat eingefugt und dann zu seiner eigentlichen Prioritat befordertwird.

Algorithmus 8.85 (Hinzufugen)

Methodenkopf:add(g)

Großschritt 1. [Abbruch, wenn Schlange voll.]Falls heapsize = n

Fehlermeldungreturn

Großschritt 2.heapsize← heapsize + 1C[heapsize − 1]← g

g.carrier← heapsize − 1priority← g.priority()g.priority← −∞siftup(g, priority)

Satz 8.86 Hat die zu Grunde liegende Prioritatswarteschlange die Große m, so ist dieLaufzeit der Algorithmen 8.83, 8.84 und 8.85 ein O (log2 m).

Die bisher betrachteten Heaps nennt man auch 2-Heaps. In vollig analoger Weise kannman d-Heaps einfuhren, wobei d eine naturliche Zahl großer als zwei ist. Werden d-Heapszur Implementation von Prioritatswarteschlangen eingesetzt, ist die Zahl d in der Regelkeine Konstante, sondern hangt von der Kapazitat n der Warteschlange ab (siehe Abschnitt10.3.2). Bei einem d-Heap haben alle Knoten bis auf die aus den beiden tiefsten Niveausgenau d Sohne. Alle Algorithmen aus diesem und den Abschnitten 8.4.2 und 8.4.3 lassensich in kanonischer Weise ubertragen. Der Beweis des folgenden Satzes ist offensichtlich.

Satz 8.87 Hat die zu Grunde liegende Prioritatswarteschlange die Große m, so ist furd-Heaps die Laufzeit von Algorithmus 8.83 ein O (d · logd m), die Laufzeit der Algorithmen8.84 und 8.85 ein O (logd m).

8.4.5 Internes Mergesort

Die Grundidee ist einfach. Sie verwirklicht das Teile–und–Herrsche–Prinzip:

99

Page 98: Skript Waack merged

Teile die Eingabefolge A[v, v+ l) — am Anfang ist naturlich v = 0 und l = n — der Langel in die Folge A[v, v+⌊l/2⌋) der Lange ⌊l/2⌋ und die Folge A[v+⌊l/2⌋, v+l) der Lange⌈l/2⌉. (Es ist offensichtlich, daß fur jede ganze Zahl z die Gleichung z = ⌊z/2⌋+⌈z/2⌉erfullt ist.)

Beherrsche die Teilfolgen durch rekursiven Aufruf.

Kombiniere die sortierten Teilfolgen durch Mischen zu einer sortierten Gesamtfolge.

Wie sieht das Mischen monoton sortierter Teilfolgen zu einer sortierten Gesamtfolgeaus? Wir nehmen ab jetzt an, daß unser Algorithmus neben dem Eingabefeld A, auf daser lesend und schreibend zugreifen kann, noch uber ein zweites Hilfsfeld B gleicher Langeverfugt. Zunachst spezifizieren wir unseren Algorithmus merge(v, l), der zwei Teilfeldervon A mischen soll. Ihm werden zwei Indizes v und l ubergeben, wobei v der Anfangsindexunseres Teilfeldes und l dessen Lange ist.

Vorbedingung: Die Teilfelder A[v, v + ⌊l/2⌋) und A[v + ⌊l/2⌋, v + l) sind aufsteigendsortiert.

Nachbedingung: Das Teilfeld A[v, v + l) ist aufsteigend sortiert.

Nun geht es zur Sache.

Algorithmus 8.88 (Mischen zweier sortierter Teilfelder)

Methodenkopf:merge(v, l)

Rumpf:Großschritt 1.

Kopiere A[v, v + l) auf B[v, v + l).Großschritt 2.

Initialisiere i, j und k mit den Werten v, v + ⌊l/2⌋ und v.Fuhre aus:min← minB[i], B[j]A[k]← min

k← k + 1.Falls min = B[i] ist,i← i + 1.

Andernfallsj← j + 1.

bis daß i = v + ⌊l/2⌋ oder j = v + l.Großschritt 3.

Falls i = v + ⌊l/2⌋ fuhre aus:Fuhre aus:

A[k]← B[j]

100

Page 99: Skript Waack merged

j← j + 1, k← k + 1bis daß j = v + l.

Andernfalls fuhre aus.Fuhre aus:

A[k]← B[i]i← i + 1, k← k + 1

bis daß i = v + ⌊l/2⌋.

Die Korrektheit von Algorithmus 8.88 ist offensichtlich. Was ist mit seiner Laufzeit?Lemma 8.89 gibt Antwort.

Lemma 8.89 1. Die Anzahl der Schlusselvergleiche fur das Mischen eines Arrays Ader Lange l vermoge des vorstehenden Algorithmus ist durch l − 1 nach oben unddurch ⌊l/2⌋ nach unten beschrankt.

2. Jeder vergleichsorientierte Algorithmus A, der ein Array der Lange l in der vor-stehend spezifizierten Weise mischt, benotigt im schlechtesten Fall l − 1 Vergleichezwischen Schlusselelementen.

Beweis. Behauptung 1. Nach jedem Schlusselvergleich wird ein Schlussel vom Hilfsfeldauf das Hauptfeld umkopiert. Dies geschieht solange, bis die eine Halfte des Hilfsfeldesleer ist. Im besten Falle reichen ⌊l/2⌋ Vergleiche. Dieser tritt ein, wenn jeder Schlusselaus der linken Halfte kleiner oder gleich jedem Schlussel aus der rechten Halfte ist. Imschlechtesten Fall sind die Schlussel der beiden Halften wie im Falle des Beweises vonBehauptung 2 verschrankt. Dann bleibt nach dem letzten Vergleich in der rechten Halftedes Hilfsfeldes genau ein Schlussel stehen, der ohne Vergleich umgespeichert werden kann.

Behauptung 2. Wir fuhren den Beweis indirekt und nehmen das Gegenteil an. Sei Aein Algorithmus, der mit weniger als l − 1 Vergleichen im schlechtesten Fall mischt. Wirnehmen an, daß der Inhalt des Feldes A[0, l) die folgende Eigenschaft hat:

A[0] < A[⌊l/2⌋] < A[1] < A[⌊l/2⌋+ 1] < A[2] < . . . < A[⌊l/2⌋ − 1] < A[l − 1].

Dann kann wenigstens eines der Paare A[ν], A[ν + ⌊l/2⌋] oder A[ν + ⌊l/2⌋], A[ν + 1] von Anicht miteinander verglichen worden sein. Folglich wurde der Algorithmus A die Eingabein derselben Weise permutieren, wenn man die Großenverhaltnisse genau dieses Paaresumdrehte. Widerspruch.

Aus Lemma 8.89 folgt insbesondere, daß die Laufzeit des Algorithmus merge(v, l) – sie istproportional zur Anzahl der Schlusselvergleiche – ein O (ℓ) ist.

Wir kommen nun zum Algorithmus mergesort(v, l), dessen Aufgabe darin besteht, dasEingabeteilfeld A[v, v + l) aufsteigend zu sortieren und dabei die anderen Feldelementeunberuhrt zu lassen.

Algorithmus 8.90 (Mergesort)

101

Page 100: Skript Waack merged

Methodenkopf:mergesort(v, l)

Rumpf:Großschritt 1. [Basis.]

Falls l ≤ 1 ist, so return.Falls l = 2 ist, so fuhre aus:

Sortiere das Teilfeld durch Vergleich der Schlussel A[v] und A[v + 1]return

Großschritt 2. [Rekursion.]mergesort(v, ⌊l/2⌋)mergesort(v + ⌊l/2⌋, ⌈l/2⌉)merge(v, l)

Satz 8.91 1. Algorithmus 8.90 arbeitet korrekt.

2. Die Anzahl der Schlusselvergleiche ist kleiner oder gleich n · ⌈log2 n⌉ − 2⌈log2 n⌉ + 1,wobei n die Lange der ubergebenen Sequenz ist.

3. Die Laufzeit ist O (n log n).

Beweis. Die Korrektheit von Algorithmus 8.90 auf der Grundlage der Korrektheit vonAlgorithmus 8.88 ist sofort einzusehen: Ein einfacher Induktionsbeweis uber die Lange desArrays fuhrt zum Ziel.

Fur die Abschatzung der Anzahl der Schlusselvergleiche werden wir uns, um uns dasLeben zu erleichtern, auf den Fall beschranken, daß die Eingabenlange eine Potenz der Zahl2 ist: n = 2k. Die Anzahl der Vergleiche V (n) genugt der folgenden einfachen Rekursion:

V (1) = 0

V (n) ≤ n− 1 + 2 · V (n/2)

Die Auflosung dieser Rekursion ist kein Problem. Fur alle l ≤ log2 n = k gilt:

V (n) ≤ (n− 1) + (n− 2) + . . . + (n− 2l−1) + 2lV (n/2l)

Wegen V (n/2k) = V (1) = 0 ist

V (n) ≤ k · n−k−1∑

l=0

2l ≤ k · n− n + 1.

Die Aussage uber die Gesamtlaufzeit ist eine leichte Ubungsaufgabe.

102

Page 101: Skript Waack merged

8.4.6 Untere Schranken fur das vergleichsorientierte Sortieren

Wir haben bisher vergleichsorientierte Sortieralgorithmen studiert. Die mittlere Anzahlvon Schlusselvergleichen bei deterministischen bzw. die erwartete Anzahl von Schlussel-vergleichen bei randomisierten Algorithmen war stets ein Ω(n log2 n). Lag das an unseremUnvermogen, bessere Algorithmen zu entwerfen, oder geht es wirklich nicht besser? Indiesem Abschnitt geben wir auf diese Frage eine Antwort.

Fur die Zwecke dieses Abschnitt schreiben wir die Spezifikation eines vergleichsorien-tierten Sortieralgorithmus nochmals auf. Dazu sei S = Sn eine total geordnete n-Mengevon Schlusseln.

Eingabe. Eine Anordnung s1, s2, . . . sn aller Schlussel aus S. Wir fassen dabei die Elementesi als Variable uber der Schlusselmenge S auf.

Ausgabe. Eine Umordnung sπ(1), sπ(2), . . . , sπ(n) (π ∈ Sn) der Eingabe, so daß sπ(1) <sπ(2) < . . . < sπ(n) ist.

Wir interessieren uns zunachst fur deterministische vergleichsorientierte Sortieralgorith-men A und deren mittlere Anzahl

keyCompaverageA (n)

von Schlusselvergleichen auf Eingaben der Lange n. Die Haupteigenschaft solcher Algorith-men ist, daß im Laufe jeder Rechnung die einzigen Verzweigungspunkte Schlusselverglei-che si > sj? sind. An diesen und nur an diesen Stelle erfolgt der Zugriff auf die Eingabe.Folglich kann man alle Rechnungen auf Eingaben der Lange n durch einen sogenanntenEntscheidungsbaum protokollieren. Ein Beispiel sieht man in Abbildung 8.12.

s1 < s2 < s3 s1 > s2

s1 > s2

s2 > s3

s1 > s3

s1 < s3 < s2

s3 < s1 < s2 s3 < s2 < s1

s1 > s3

s2 < s3 < s1s2 < s1 < s3

0

0 0

0

1

1

1 1

1

0

1 - wahr

0 - falsch

Abbildung 8.12: Ein Entscheidungsbaum zum Sortieren von drei Schlusseln

Definition 8.92 [Entscheidungsbaum]

103

Page 102: Skript Waack merged

Syntax. Ein Entscheidungsbaum Bn fur das vergleichorientierte Sortieren von Problem-stellungen der Große n ist ein voller geordneter binarer Wurzelbaum, dessen innereKnoten einschließlich der Wurzel Markierungen der Art

”si > sj“ fur 1 ≤ i 6= j ≤ n

tragen. Die ausgehenden Kanten sind mit 0 oder mit 1 markiert. Die n! Blatter sindmit allen Permutationen π ∈ Sn markiert. (Wir schreiben fur die Markierungen derBlatter

”sπ(1) < sπ(2) < . . . < sπ(n)“ und vermischen damit Syntax und Semantik

etwas. Dafur ist sofort klar, worauf es ankommt.)

Semantik. Fur jede Eingabe s1, s2, . . . , sn gibt es einen eindeutig bestimmten Pfad vonder Wurzel zu einem Blatt, der in jedem Verzweigungspunkt mit Markierung

”si > sj“

die ausgehende 1-Kante auswahlt, wenn dies fur die Eingabe wahr ist. Andernfallswird die ausgehende 0-Kante ausgewahlt.

Korrektheit. Fur jede Eingabe s1, s2, . . . , sn tragt das Blatt, zu dem der Berechnungspfadder Eingabe in Bn fuhrt, die korrekte Markierung.

Bemerkungen.

• Ist A ein vergleichsorientierter Sortieralgorithmus, so kann man A eine Folge vonEntscheidungsbaumen

(Bn(A)

)

n∈Nzuordnen, die fur jedes n alle Problemstellungen

der Große n korrekt sortieren. Fur jedes n und jede Eingabe s1, s2, . . . , sn ist

keyCompA(s1, s2, . . . , sn) = depthBn(A)(v),

wobei v das Blatt ist, zu dem der Berechnungspfad in Bn(A) unter der Eingabes1, s2, . . . , sn fuhrt.

• Fur jedes n definiert der Entscheidungsbaum Bn(A) auf kanonische Weise einenprafixfreien Code

cAn : Sn → 0, 1∗, (8.64)

fur dessen erwartete Wortlange unter der Voraussetzung, daß Π ein gleichverteiltesZufallselement aus der Menge Sn der Permutationen von 1, 2, . . . , n ist, gilt:

E LcAn(Π) =

1

n!

v ist Blattvon Bn(A)

depthBn(A) v = keyCompaverageA (n). (8.65)

• Aus der elementaren Analysis kennen wir die Stirlingsche Formel:

n! =√

2πn · nn

en· e Θn

12n (Θn ∈ (0, 1))

Es folgt:

log2 n! = n log2 n− 1, 44n + Θ(log2 n).

104

Page 103: Skript Waack merged

Da log2 n! die Entropie der Gleichverteilung auf Sn ist, erhalten wir aus dem Quellen-codierungssatz (Satz 3.17) den folgenden Satz.

Satz 8.93 Ist A ein beliebiger deterministischer vergleichsorientierter Sortieralgorithmus,so ist fur jede Problemgroße n

log2 n! ≤ keyCompaverageA (n). (8.66)

Zum Abschluß kommen wir zu einer unteren Schranke fur randomisierte vergleichsori-entierte Sortieralgorithmen. Wir bemerken, daß wir uns randomisierte Algorithmen aufeine Eingabe der Große n in der Weise normalisiert denken konnen, daß

– zuerst eine Folge zufalliger Bits

Υ0, Υ1, . . . , Υρ(n)

(siehe dazu Abschnitt 8.3.6) erzeugt wird, und dann

– die weitere Rechnung in Abhangigkeit von der Eingabe und den Werten, welche dieZufallsbits angenommen haben, deterministisch erfolgt.

Unser randomisiertes Quicksort ist ein sogenannter Las-Vegas-Algorithmus: Gleich-gultig, welche Werte die Zufallsbits angenommen haben, berechnet der Algorithmus imweiteren stets das richtige Ergebnis. Die Werte der Zufallsbits beeinflussen lediglich dieLaufzeit. Monte-Carlo-Algorithmen dagegen berechnen nicht immer das richtige Ergebnis.Naturlich muß letzteres mit hoher Wahrscheinlichkeit der Fall sein, damit der Algorithmuseinen praktischen Wert haben soll.

Satz 8.94 Ist A ein beliebiger vergleichsorientierter Las-Vegas-Sortieralgorithmus, so gibtes fur jede Problemgroße n eine Eingabe s = (s1, s2, . . . , sn) derart, daß

log2 n! ≤ E keyCompA(s1, s2, . . . , sn). (8.67)

Beweis. Sei n eine beliebige, aber feste Problemgroße. Dann konnen wir dem Las-Vegas-Algorithmus A eine Folge von 2ρ(n) Entscheidungsbaumen Bn,j (j = 0, 1, . . . , 2ρ(n) − 1)zuordnen, die alle das Sortierproblem fur Eingaben der Lange n losen. Die Wirkung vonA auf solche Eingaben besteht darin, daß mit Wahrscheinlichkeit 2−ρ(n) einer dieser Ent-scheidungsbaume

”ausgewurfelt“ wird, mit Hilfe dessen dann sortiert wird.

Wir fuhren den Beweis indirekt. Angenommen, fur alle Eingaben s = (s1, s2, . . . , sn)gilt

log2 n! > E keyCompA(s).

Das ist gleichbedeutend mit

log2 n! >1

2ρ(n)·

2ρ(n)−1∑

j=0

depthBn,jvn,j(s)

105

Page 104: Skript Waack merged

fur alle s, wobei vn,j(s) das Blatt ist, zu dem der Berechnungspfad zu der Eingabe s imEntscheidungsbaum Bn,j fuhrt. Indem wir uber alle n! Eingaben der Lange n mitteln unddie Summationsindizes vertauschen, erhalten wir

log2 n! >1

2ρ(n)·

2ρ(n)−1∑

j=0

1

n!

v ist Blattin Bn,j

depthBn,jv

.

Dann muß es aber einen Index j ∈ 0, 1, . . . , 2ρ(n) − 1 mit

log2 n! >1

n!

v ist Blattin Bn,j

depthBn,jv

geben. Das steht im Widerspruch zu Satz 8.93.

8.5 Sortieren reeller Zahlen durch Fachverteilung

In diesem Abschnitt werden wir sehen, daß man den Sortiervorgang deutlich beschleunigenkann, wenn man aus den Schlusseln nicht nur durch Vergleich untereinander Informationengewinnt.

Die Situation. Uns ist ein Feld

A[0, n) of Real (8.68)

gegeben, das aufsteigend sortiert werden soll. Vorausgesetzt wird, daß die Folge

A[0], A[1], . . . , A[n− 1] (8.69)

unabhangige, gleichverteilte Zufallsvariablen aus [0, 1) sind.Die Grundidee von Algorithmus 8.95 knupft an unsere Vorstellungen uber die gleichmaßi-

ge Verteilung der Schlussel beim offenen Hashing (siehe Abschnitt 8.3.2) an. Das Intervall[0, 1) wird in n gleichlange Teilintervalle

[jn, j+1

n

)(j = 0, 1, . . . , n− 1) partitioniert, denen

Buckets q[j] zugeordnet werden. Fur jedes i = 0, 1, . . . , n− 1 verfahren wir wie folgt. Wirlegen den Schlussel A[i] genau dann in das Bucket q[j], wenn

j

n≤ A[i] <

j + 1

n⇐⇒ j = ⌊n ·A[i]⌋ (8.70)

ist. Anschließend werden die Buckets z.B. mit Heapsort sortiert und abschließend unterWahrung der nun bereits ermittelten Ordnung auf A zuruckgespeichert. Wir erhalten:

Algorithmus 8.95 (Sortieren durch Fachverteilung)

106

Page 105: Skript Waack merged

Methodenkopf:hybridsort()

Großschritt 1. [Erzeugen eines Feldes von Buckets.]Erzeuge ein Feld q[0, n) von leeren Warteschlangen.

Großschritt 2. [Verteilen der Schlussel auf die Buckets.]Fur i = 0, 1, . . . , n− 1 fuhre aus.

q [⌊nA[i]⌋] .add(A[i]

)

Großschritt 3 [Sortieren der Buckets durch vergleichsorientiertes Sortieren.]Fur j = 0, 1, . . . , n− 1 fuhre aus.

Sortiere q[j] mit Heapsort.Großschritt 4.[Ruckspeicherung auf A.]

Fur j = 0, 1, . . . , n− 1 fuhre aus.

Speichere q[j] auf A[∑j−1

i=0 λi,∑j

i=0 λi

)

unter Wahrung der Reihenfolge um,

wobei λi die Lange von q[i] ist.

Satz 8.96 1. Algorithmus 8.95 ist korrekt.

2. Im schlechtesten Fall hat Algorithmus 8.95 eine Laufzeit von O (n ln n).

3. Die erwartete Laufzeit von Algorithmus 8.95 auf eine zufallige Eingabe A der Langen ist O (n).

Die erwartete Anzahl der Schlusselvergleiche auf eine zufallige Eingabe der Lange nlaßt sich nach oben durch 2n− 1 abschatzen.

4. Mit Wahrscheinlichkeit großer oder gleich 1 − 1n2 ist die Laufzeit von Algorithmus

8.95 ein O (n ln ln n).

Beweis. Behauptung 1 ist eine unmittelbare Folgerung von (8.70).

Behauptung 2 ist klar: Im schlechtesten Fall fallen alle Eingaben in dasselbe Bucket.Behauptung 3. Da fur jedes i = 0, 1, . . . , n− 1 die Zufallsvariable A[i] auf [0, 1) gleich-

verteilt ist, gilt nach Definition fur jedes j = 0, 1, . . . , n− 1

P

(

A[i] ∈[

j

n,j + 1

n

))

=1

n.

Fur jedes j = 0, 1, . . . , n− 1 ist die Zufallsvariable

card

i

∣∣∣∣A[i] ∈

[j

n,j + 1

n

)

=:Lj

107

Page 106: Skript Waack merged

(n, 1

n

)-binomialverteilt, da alle Zufallsvariablen aus (8.69) auch unabhangig sind. Die Va-

riable Lj ist die zufallige Lange des j-ten Buckets. Es ist klar, daß sich die erwarteteLaufzeit fur eine zufallige Eingabe bis auf eine multiplikative Konstante nach oben durch

E

(n−1∑

j=0

Lj log2 Lj

)

≤n−1∑

j=0

E L2j = n · E L2

1

abschatzen laßt, wobei wegen 2n log2 n ≤ n2 fur alle naturlichen Zahlen n ≥ 1 die rechte Sei-te der vorstehenden Gleichung die erwartete Anzahl der Schlusselvergleiche in Großschritt3 nach oben abschatzt. Es genugt also, E L2

1 zu berechnen. Wir wissen, daß E L1 = 1 ist,und daß auf die Varianz von L1 einerseits Gleichung 3.30 und andererseits Gleichung 3.27anwendbar sind. Wir erhalten

VarL1 = E L21 − (E L1)

2 = 1− 1

n.

Es folgt

E L21 = 2− 1

n.

Damit haben wir auch bewiesen, daß die erwartete Anzahl der Schlusselvergleiche in Al-gorithmus 8.95 nach oben durch 2n− 1 abgeschatzt werden kann.

Zu Behauptung 4. Wir stellen fest, daß wir in der gleichen Situation sind wie beimBeweis von Satz 8.44. Uns interessiert die Lange des langsten Buckets nach Großschritt 2:

L := max Lj | j = 0, 1, . . . , n− 1 .

Nach Satz 8.44 wissen wir, daß

P (L > 3 · λ(n)) <1

n2

ist, wobei

λ(n) := minr | r! ≥ n ∼ ln n

ln ln n

ist. Wir wissen, daß wir in Großschritt 3 eine Laufzeit

T3 := O(

n−1∑

i=0

Li lnLi

)

haben, die uberdies die Laufzeit des restlichen Algorithmus majorisiert. Wir betrachtennun da Ereignis

E := L ≤ 3 · λ(n),

108

Page 107: Skript Waack merged

von dem wir wissen, daß es eine Wahrscheinlichkeit ≥ 1−1/n2 hat. Da die Funktion x ln x∪-konvex ist, steht, sofern E gegeben ist, der fur die Laufzeit schlimmste Fall ins Haus,wenn soviele Buckets wie nur moglich die Große 3 · λ(n) haben. Wir uberschatzen dieseZahl und damit die Laufzeit, wenn wir sie

b :=

⌈n

3 · λ(n)

= Θ

(n ln ln n

lnn

)

setzen. Wir erhalten

T3 = O(

b · ln n

ln lnn(ln ln n− ln ln ln n)

)

= O (b · ln n)

= O (n ln lnn) .

109

Page 108: Skript Waack merged

Literaturverzeichnis

[CLRS01] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein. Introduction toAlgorithms. MIT Press, 2001.

[MR95] R. Motwani and P. Raghavan. Randomized Algorithms. Cambridge UniversityPress, 1995.

110

Page 109: Skript Waack merged

Kapitel 9

Externes Suchen und Sortieren

Bisher galt, daß sich alle Datenstrukturen komplett im Hauptspeicher befunden haben.Fur manche Anwendungen trifft das nicht zu. Einerseits kann es erforderlich sein, daßdie Datenstrukturen dauerhaft sein sollen. Andererseits besteht die Moglichkeit, daß dievorhandenen Datenmengen einfach zu groß sind.

Als Hintergrundspeicher sind heute Magnetplatten gebrauchlich. Um unsere Strukturenund Algorithmen analysieren zu konnen, benotigen wir ein angemessenes Modell. Im Ar-beitsspeicher kostet die Verarbeitung von k Bytes k mal soviel wie die Verarbeitung einesBytes. Auf Plattenspeichern werden sogenannte Blocke mit einer typischen Große von 1

2

bis 8 K gemeinsam geschrieben oder gelesen, so daß man kaum sparen kann, wenn manbeispielsweise nur ein Byte lesen will. Aus der Sicht des Systems heißen die Blocke Seiten.Der Zeitbedarf fur einen Seitenzugriff ist relativ hoch. Die CPU kann in dieser Zeit in derRegel mehrere tausend Instruktionen ausfuhren. Deshalb legen wir folgendes fest:

– Bei der Analyse betrachten wir vor allem die Anzahl der Seitenzugriffe. Dazu ha-ben wir Operationen disk-read und disk-write. Die CPU-Zeit ist dagegen vongeringerer Bedeutung.

– Der Platzbedarf einer externen Speicherstruktur wird in der Anzahl der belegten Sei-

ten gemessen.

Die Ausnutzung der benutzten Seiten kann daruber hinaus von Interesse sein. Sie wirdgewohnlich in Prozent angeben und ist als

Anzahl der benutzten Bytes

Anzahl der benutzten Seiten · Anzahl der moglichen Bytes je Seite(9.1)

definiert.Eine externe Datenstruktur ist vollstandig im Hintergrundspeicher dargestellt; wir spre-

chen deshalb auch von einer Speicherstruktur. Fur die Verarbeitung einer Speicherstrukturmit Großenparameter n wird nur O (1) Platz im Arbeitsspeicher benotigt: Eine konstanteAnzahl von Seiten wird im Hauptspeicher gehalten und verarbeitet. Dann wird ruckgespei-chert und ggf. neue Seiten geladen.

111

Page 110: Skript Waack merged

Wir werden uns relativ kurz fassen. Wer zu diesem Thema mehr wissen will, der seiauf die gute Darstellung in [GD03] ab Seite 295 verwiesen, auf die wir uns auch stutzenwerden.

Wie ist die Situation? Rein mathematisch gesehen, gleicht sie der zu Beginn von Kapitel8 dargestellten: Wir haben n Schlussel aus einer total geordneten Menge. (Uber Satelliten-daten reden wir in diesem Kapitel nicht mehr.)

Die n Datensatze

k0, k1, . . . , kn−1 (9.2)

befinden sich im Hintergrundspeicher. Wir werden in diesem Kapitel Algorithmen undDatenstrukturen besprechen, die es uns ermoglichen, die Daten aus (9.2)

1. als Worterbuch (Spezifikation siehe Abschnitt 8.1) zu verwalten (siehe Abschnitt 9.1);

2. zu sortieren (siehe Abschnitt 9.2).

9.1 Externes Suchen: B-Baume

Die Datenstruktur, um die es uns im folgenden geht, sind Bayer-Baume, abgekurzt B-Baume, eine Datenstruktur im Hintergrundspeicher. Die Natur der Schlussel ist fur unsnicht interessant, weil sie algorithmisch ohne Bedeutung ist. Wir denken sie uns deshalbals ganze Zahlen. (Tatsachlich handelt es sich um Schlussel, die bei der Speicherverwaltungeine Bedeutung haben.) Ein Beispiel ist in Abbildung 9.1 dargestellt. Mit n bezeichnen wirdie Anzahl der in einem B-Baum gespeicherten Schlussel.

10

7

1

3

2 4 5 8 9

13

11 12 14 15 17 18

16

Abbildung 9.1: Beispiel eines B-Baums

Definition 9.1 Ein B-Baum T ist ein gerichteter geordneter Wurzelbaum mit den folgen-den Eigenschaften:

1. Jeder Knoten x von T hat als Attribute

– eine geordnete Folge von Schlusseln k1 < k2 < . . . < kb

112

Page 111: Skript Waack merged

– eine Folge Succ(1), Succ(2), . . ., Succ(b + 1) von Nachfolgerknoten, die entwe-der alle vorhanden oder aber – genau dann, wenn x ein Blatt ist – alle nichtvorhanden sind.

Die Zahl b ist abhangig von x. Abbildung 9.2 zeigt, wie man sich den Knoten xvorstellen kann.

. . . . . .k1 k2 kb

Succ(1) Succ(b) Succ(b + 1)Succ(3)Succ(2)

Abbildung 9.2: Knoten eines B-Baums mit b Schlusseln

2. Alle Blatter von T haben dieselbe Tiefe.

3. Es gibt eine naturliche Zahl t ≥ 2, den Verzweigungsfaktor oder Branching Factor,so daß fur die Anzahl der Schlussel b, die jeder Knoten x von T tragt, folgendes gilt.

(a) b ≤ 2t.

(b) Ist x von der Wurzel verschieden, so ist b ≥ t.

(c) Ist T vom leeren Baum verschieden, und ist x die Wurzel, so ist b ≥ 1.

4. Es gilt die folgende verallgemeinerte Suchbaumeigenschaft : Ist x ein beliebiger Knotenvon T , der b Schlussel k1 < k2 < . . . < kb tragt und kein Blatt ist, und sind κ1, κ2, . . .,κb+1 beliebige Schlussel der Nachfolgerknoten Succ(1), Succ(2), . . ., bzw. Succ(b+1),so ist

κ1 < k1 < κ2 < k2 < . . . < κb < kb < κb+1.

Bemerkungen.

• Die Knoten eines B-Baumes werden auch Seiten genannt. Damit wird angezeigt, daßsie jeweils nicht nur einen Schlussel, sondern eine Anzahl b von Schlusseln tragen,wobei b im Normalfall in dem Intervall [t, 2t] liegt. Warum geben wir keine festeZahl an? In Definition 9.1 fordern wir, daß jedes Blatt eines B-Baumes dieselbe Tiefehat. Diese Forderung ist mit der Festlegung, jeder Knoten solle gleichviele Schlusseltragen, unvertraglich.

• Der Verzweigungsfaktor ist so bemessen, daß der Speicherplatzbedarf eines Knotensdie zu Beginn dieses Kapitels beschriebene Seitengroße nicht uberschreitet.

• Fur die Algorithmen dieses Abschnitts vereinbaren wir folgendes:

113

Page 112: Skript Waack merged

1. Das Original jeder Seite befindet sich im Hintergrundspeicher. Die Wurzel istaber stets

”geladen“. Wir legen fest, daß jeder Zugriff auf eine Seite zunachst

mit einem disk-read und nach erfolgter Modifikation mit einem disk-write

verbunden ist. Diese klare Regelung ermoglicht es, die Seitenzugriffsbefehle inunserem Pseudocode zu unterdrucken.

Stets werden nur konstant viele Knoten gleichzeitig einer Veranderung unter-worfen. Versionen dieser Knoten befinden sich im Hauptspeicher. Diese Arbeits-

versionen heißen interne Knoten. Alle anderen Knoten nennen wir auch extern.

2. Bei der Analyse werten wir sowohl die CPU- als auch die Plattenzugriffszeit aus.Der Verzweigungsfaktor t – man mag an t ≥ 50 denken – wird dabei nicht inder O-Notation verborgen.

3. Wir betrachten keine Garbage-Kollektion.

• Ist x ein interner Knoten, ist x also gerade einem Veranderungsprozeß unterworfen,so konnen die Bedingungen aus Definition 9.1 uber die Anzahl b der von x gehaltenenKnoten vorubergehend verletzt sein:

b ∈

[t− 1, 2t + 1] falls x verschieden von der Wurzel ist;

[0, 2t + 1] falls x gleich der Wurzel ist.

Ein interner Knoten x von T , der von der Wurzel verschieden ist, heißt unterfullt

(uberfullt), wenn b = t − 1 (b = 2t + 1) ist. Die Wurzel kann uberfullt aber nicht

unterfullt sein.

• Knoten konnen wir uns als Instanzen einer Klasse BNode implementiert denken.Hauptdatenfelder sind

– ein Feld

key :

Array[1, 2t] of Key falls der Knoten extern ist;

Array[0, 2t + 2] of Key falls der Knoten intern ist;

wobei in unserer Darstellung aus technischen Grunden – Randbedingungen ver-einfachen sich – fur interne Knoten stets key(0) = −∞ und key(2t + 2) = +∞gilt;

– eine ganzzahlige Variable used, welche die Anzahl der Schlussel halt, die in demKnoten gespeichert sind;

– ein Feld

succ :

Array[1, 2t + 1] of BNode falls der Knoten extern ist;

Array[1, 2t + 2] of BNode falls der Knoten intern ist;

– eine Variable father of BNode.

114

Page 113: Skript Waack merged

Wir wollen annehmen, daß wenn used = b ist, so ist key(b+1) = . . . = key(2t+2) =+∞.

Da interne und externe Knoten eine geringfugig abweichende Darstellung haben,muß jeder Plattenzugriff von einem (sehr einfachen) Konversionalgorithmus flankiertwerden, der O (t) CPU-Zeit erfordert.

• Die Datenfelder key und succ sind von expandiertem Typ. Das soll heißen, sie ent-halten nicht nur die Referenz auf das entsprechende Feld, sondern vielmehr das Feldselbst.

• Fur ein internes BNode-Objekt x gilt:

– x ist genau dann die Wurzel, wenn x.father = ↑ ist.

– x ist genau dann ein Blatt, wenn succ(1) = . . . = succ(2t + 2) = ↑ ist.

• Fur externe Knoten kann man analoge Bedingungen wie die vorstehenden formulie-ren. Aber sie sind fur uns uninteressant, da unsere Algorithmen definitionsgemaß nurauf interne Knoten als Aktualparameter zugreifen.

• B-Baume insgesamt denken wir uns als Instanzen einer Klasse BTree mit dem Haupt-datenfeld root vom Typ BNode und allen Algorithmen, die in diesem Abschnitt be-sprochen werden.

Der Zustand eines B-Baumes zwischen zwei Aufrufen offentlicher Methoden heißtstabil. In einem stabilen Zustand sind alle Bedingungen aus Definition 9.1 erfullt.

Wie steht es um die Tiefe eines B-Baumes T mit Verzweigungsfaktor t, der n Schlusseltragt?

Satz 9.2 Es ist

log2t+1(n + 1)− 1 ≤ depth(T ) ≤ logt+1

(n + 1

2

)

.

Beweis. Sei d die Tiefe des in Rede stehenden B-Baumes.Ein Suchbaum Td,min mit der Tiefe d mit minimal vielen Schlusseln sieht so aus.

1 Schlussel

t Schlussel t Schlussel

· . . . (t + 1) . . . · · . . . (t + 1) . . . ·

. . . . . . . . . . . . . . . . . . . . . . . . . . .

t Schlussel t Schlussel

. . . t Schlussel . . . (t + 1) . . . t Schlussel t Schlussel . . . (t + 1) . . . t Schlussel . . .

115

Page 114: Skript Waack merged

Aus der vorstehenden Abbildung erkennen wir leicht, daß im linken und im rechten Teil-baum von Td,min jeweils

t ·

(d−1∑

i=0

(t + 1)i

)

= t ·(t + 1)d − 1

t= (t + 1)d − 1

Schlussel gespeichert sind. Folglich enthalt Td,min insgesamt 2(t + 1)d− 1 Schlussel. Wegender Minimalitat von Td,min folgt

2(t + 1)d − 1 ≤ n,

woraus wir

d ≤ logt+1

n + 1

2

erhalten.

Ein Suchbaum Td,max mit der Tiefe d mit maximal vielen Schlusseln sieht so aus.

2t Schlussel

2t Schlussel . . . (2t + 1) . . . 2t Schlussel

· . . . (2t + 1) . . . · · . . . (2t + 1) . . . ·

. . . . . . . . . . . . . . . . . . . . . . . . . . .

2t Schlussel 2t Schlussel

. . . 2t Schlussel . . . (2t + 1) . . . 2t Schlussel 2t Schlussel . . . (2t + 1) . . . 2t Schlussel . . .

Die vorstehende Abbildung macht deutlich, daß in Td,max

2t ·

(d∑

i=0

(2t + 1)i

)

= 2t ·(2t + 1)d+1 − 1

2t= (2t + 1)d+1 − 1

Schlussel gespeichert sind. Wegen der Maximalitat von Td,max folgt

n ≤ (2t + 1)d+1 − 1,

woraus wir

log2t+1(n + 1)− 1 ≤ d

erhalten.

116

Page 115: Skript Waack merged

Korollar 9.3 Es ist

depth(T ) = Θ (logt n) .

Viele Begriffe und Aussagen uber binare Suchbaume aus dem Abschnitt 8.2 konnen sehrleicht auf B-Baume ubertragen werden. Mehr noch, die Verhaltnisse sind bei B-Baumeneinfacher, da jeder Knoten eines B-Baumes, der b Schlussel halt, entweder b+1 oder keinenNachfolger hat. Der Beweis des folgenden Lemmas ist deshalb eine leichte Ubungsaufgabe.

Lemma 9.4 Sei T ein B-Baum und v ein innerer Knoten von T . Ist k ein Schlussel auf

v, so liegt der unmittelbare Vorganger und der unmittelbare Nachfolger von k auf einem

Blatt.

Besonders einfach ist die Ubertragung des Begriffes des Suchpfades aus Definition 8.17.Es ist offensichtlich, daß der Endknoten des Suchpfades nach jedem Schlussel, der nicht zudem aktuellen B-Baum gehort, ein Blatt ist. Der folgende Algorithmus ist dem Algorithmus8.19 aus dem Abschnitt 8.2.5 sehr ahnlich.

Algorithmus 9.5 (Berechnung des Blattes eines Suchpfades)

Methodenkopf:searchPath

(Key k, BNode v

)returns BNode

Vorbedingung:Der ubergebene Knoten v gehort zum aktuellen B-Baum T .

Nachbedingung:Ruckgabe des Endknotens des Suchpfades nach k in Tv.

Großschritt 1. [Basis]Berechne den eindeutig bestimmten Index i mitv.key(i) ≤ k < v.key(i + 1).

Fuhrereturn v

aus, falls eine der folgenden zwei Bedingungen erfullt ist:- v.key(i) = k

- v.key(i) 6= k und v ist Blatt.Großschritt 2. [Rekursion]return searchPath

(k, v.succ(i + 1)

)

Wie alle Laufzeitanalysen dieses Abschnitts, ist der Beweis des folgenden Lemmas aufder Grundlage von Korollar 9.3 eine leichte Ubungsaufgabe.

Lemma 9.6 Algorithmus 9.5 hat O (logt n) Plattenzugriffs- und O (t · logt n) CPU-Zeit.

117

Page 116: Skript Waack merged

Der folgende Algorithmus ist eine nichtoffentliche Methode, die auf B-Baume Anwen-dung findet, die sich durch Einfugen eines Schlussels in einen Knoten vorubergehend nichtmehr in einem stabilen Zustand befinden.

Algorithmus 9.7 (Hilfsalgorithmus zum Aufspalten eines Knotens)

Methodenkopf:split

(BNode v

)

Vorbedingung:Der ubergebene Knoten v des aktuellen B-Baumes T ist als einziger uberfullt.

Nachbedingung:Kein Knoten des aktuellen B-Baums T ist mehr uberfullt.

Großschritt 1. [Basis]Falls v die Wurzel ist, so

verfahre gemaß Abbildung 9.3.return

Großschritt 2. [Rekursion]Verfahre gemaß Abbildung 9.4.Falls der Vater von Knoten v nun uberfullt ist, fuhresplit(v.father())

aus.

Wir bemerken, daß sowohl in Abbildung 9.3 als auch in Abbildung 9.4 die beidenKnoten, die durch Aufspaltung neu entstehen, genau t Schlussel enthalten.

Lemma 9.8 Algorithmus 9.7 hat O (logt n) Plattenzugriffs- und O (t · logt n) CPU-Zeit.

Mit Hilfe von Algorithmus 9.7 ist die Einfuge-Operation leicht ins Werk zu setzen.

Algorithmus 9.9 (Algorithmus zum Einfugen eines Schlussels)

Methodenkopf:insert

(Key k

)

Großschritt 1.Falls die gespeicherte Menge leer ist, so fuhre aus.

Speichere Schlussel k als einzigen Schlussel in der Wurzel.Fuhre return aus.

Großschritt 2.v← searchPath(k, root).Falls v den Schlussel k tragt, so fuhre return aus.

Großschritt 3.Fuge den Schlussel k an der richtigen Stelle der Schlusselfeldes des Knotens v ein.Falls v nun uberfullt ist, so fuhre split(v) aus.

118

Page 117: Skript Waack merged

. . .kt+2

kt+1

k1 . . . kt k2t+1

. . .k1 . . .kt+1kt k2t+1kt+2

R1 R2 R4

R1 R4

R3

R3R2

Abbildung 9.3: Aufspalten eines uberfullten Knotens:”Geburt“ einer neuen Wurzel

Satz 9.10 Algorithmus 9.9 hat O (logt n) Plattenzugriffs- und O (t · logt n) CPU-Zeit.

Der Algorithmus des Streichens ist zu dem des Einfugens dual. Zunachst entwerfenwir eine nichtoffentliche Methode, die Anwendung findet, wenn sich durch Streichen ei-nes Schlussels der aktuelle B-Baum vorubergehend nicht mehr in einem stabilen Zustandbefindet, weil ein Knoten u nunmehr unterfullt ist.

Da ein B-Baum geordnet ist, kann man fur jeden Knoten von einem rechten oderlinken Nachbarn sprechen. Diese konnen auch fehlen. Ein unterfullter Knoten hat stetseinen Nachbarn, denn er ist definitionsgemaß verschieden von der Wurzel.

Ein Nachbar des unterfullten Knotens u heißt reich, wenn er mehr als t Schlussel halt.Ein solcher Nachbar kann einen Schlussel abgeben. Ein Nachbar heißt arm, wenn er genaut Schlussel halt. Ein solcher Nachbar kann nichts abgeben. Das Wenige, was er hat, brauchter fur sich.

In dem nun folgenden Algorithmus wird zunachst gepruft, ob u einen reichen Nachbarnhat. Wenn ja, so wird einer ausgewahlt, der einen Schlussel gemaß Abbildung 9.5 an uabgibt. Das geht nur deshalb so einfach, weil die Schlusselliste, die ein Knoten halt, geordnetist.

Hat der unterfullte Knoten nur arme Nachbarn, fusioniert er mit einem von ihnen gemaßAbbildung 9.6 zu einem neuen Knoten. Dabei bedienen sich beide aus der Substanz ihresgemeinsamen Vaters mit einem Schlussel. Der so entstandene neue Knoten halt genau 2t

119

Page 118: Skript Waack merged

λ

κλ

κ

. . .kt+2

kt+1

k1 . . . kt k2t+1

. . .k1 . . .kt+1kt k2t+1kt+2

R1 R2 R4

R1 R4

R3

R3R2

Abbildung 9.4: Aufspalten eines uberfullten Knoten: Vergroßerung des Vaters

Schlussel. Nun kann es sein, daß der Vater unterfullt ist, sofern er uberhaupt uberlebthat. War der Vater (vorher) die Wurzel, sind wir fertig, da die Wurzel unterfullt sein darf.Anderfalls kommt es zu einem rekursiven Aufruf mit dem Vater als Aktualparameter.

Algorithmus 9.11 (Hilfsalgorithmus zum Zusammenlegen von Knoten)

Methodenkopf:contract

(BNode v

)

Vorbedingung:Der ubergebene Knoten v von T ist als einziger unterfullt.(Erinnerung: Der Knoten v ist dann verschieden von der Wurzel.)

Nachbedingung:Kein Knoten des aktuellen B-Baums T ist mehr unterfullt.

Großschritt 1. [Basis]

120

Page 119: Skript Waack merged

Falls v einen reichen Nachbarn v′ hat, soverfahre gemaß Abbildung 9.5 und fuhre dann return aus.

Falls v die Wurzel als Vater hat, soverfahre gemaß Abbildung 9.6 und fuhre dann return aus.

Großschritt 2. [Rekursion]Verfahre gemaß Abbildung 9.6.Falls der Vater von Knoten v nun unterfullt ist, fuhrecontract(v.father())

aus.

. . . . . .k

. . .ℓk′′. . . . . . k′

. . . k′ k . . . . . .ℓ

R2 R3 R4

R1 R2 R3

. . . . . .k′′

R4

R1

Vater von v

Unterfullter Knoten v”Reicher“ Nachbar v′ von v

Abbildung 9.5:”Nachbarschaftlicher Vermogensausgleich“

Lemma 9.12 Algorithmus 9.11 hat O (logt n) Plattenzugriffs- und O (t · logt n) CPU-Zeit.

Mit Hilfe von Algorithmus 9.11 ist das Streichen leicht moglich. Es ist einfacher alsim Falle von Suchbaumen: Der Fall des Großschritts 3 aus Algorithmus 8.25 kann nichtauftreten.

121

Page 120: Skript Waack merged

. . . . . .k

. . . . . . k′

. . . . . .

R2 R3 R4

k′′ . . . . . .

. . . . . .kk′ k′′. . .. . .

R1

R1 R2 R3 R4

Unterfullter Knoten v

Vater von v

”Armer“ Nachbar von v

Abbildung 9.6: Der”Staubsaugereffekt“

Der Fall, daß der zu streichende Schlussel auf einem Blatt liegt, ist kanonisch zu behan-deln. Schlussel k wird aus der Schlusselliste des Blattes gestrichen und Algorithmus 9.11mit diesem Blatt als Aktualparameter aufgerufen.

Liegt der zu streichende Schlussel auf einem Knoten u, der nicht Blatt ist, so verfahrtman wegen Lemma 9.4 analog zu Großschritt 4 aus Algorithmus 8.25. Man ermittelt dasBlatt u′, auf dem der Vorganger k′ von Schlussel k liegt, vertauscht k und k′ mit einanderund loscht schließlich k auf dem Blatt v′ wie oben beschrieben.

Algorithmus 9.13 (Algorithmus zum Streichen eines Schlussels)

Methodenkopf:delete

(Key k

)

Großschritt 1.Falls die gespeicherte Menge leer ist, so fuhre return aus.

122

Page 121: Skript Waack merged

u← searchPath(k, root).Falls u den Schlussel k nicht tragt, so fuhre return aus.

Großschritt 2 [u ist kein Blatt].Falls u kein Blatt ist, so fuhre aus.

Berechne das Blatt u′, das den Vorganger k′ von k tragt.Tausche die Positionen der Schlussel k und k′.u← u′

Großschritt 3 [u ist Blatt].Streiche den Schlussel k aus dem Schlusselfeld des Knotens u.Falls u nun unterfullt ist, so fuhre contract(u) aus.

Satz 9.14 Algorithmus 9.13 hat O (logt n) Plattenzugriffs- und O (t · logt n) CPU-Zeit.

Zum Abschluß betrachten wir als Beispiel fur Algorithmus 9.13 den B-Baum aus Abbil-dung 9.1, aus dem wir den Schlussel 7 streichen wollen. (Der Verzweigungsfaktor sei t = 2.Jeder Knoten, der von der Wurzel verschieden ist, darf zwischen 2 und 4 Schlussel halten.)

Zunachst tauscht der Schlussel 7 mit seinem Vorganger, dem Schlussel 5, die Platze. An-schließend wird Schlussel 7 aus dem Blatt, auf dem er sich nunmehr befindet, entfernt. DasErgebnis ist in Abbildung 9.7 dargestellt: Das Blatt ist nach dem Streichen des Schlussels7 unterfullt. Ein typischer Fall fur die Methode contract mit diesem Blatt als Aktualpa-rameter. Da beide Nachbarn arm sind, fusioniert dieses Blatt (naturlich unter Gleichen)mit seinem rechten Nachbarn, nicht ohne vorher den gemeinsamen Vater zur Kasse gebe-ten zu haben (siehe Abbildung 9.8). Dieser wiederum ist nunmehr unterfullt und muß sichseinerseits mit seinem einzigen, armen Nachbarn zusammentun. Ihr gemeinsamer Vater istdie Wurzel, die dabei aufgesogen wird, wie aus Abbildung 9.9 ersichtlich ist.

10

1

3

2 8 9

13

11 12 14 15 17 18

165

4

unterfullt

Abbildung 9.7: Das Blatt, das Schlussel 4 tragt, ist unterfullt.

123

Page 122: Skript Waack merged

10

1 2

13

11 12 14 15 17 18

16

4

3

5 8 9

unterfullt

Abbildung 9.8: Der Knoten, der Schlussel 3 tragt, ist unterfullt.

10 13 163

1 2 11 12 14 15 17 184 5 8 9

Abbildung 9.9: Die Wurzel aus Abbildung 9.8 wurde”aufgesaugt“.

9.2 Externes Sortieren: Mergesort

Das zweite zentrale Problem der Behandlung großer Datensatze ist das Sortieren. Dazustehen die Daten aus (9.2) in einer vom Betriebssystem verwalteten Datei, deren Darstel-lung auf Magnetspeicherplatten wir uns als Seitenfolge vorstellen wollen. Bequem, wie wirsind, nehmen wir an, daß jede Seite (eventuell bis auf die letzte) genau b Schlussel enthalt:

k0, k1, . . . , kb−1︸ ︷︷ ︸

Seite 0

kb, kb+1, . . . , k2b−1︸ ︷︷ ︸

Seite 1

. . . k(k−1)b, k(k−1)b+1, . . . , kn−1︸ ︷︷ ︸

Seite k − 1

(9.3)

Von zentraler Bedeutung fur die Analyse der Anzahl der Plattenzugriffe in diesemAbschnitt sind die folgenden Bemerkungen.

Bemerkungen.

• Wollen wir alle Daten lesen, so kann das mit k =⌈

nb

⌉Seitenzugriffen geschehen, wenn

wir die kanonische Reihenfolge aus (9.3) einhalten.

• Man braucht kein Genie zu sein, um sich vorstellen zu konnen, daß man bei einemZugriff in einer Reihenfolge, die stark von der in (9.3) gegebenen abweicht, n Zugriffe

124

Page 123: Skript Waack merged

benotigt, denn der Platz, den man im Arbeitsspeicher benutzen darf, ist ja durcheine konstante Anzahl von Seiten beschrankt.

Da die Zahl b in der Regel großer oder gleich 50 ist, und Seitenzugriffe teuer sind,brauchen wir ein Sortierverfahren, das die Anordnung der Schlussel der verwendeten Da-teien einhalt. Letzteres wird zur unabweislichen Notwendigkeit, wenn Magnetbander zumEinsatz kommen: Hier ist der Zeitaufwand extrem hoch, einen Schlussel außerhalb derSpeicherreihenfolge zu lesen. Der Algorithmus unserer Wahl ist die iterative Variante desin Abschnitt 8.4.5 dargestellten Mergesort. Wir machen uns den Algorithmus zunachstanhand eines Beispiels klar. Wir verwenden vier Dateien f1, f2, g1 und g2. Am Anfangbefinden sich alle Schlussel in der Datei g1.

g1 :48|99|30|15|9|72|38|2|79|61|69|12|16

g2 :∅

f1 :∅

f2 :∅

Wahrend des Preprocessings, der Methode initialRuns(g1, f1, f2) mit der Vorbedingungg2 = f1 = f2 = ∅, werden die Schlussel von g1 auf f1 und f2 in kanonischer Weise abwech-selnd verteilt:

g1 :∅

g2 :∅

f1 :48|30|9|38|79|69|16

f2 :99|15|72|2|61|12

Das Symbol”|“ ist das Trennzeichen fur die sogenannte Laufe oder Runs. Ein Lauf ist eine

aufsteigend sortierte Teilfolge.

In der nun folgenden Mischphase ist die Situation wie folgt. Die zu sortierende Folgebefindet sich, aufgeteilt in Laufe, gleichmaßig verteilt entweder auf f1 und f2 oder aber aufg1 und g2. Wir nehmen an, daß das erstere der Fall ist. Dann werden die Laufe von f1 undf2 von links nach rechts paarweise, wie in Algorithmus 8.88 dargestellt, gemischt und dieneuen langeren Runs abwechselnd auf g1 und g2 gespeichert.

Mischphase 1.

g1 :48, 99|9, 72|61, 79|16

g2 :15, 30|2, 38|12, 69|

f1 :∅

f2 :∅

125

Page 124: Skript Waack merged

Mischphase 2.

g1 :∅

g2 :∅

f1 :15, 30, 48, 99|12, 61, 69, 79|

f2 :2, 9, 38, 72|16

Mischphase 3.

g1 :2, 9, 15, 30, 38, 48, 72, 99|

g2 :12, 16, 61, 69, 79|

f1 :∅

f2 :∅

Mischphase 4.

g1 :∅

g2 :∅

f1 :2, 9, 12, 15, 16, 30, 38, 48, 61, 69, 72, 79, 99|

f2 :∅

Wir wenden uns dem allgemeinen Fall zu. Wir brauchen fur unsere Rahmenklasse vierHauptdatenfelder f1, f2, g1, g2 vom Typ

”Datei“. Hinzu kommt ein Datenfeld runs vom

Typ Integer. Die Eingabe erfolgt auf g1, die Ausgabe auf f1 oder g1. Das Datenfeld runs

halt (zwischen den Mischphasen) die Anzahl der Laufe in allen Dateien.

Algorithmus 9.15 (Initialisierung)

Methodenkopf:InitialRuns(Datei k, ℓ1, ℓ2)

Vorbedingungen:1.) Die aus n Schlusseln bestehende Eingabe befindet sich in der Datei k.2.) Alle anderen Dateien sind leer.

Nachbedingungen:1.) In ℓ1 sind ⌈n/2⌉ viele Laufe der Lange eins.2.) In ℓ2 sind ⌊n/2⌋ viele Laufe der Lange eins.3.) Alle anderen Dateien sind leer.4.) runs = n.

Rumpf:runs← Anzahl der Schlussel in g1

Verteile die Schlussel aus k abwechselnd zu Laufen der Lange eins auf ℓ1 und ℓ2.

126

Page 125: Skript Waack merged

Aufgrund der zu Eingang dieses Abschnittes gemachten Bemerkung beobachten wir,daß die Anzahl der Plattenzugriffe von Algorithmus 9.15 ein O (n/b) ist. Das trifft ausdemselben Grund auch fur den folgenden Algorithmus 9.16 zu.

Algorithmus 9.16 (Mischen)

Methodenkopf:merge(Datei k1, k2, l1, l2)

Vorbedingungen:1.) runs > 12.) In k1 und k2 befindet sich eine Schlusselmenge S in runs vielen Laufen.3.) In k1 sind ⌈runs/2⌉ viele Laufe.4.) In k2 sind ⌊runs/2⌋ viele Laufe.5.) Die Dateien l1 und l2 sind leer.

Nachbedingungen:1.) In l1 und l2 befindet sich dieselbe Menge S in r := ⌈runs/2⌉ vielen Laufen.2.) In l1 sind ⌈r/2⌉ viele Laufe.3.) In l2 sind ⌊r/2⌋ viele Laufe.4.) Die Dateien k1 und k2 sind leer.

Rumpf:Mische die Laufe aus k1 und k2 paarweise von links nach rechts,

und speichere sie abwechseln in l1 und l2 mit l1 beginnend ab.runs← ⌈runs/2⌉

Nun sind wir auf das externe Mergesort vorbereitet.

Algorithmus 9.17 (Externes Mergesort)

Methodenkopf:externalMergesort()

Vorbedingung:1.) Die aus n Schlusseln bestehende Eingabe befindet sich in der Datei g1.2.) Alle anderen Dateien sind leer.

Nachbedingungen:Die Datei f1 oder die Datei g1 enthalt die sortierte Folge.

Rumpf:Großschritt 1.

Fuhre InitialRuns(g1, f1, f2) aus.even← true.

Großschritt 2.Fuhre aus

Falls even, so fuhre merge(f1, f2, g1, g2) aus.Andernfalls fuhre merge(g1, g2, f1, f2) aus.

127

Page 126: Skript Waack merged

even← ¬(even)bis daß runs = 1.

Wir kommen zur Analyse von Algorithmus 9.17. Dazu nennen wir jeden Durchlauf derFuhre-aus-bis-daß-Schleife eine Phase. Wir erinnern uns, daß wir b Schlussel je Seite haben.Wegen der Halbierung des Datenfeldes runs je Phase gibt es ⌈log2 n⌉ Phasen. In jeder Phasewird jeder Datensatz genau einmal gelesen, und folglich gibt es O (n/b) Seitenzugriffe.Die Anzahl der Seitenzugriffe insgesamt ist ein O (n/b · log2 n). Die CPU-Zeit ist, wie beiAlgorithmus 8.90, um dessen iterative Variante es sich handelt, ein O (n log2 n).

128

Page 127: Skript Waack merged

Literaturverzeichnis

[GD03] R. H. Guting and St. Dieker. Datenstrukturen und Algorithmen. Leitfaden derInformatik. Teubner Verlag, Stuttgart, Leipzip, Wiesbaden, 2003.

129

Page 128: Skript Waack merged

Kapitel 10

Grundlegende Algorithmen furungerichtete Graphen

Dieses Kapitel setzt den Inhalt des Abschnitts 1.5 des Kapitels 1 voraus. Als erganzendeLekture ist [CLRS01] besonders gut geeignet. Die Darstellung der MST-Algorithmen folgt[Tar83].

10.1 Datenstrukturen fur Graphen

Adjazenzmatrizen. Fur einen Graphen G = (V, E) mit n Knoten gehen wir davon aus,daß die Knoten von 0 bis n− 1 durchnumeriert sind. Anders ausgedruckt, denken wir dieKnoten als Folge v0, v1, . . . , vn−1 aufgelistet. (Betrachten wir beispielsweise den Graphenaus Abbildung 1.1, so ist die naturliche Numerierung die folgende: v0 = A, v1 = B,. . ., v6 = G.) Nun ordnen wir G die folgende n × n Matrix A(G) zu: Der Eintrag vonA(G) in der i-ten Zeile und der j-ten Spalte ist genau dann 1, wenn (vi, vj) eine Kantein G ist. Andernfalls ist der Eintrag 0. Da wir ungerichtete Graphen betrachten, ist dieAdjazenzmatrix symmetrisch.

Der Graph aus Abbildung 1.1 hat dann die Adjazenzmatrix

0 1 1 0 0 1 11 0 0 0 0 0 01 0 0 0 0 0 00 0 0 0 1 1 00 0 0 1 0 1 11 0 0 1 1 0 01 0 0 0 1 0 0

Adjazenzmatrizen sind fur dicke Graphen (d.h. mit Ω(n2) vielen Kanten), bei denen sichdie Menge der Knoten uber die gesamte Anwendung nicht verandert, besonders speicher-und zeiteffizient.

131

Page 129: Skript Waack merged

Adjazenzlisten. Hier wird fur jeden Knoten vi des Graphen eine Liste vi : vj1, . . . , vjki

seiner Nachfolger gehalten.

Die Adjazenzlisten des Graphen aus Abbildung 1.1 sehen so aus:

X Liste der Nachbarn von XA F, C, B, GB AC AD E, FE F, G, DF A, D, EG A, E

Adjazenzlisten bieten sich bei dunnen Graphen – Graphen mit relativ wenigen Kanten– an, oder bei Graphen, bei denen die Knotenmenge wahrend der Anwendung variabel ist.

Kantenlisten sind eine Erweiterung von Adjazenzlisten. Man halt fur jeden Knoten desGraphen die Liste der zu ihm inzidenten Kanten. Man wird Kantenlisten einsetzen, wenndie Bedingungen fur den Einsatz von Adjazenzlisten gegeben sind, und man Kantenobjektebraucht, um die Algorithmen transparent entwerfen und implementieren zu konnen.

Die Kantenlisten des Graphen aus Abbildung 1.1 sehen so aus:

X Liste der zu X inzidenten KantenA (A,F), (A,C), (A,B), (A,G)B (B,A)C (C,A)D (D,E), (D,F)E (E,D), (E,F), (E,G)F (F,A), (F,D), (F,E)G (G,A), (G,E)

Wir entscheiden uns fur Kantenlisten. Jeder Knoten und jede Kante bekommt ihr ei-genes Objekt. Das ist fur uns bequem, da wir unsere Algorithmen sowohl Knoten als auchKanten markieren lassen werden.

Wenden wir uns zuerst unserer Kantenklasse Edge zu. Die Schlusselinformation fur ei-ne Kante ist fur uns die Zweimenge ihrer Endknoten. (Das heißt, zwei Kantenobjekte sindgenau dann gleich, wenn ihre Endknotenmengen gleich sind. Dies findet seine Rechtferti-gung darin, daß wir im Abschnitt Abschnitt 1.5 Mehrfachkanten ausgeschlossen haben.)Fur diese sind zwei Datenfelder vorgesehen.

Die Knotenklasse Vertex hat als Hauptdatenfeld die Liste edges der zu dem aktuellenKnoten inzidenten Kantenobjekte.

Die Graphen selbst sind Inkarnationen einer Klasse UGraph, deren Hauptdatenfeld dieListe vertices der zu dem Graphen gehorigen Knoten ist.

132

Page 130: Skript Waack merged

10.2 Berechnung eines aufspannenden Baumes fur un-

gerichtete Graphen

Um Kanten danach klassifizieren zu konnen, ob sie zu dem aufzubauenden aufspannendenWald gehoren, gibt es ein Datenfeld classification, das die Werte unclassifiedEdge,treeEdge und otherEdge enthalten kann.

Die Algorithmen dieses Abschnitts verwenden eine Warteschlange oder einen Stapelvon Knoten. Jeder Knoten muß da genau einmal durch. Um einem Knoten diesen Statussofort ansehen zu konnen, hat die Klasse Vertex ein Datenfeld color, das die Werte white,grey und black annehmen kann: Die Farbe white bedeutet, daß der Knoten noch nichtin der Warteschlange bzw. auf dem Stapel war. Die Farbe grey zeigt an, daß der Knotengerade dort ist. Die Farbe black schließlich verkundet, er wurde bereits von dort entfernt.

Daruber hinaus ist ein Datenfeld n components mit Werten in den naturlichen Zahlenhilfreich, das nach Abschluß unserer Algorithmen die Anzahl der Zusammenhangskompo-nenten des aktuellen Graphen halt.

Wir beginnen mit den Hilfsalgorithmen Breitensuche (engl. breadth–first search, ab-gekurzt bfs) und Tiefensuche (engl. depth–first search, abgekurzt dfs), denen jeweils einsogenannter Wurzelknoten v0, an dem die Suche beginnt, ubergeben wird. Deren Spezifi-kation sieht so aus:

Vorbedingung: (i) Der ubergebene Knoten v0 gehort zur Knotenmenge V des aktuellenGraphobjekts G = (V, E).(ii) Das aktuelle Graphobjekt G = (V, E) ist zusammenhangend.(iii) Alle Knoten von G haben die Farbe white, alle Kanten tragen das Klassifizie-rungsmerkmal unclassifiedEdge.

Nachbedingung: (i) Alle Knoten von G tragen die Farbe black.(ii) Alle Kanten von G sind entweder als treeEdge oder als otherEdge klassifiziert.(iii) Der Teilgraph T = (V, e ∈ E | e ist treeEdge) ist ein aufspannender Baumvon G.

Wir beginnen mit dem Algorithmus bfs(v0).

Algorithmus 10.1 (Breitensuche von einem Knoten aus)

Methodenkopf:bfs(Vertex v0)

Rumpf:Großschritt 1.

Erzeuge eine (leere) Warteschlange x fur Knoten.Großschritt 2. [Beruhre die Wurzel]

2.1. Farbe die Wurzel v0 mit der Farbe grey ein.2.2. Fuge v0 in die Warteschlange x ein.

133

Page 131: Skript Waack merged

Großschritt 3. [Besuch beim Spitzenknoten der Warteschlange]Fuhre aus

3.1.[Beginne den Besuch]Binde das Spitzenelement von x an Variable v.Entferne das Spitzenelement aus der Warteschlange.

3.2.[Beruhre alle noch unberuhrten Nachbarn des Knotens v]Fur alle zu v inzidenten, bisher unklassifizierten Kanten e fuhre aus:

Binde den von v verschiedenen Endknoten von e an u.Falls die Farbe von u white ist, so fuhre aus:

Versehe e mit der Klassifikation treeEdge.Beruhre u: Farbe u grey und fuge ihn in die Schlange x ein.

Andernfalls klassifiziere e als otherEdge.3.3.[Beende den Besuch]

Farbe v mit der Farbe black.solange die Warteschlange x nicht leer ist.

Machen wir uns zunachst anhand des Graphen aus Abbildung 1.1 klar, wie der Al-gorithmus arbeitet. Ist der dort dargestellte Graph das aktuelle Objekt und wird diesesgebeten, bfs(A) auszufuhren, so hangt das Ergebnis sicherlich von der Reihenfolge ab, inder die zu dem jeweiligen Spitzenknoten inzidenten Kanten aufgezahlt werden. Wir wol-len annehmen, daß die zu einem Knoten inzidenten Kanten in lexikografischer Ordnungbezuglich des Schlussels des

”anderen“ Knotens der Kante aufgezahlt werden:

v Liste der zu v inzidenten Kanten e

A (A,B), (A,C), (A,F), (A,G)B (B,A)C (C,A)D (D,E), (D,F)E (E,D), (E,F), (E,G)F (F,A), (F,D), (F,E)G (G,A), (G,E)

(In der Terminologie des Algorithmus variieren die Kanten der Tabelle wie das Varia-blenpaar (v,u).)

Wir notieren nun fur jedes i von 1 bis 7 – gilt es doch 7 Knoten zu besuchen – denInhalt der Warteschlange vor dem i–ten Durchlauf der Schleife als Folge von Knoten, wobeilinks stets das im i–ten Durchlauf zu besuchende Spitzenelement steht. Zusatzlich schrei-ben wir uns auf, welche Kanten im i–ten Durchlauf das Pradikat treeEdge und welche dasPradikat otherEdge bekommen. Die folgende Tabelle leistet das Gewunschte:

134

Page 132: Skript Waack merged

Durchlauf Inhalt von x neue treeEdge–Kanten neue otherEdge–Kanten1 A (A,B), (A,C), (A,F), (A,G) keine2 B, C, F, G keine keine3 C,F,G keine keine4 F,G (F,D), (F,E) keine5 G,D,E keine (G,E)6 D,E keine (D,E)7 E keine keine

Im Ergebnis unserer Rechnung sind die Kanten des Graphen wie in Abbildung 10.1angegeben klassifiziert.

A

treeEdge

F C B G

E D

treeEdge treeEdge treeEdge treeEdge

otherEdge

treeEdge

otherEdge

Abbildung 10.1: Ein Beispiel zur Breitensuche

Bevor wir uns um die Korrektheit und die Laufzeit unseres Algorithmus kummern,untersuchen wir, was passiert, wenn wir zur

”Aufbewahrung“ von noch zu besuchenden

Knoten statt einer Schlange einen Stapel verwenden. Heraus kommt die Tiefensuche, diesich nur in der Reihenfolge des Besuchs der entdeckten Knoten von der Breitensuche un-terscheidet. Die Namen ruhren daher, daß mit einer Schlange zuerst in die Breite gesuchtwird und mit einem Stapel zuerst in die Tiefe.

Algorithmus 10.2 (Tiefensuche von einem Knoten aus)

Methodenkopf:dfs(Vertex v0)

135

Page 133: Skript Waack merged

Rumpf:Großschritt 1.

Erzeuge einen (leeren) Stapel x fur Knoten.Großschritt 2. [Beruhre die Wurzel]

2.1. Farbe die Wurzel v0 mit der Farbe grey ein.2.2. Lege v0 auf den Stapel x.

Großschritt 3. [Besuch beim Spitzenknoten des Stapels]Fuhre aus

3.1.[Beginne den Besuch]Binde das Spitzenelement von x an Variable v.Entferne das Spitzenelement vom Stapel.

3.2.[Beruhre alle noch unberuhrten Nachbarn des Knotens v]Fur alle zu v inzidenten, bisher unklassifizierten Kanten e fuhre aus:

Binde den von v verschiedenen Endknoten von e an u.Falls die Farbe von u white ist, so fuhre aus:

Versehe e mit der Klassifikation treeEdge.Beruhre u: Farbe u grey und lege ihn auf den Stapel x.

Andernfalls klassifiziere e als otherEdge.3.3.[Beende den Besuch]

Farbe v mit der Farbe black.solange der Stapel x nicht leer ist.

Verdeutlichen wir uns den Unterschied von Algorithmus 10.2 zu Algorithmus 10.1,indem wir den Graphen aus Abbildung 1.1 diesem Algorithmus unterwerfen.

Als”Protokoll der Rechnung“ erhalten wir die folgende Tabelle, wobei das Spitzenele-

ment des Stapels jeweils links steht:

Durchlauf Inhalt von x neue treeEdge–Kanten neue otherEdge–Kanten1 A (A,B), (A,C), (A,F), (A,G) keine2 G, F, C, B (G,E) keine3 E, F, C, B (E,D) (E,F)4 D, F, C, B keine (D,F)5 F, C, B keine keine6 C, B keine keine7 B keine keine

Im Ergebnis werden die Kanten wie in der Abbildung 10.2 dargestellt klassifiziert.Als nachstes geht es darum, die Korrektheit unserer Algorithmen nachzuweisen.

Lemma 10.3 Die folgende Bedingung Inv ist eine Invariante der Schleife des Großschrit-tes 3 der Algorithmen bfs(v0) und dfs(v0):

Klausel 1: Der Teilgraph T des Eingabegraphen, dessen Knotenmenge aus allen grauenund schwarzen Knoten besteht, und dessen Kanten die treeEdge–Kanten sind, ist einBaum.

136

Page 134: Skript Waack merged

A

treeEdge

F C B G

E D

treeEdge treeEdge treeEdge treeEdge

otherEdge

otherEdge

treeEdge

Abbildung 10.2: Ein Beispiel zur Tiefensuche

Klausel 2: Die Warteschlange (Der Stapel) enthalt genau die grauen Knoten. Die weißenKnoten waren noch nie in der Schlange (dem Stapel), die schwarzen haben sie (ihn) bereitswieder verlassen.

Beweis. Die Invarianz von Klausel 2 der Bedingung Inv ist offensichtlich: Jeder weißeKnoten, der grau gefarbt wird, muß sich sofort in die Warteschlange bzw. in den Stapeleinreihen. Ein Knoten, der aus der Schlange (dem Stapel) entfernt wurde, bekommt nachdem Besuch die Farbe schwarz.

Die Invarianz von Klausel 1 beweisen wir durch vollstandige Induktion uber die Anzahlder Schleifendurchlaufe λ.

Induktionsanfang λ = 0. Vor dem ersten Durchlauf befindet sich nur der an die Methodeubergebene Wurzelknoten in der Schlange bzw. dem Stapel, ist also grau. Schwarze Knotenund Tree-Kanten gibt es noch nicht.

Induktionsschritt von λ ≥ 0 auf λ + 1. Sei Tλ der in Klausel 1 angegebene Teil-graph nach dem λ–ten Schleifendurchlauf. Nach Induktionsvoraussetzung handelt es sichum einen Baum. Im λ + 1–ten Durchlauf kommen alle zum Spitzenknoten der Schlange(des Stapels), der ja als grauer Knoten bereits zu Tλ gehort, adjazenten weißen Knotenhinzu. Die jeweiligen Verbindungskanten werden Tree–Kanten. Damit ist klar, daß derGraph Tλ+1, der Graph aus Klausel 1 nach dem λ + 1–ten Durchlauf der Schleife, zusam-menhangend ist. Warum ist Tλ+1 ebenfalls ein Baum? Wir verwenden die Bedingung 4 ausSatz 1.35. Nach Induktionsvoraussetzung ist Tλ Baum und es gilt: E (Tλ) = V (Tλ)−1. Imλ + 1–ten Durchlauf der Schleife kommen genauso viele Knoten wie Kanten hinzu. Um-

137

Page 135: Skript Waack merged

klassifizierungen von Tree-Kanten und Other–Kanten finden nicht statt. Folglich gilt auchE (Tλ+1) = V (Tλ+1)− 1.

Satz 10.4 Sei G = (V, E) das aktuelle Graphobjekt, das die Vorbedingung erfullt, und seiv0 ∈ V ein beliebiger Wurzelknoten. Dann gilt:

Die Methoden bfs(v0) und dfs(v0) arbeiten korrekt und haben Laufzeit Θ(|E|+ |V |).

Beweis. Die Korrektheit folgt unmittelbar aus Lemma 10.3: die Schleife in Großschritt3 wird erst verlassen, wenn keine grauen Knoten mehr vorhanden sind, denn diese sindnach Klausel 2 die Knoten in der Warteschlange bzw. dem Stapel. Daß alle Knoten

”ent-

deckt“, also grau gefarbt werden, liegt daran, daß der Graph (nach der Vorbedingung)zusammenhangend ist.

Die entscheidende Beobachtung in Bezug auf die Laufzeit ist, daß nach Klausel 2 derSchleifeninvarianten jeder Knoten genau einmal in die Schlange bzw. den Stapel einge-reiht wird. Folglich gibt es genau |V | Schleifendurchlaufe, von denen jeder offensichtlichΘ(1+degree(v)) Kosten verursacht, wobei v derjenige Knoten ist, der wahrend des Durch-laufs gerade besucht wird, und degree(v) den Grad des Knotens v bezeichnet. Nach Aussage1.32 folgt nun die Behauptung.

Zum Abschluß dieses Abschnittes mussen wir uns der Tatsache stellen, daß wir einemsehr großen Graphen, wenn er uns durch Kantenlisten gegeben ist, nicht problemlos ansehenkonnen, ob er zusammenhangend ist. Dazu sehen wir uns die Algorithmen 10.1 und 10.2nochmals an und stellen fest, daß sie auch den folgenden Vertrag erfullen:

Vorbedingung: (i) Knoten v0 gehort zur Knotenmenge V des aktuellen Graphen G.(ii) Ist Gv0

die Zusammenhangskomponente von G, in welcher der Knoten v0 liegt,so sind alle Knoten von Gv0

weiß; alle Kanten von Gv0tragen das Klassifizierungs-

merkmal unclassifiedEdge.

Nachbedingung: (i) Alle Knoten von Gv0tragen die Farbe black.

(ii) Alle Kanten von Gv0sind entweder als treeEdge oder als otherEdge klassifiziert.

(iii) Der Teilgraph Tv0= (V (Gv0

) , e ∈ E(Gv0) | e ist treeEdge ist ein aufspannen-

der Baum von Gv0.

Wir betrachten die folgenden Algorithmen:

Algorithmus 10.5 (Breiten/Tiefensuche)

Methodenkopf:breadthFirstSearch() bzw. depthFirstSearch()

Rumpf:Großschritt 1.

Setze das Datenfeld n components des aktuellen Graphen auf 0.

138

Page 136: Skript Waack merged

Großschritt 2.Durchlaufe mit dem Platzhalter v alle Knoten von G und fuhre aus:

Falls v noch weiß ist, so fuhre aus:Erhohe das Datenfeld n components um 1.Fuhre bfs(v) bzw. dfs(v) aus.

Die Analyse der beiden Algorithmen 10.5 ist einfach: Zunachst stellt man ohne Proble-me fest, daß sie den folgenden Vertrag erfullen:

Vorbedingung: (i) Alle Knoten des aktuellen Graphen G = (V, E) sind weiß.(ii) Alle Kanten von G tragen das Klassifizierungsmerkmal unclassifiedEdge.(iii) Das Datenfeld n components ist 0.

Nachbedingung: (i) Alle Knoten von G tragen die Farbe black.(ii) Alle Kanten von G sind entweder als treeEdge oder als otherEdge klassifiziert.(iii) Der W = (V, e ∈ E | e ist treeEdge ist ein aufspannender Wald von G.(iv) Das Datenfeld n components halt die Anzahl der Zusammenhangskomponentenvon G

Die Laufzeit der beiden Algorithmen, angesetzt auf den Graphen G, ist ebenfallsΘ(|E(G)| + |V (G)|): Da nichts passiert, wenn der Laufer v in eine Zusammenhangskom-ponente des aktuellen Graphen G fallt, deren aufspannender Baum bereits durch einenfruheren Aufruf von bfs bzw. dfs berechnet worden ist, gilt fur die Laufzeit die folgendeGleichung:

Θ

(

|V (G)|+k∑

i=1

(|E(Gi)|+ |V (Gi)|)

)

= Θ(|E(G)|+ |V (G)|),

wobei G1, . . . , Gk die Zusammenhangskomponenten des Eingabegraphen G sind.

10.3 Minimale aufspannende Baume

10.3.1 Begriffe. Ein allgemeiner generischer Algorithmus

Ein ungerichteter Graph G = (V, E) heißt ungerichtetes Netzwerk, wenn er zusatzlich miteiner Kantenmarkierungsfunktion, einer Kostenfunktion

cost : E → N,

ausgestattet ist. (Als Kantengewichte kommen nicht nur naturliche, sondern auch ganzeoder reelle Zahlen in Betracht.)

Die Kosten einer Kantenmenge sind die Summe der Kosten ihrer Elemente. Die Kosteneines Teilgraphen sind die Kosten seiner Kantenmenge. Ein aufspannender Baum einesNetzwerks G heißt minimal, wenn er unter allen aufspannenden Baumen von G minimaleKosten hat.

139

Page 137: Skript Waack merged

Beobachtung 10.6 Die Existenz minimaler aufspannender Baume (Abkurzung: MST )ist wegen Beobachtung 1.36 und der Tatsache, daß es fur einen endlichen Graphen nurendlich viele aufspannende Baume gibt, gesichert.

Im weiteren sei N =(G = (V, E), cost

)ein zusammenhangendes ungerichtetes Netz-

werk. Wir fragen uns, unter welchen Bedingungen wir eine bestimmte Kante in einenvorliegenden MST einwechseln konnen. Folgendes ist offensichtlich.

Beobachtung 10.7 (Einwechseln einer Kante in einen MST) Sei T ein MST vonN , und sei e ∈ E eine Kante, die nicht zu T gehort. Dann schließt die Hinzunahme von e

zu T einen Kreis in T ∪ e. Sind e1, e2, . . ., em und e genau die Kanten dieses Kreises,so bezeichnen wir fur jede Kante e′ ∈ e1, e2, . . . , em mit Te′e denjenigen aufspannendenBaum, den man aus T durch Austausch der Kante e′ gegen die Kante e erhalt.

Dann ist

1. cost e ≥ cost e′;

2. der Baum Te′e genau dann ein MST, wenn cost e = cost e′ ist.

Fur die umgekehrte Frage benotigen wir den folgenden Begriff.

Definition 10.8 Ein Schnitt in G = (V, E) ist eine nichttriviale Partition (X, V \X) derKnotenmenge V von G.

Eine Kante e ∈ E kreuzt den Schnitt (X, V \X), wenn der eine Endknoten von e zuX, der andere Endknoten zu V \X gehort.

Naturlich gilt.

Beobachtung 10.9 Sei (X, V \X) ein Schnitt von G = (V, E), und sei e eine Kante, dieden Schnitt (X, V \X) kreuzt.

Jeder Kreis C in G, der die Kante e enthalt, enthalt mindestens noch eine weitere denSchnitt (X, V \X) kreuzende Kante e′ 6= e.

Ist daruber hinaus T ein aufspannender Baum von G = (V, E), der die Kante e enthalt,und zerfallt T durch Entfernen der Kante e in die Zusammenhangskomponenten X undV \X, so gehort e′ nicht zu T .

Beobachtung 10.10 (Auswechseln einer Kante aus einem MST) Sei T ein MSTvon N , und sei e ∈ E eine Kante, die zu T gehort. Seien ferner X und V \ X die Zu-sammenhangskomponenten, in die T durch Entfernen der Kante e zerfallt.

Sind e, und e1, e2, . . ., em genau die Kanten aus E, die den Schnitt (X, V \X) kreuzen,und ist fur jede Kante e′ ∈ e1, e2, . . . , em Tee′ der aufspannende Baum, den man aus T

durch Austausch der Kante e gegen die Kante e′ erhalt.Dann ist

1. cost e ≤ cost e′;

140

Page 138: Skript Waack merged

2. der Baum Tee′ genau dann ein MST, wenn cost e = cost e′ ist.

Unsere Algorithmen berechnen einen MST, indem sie die Kanten farben. Ist eine Kantegrun, so gehort sie zum MST, ist sie rot, so gehort sie nicht dazu. Wir brauchen Regeln, diees erlauben festzustellen, ob zu einem Zeitpunkt wahrend der Laufzeit eine noch ungefarbteKante grun- oder rotfarbbar ist.

Definition 10.11 1. Eine bisher ungefarbte Kante e ∈ E heißt genau dann grunfarb-bar, wenn es einen Schnitt (X, V \X) mit den folgenden Eigenschaften gibt:

– Die Kante e kreuzt den Schnitt (X, V \X).

– Keine grune Kante kreuzt den Schnitt (X, V \X).

– Unter allen ungefarbten Kanten, die den Schnitt (X, V \ X) kreuzen, ist dieKante e von minimalem Gewicht.

2. Eine bisher ungefarbte Kante e heißt genau dann rotfarbbar, wenn einen Kreis C inG mit den folgenden Eigenschaften gibt:

– Der Kreis C enthalt die Kante e.

– Der Kreis C enthalt keine rote Kante.

– Unter allen ungefarbten Kanten, die auf dem Kreis C liegen, ist die Kante e vonmaximalem Gewicht.

3. Eine bisher ungefarbte Kante heißt genau dann farbbar, wenn sie grun- oder rotfarb-bar ist.

Alle Algorithmen, die wir in diesem Abschnitt studieren werden, sind Konkretisierungendes folgenden allgemeinen generischen Algorithmus.

Algorithmus 10.12 (Allgemeiner generischer MST-Algorithmus)

Vorbedingung.N = (G = (V, E), cost) ist ein zusammenhangendes Netzwerk mit |E| ≥ 1.Alle Kanten aus E sind ungefarbt.

Nachbedingung.Alle Kanten sind gefarbt.Die grungefarbten Kanten zusammen mit V bilden einen MST von N .

Rumpf.Fuhre aus

”Wahle eine farbbare Kante aus und farbe sie entsprechend ein.“

bis daß keine Kante mehr farbbar ist.

Lemma 10.13 Algorithmus 10.12 ist korrekt.

141

Page 139: Skript Waack merged

Beweis. Zum Beweise der Korrektheit von Algorithmus 10.12 genugt es offenbar zuzeigen, daß die folgende Bedingung eine Invariante von dessen Fuhre-aus-Schleife ist. Dazusei t die Anzahl der bisherigen Iterationen dieser Schleife, und seien

E(red)t , E

(green)t ⊆ E

die Menge der bis zu diesem Zeitpunkt rot bzw. grungefarbten Kanten.

Klausel 1. Es existiert ein MST Tt mit

E(green)t ⊆ E (Tt) (10.1)

E(red)t ∩ E (Tt) = ∅ (10.2)

Klausel 2. Falls∣∣∣E

(red)t

∣∣∣ < |E| − |V |+ 1

ist, so gibt es eine rotfarbbare Kante.

Klausel 3. Falls∣∣∣E

(green)t

∣∣∣ < |V | − 1

ist, so gibt es eine grunfarbbare Kante.

Invarianz von Klausel 1. Wir fuhren den Beweis durch vollstandige Induktion uber dieAnzahl t der bisherigen Iterationen der Schleife des Rumpfes von Algorithmus 10.12.

Der Induktionsanfang t = 0 ist eine unmittelbare Folge von Beobachtung 10.6.

Induktionsanfang t ր t + 1. Sei e diejenige Kante, die im (t + 1)-ten Durchlauf derSchleife gefarbt wird.

Fall 1. Die Kante e wird grungefarbt und e ∈ E (Tt) oder die Kante e wird rotgefarbtund e 6∈ E (Tt). Dann kann man Tt+1 als Tt wahlen.

Fall 2: Die Kante e wird grungefarbt und e 6∈ E (Tt). Wir erhalten Tt+1 aus Tt durchEinwechseln der Kante e unter Verwendung von Beobachtung 10.7 und Definition 10.11(1): Sei (X, V \X) der Schnitt, vermoge dessen die Kante e im (t + 1)-ten Durchlauf derSchleife grungefarbt wird. Wir betrachten den Teilgraphen Tt ∪ e, in dem durch e einKreis C geschlossen wird. Da die Kante e den Schnitt (X, V \ X) kreuzt, gibt es nachBeobachtung 10.9 eine zweite Kante e′ 6= e auf C, die folglich sogar in Tt liegt und denSchnitt (X, V \X) ebenfalls kreuzt.

Die Kante e′ ist unmittelbar nach dem Einfarben von e noch ungefarbt, denn ware sieschon

– grun, so konnte nach Definition 10.11 (1) (X, V \ X) nicht der Schnitt sein, langsdessen e grungefarbt wird;

142

Page 140: Skript Waack merged

– rot, so widersprache das Klausel 1 (10.2) zum Zeitpunkt t und damit der Induktions-voraussetzung, da ja e′ ∈ Tt ist.

Wegen e′ ∈ Tt folgt unter Verwendung von Beobachtung 10.7 (1)

cost(e) ≥ cost(e′).

Wegen Definition 10.11 (1) folgt

cost(e) ≤ cost(e′)

und somit

cost(e) = cost(e′).

Nun konnen wir Beobachtung 10.7 (2) anwenden und erhalten, daß Tt+1 := (Tt)e′e einMST ist.

Fall 3: Die Kante e wird rotgefarbt und e ∈ E (Tt). Wir erhalten Tt+1 aus Tt durchAuswechseln der Kante e unter Verwendung von Beobachtung 10.10 und Definition 10.11(2): Sei C der Kreis, langs dessen die Kante e im (t + 1)-ten Durchlauf der Schleife rot-gefarbt wird. Wir betrachten den Teilgraphen Tt \ e, der durch Entfernen von e in zweiZusammenhangskomponenten X und V \X zerfallt, die einen Schnitt (X, V \X) bilden.Da die Kante e diesen Schnitt kreuzt, gibt es nach Beobachtung 10.9 eine zweite Kantee′ 6= e auf C, die den Schnitt (X, V \X) ebenfalls kreuzt und die nicht zu Tt gehort.

Die Kante e′ ist unmittelbar nach dem Einfarben von e noch ungefarbt, denn ware sieschon

– rot, so konnte nach Definition 10.11 (2) C nicht der Kreis sein, langs dessen e rot-gefarbt wird;

– grun, so folgte aus Klausel 1 (10.1) zum Zeitpunkt t und damit aus der Induktions-voraussetzung, daß e′ ∈ Tt ware. Widerspruch!

Wegen Definition 10.11 (2) folgt

cost(e) ≥ cost(e′).

Wegen e ∈ Tt folgt aus Beobachtung 10.10 (1)

cost(e) ≤ cost(e′)

und somit

cost(e) = cost(e′).

143

Page 141: Skript Waack merged

Nun konnen wir Beobachtung 10.10 (2) anwenden und erhalten, daß Tt+1 := (Tt)ee′ einMST ist.

Invarianz von Klausel 2. Angenommen, es ist∣∣∣E

(red)t+1

∣∣∣ < |E| − |V |+ 1. (10.3)

Wir mussen zeigen, daß es eine rotfarbbare Kante gibt. Dazu betrachten wir den MSTTt+1, dessen Existenz wir zum Nachweis der Invarianz von Klausel 1 bewiesen haben.Wegen (10.3) und der Tatsache, daß Tt+1 genau |V | − 1 Kanten enthalt, gibt es eine Kante

e, die nicht in E(red)t+1 und nicht in Tt+1 liegt. Folglich ist sie noch ungefarbt. Wir nehmen

sie zu Tt+1 hinzu, und wissen, daß sie in Tt+1∪e einen Kreis geschlossen hat. Auf diesemKreis befindet sich keine rote Kante, da Tt+1 keine roten Kanten enthalt. Folglich ist dieKante e rotfarbbar.

Invarianz von Klausel 3. Angenommen, es ist∣∣∣E

(green)t+1

∣∣∣ < |V | − 1. (10.4)

Wir mussen zeigen, daß es eine grunfarbbare Kante gibt. Dazu betrachten wir den MSTTt+1, dessen Existenz wir zum Nachweis der Invarianz von Klausel 1 bewiesen haben.Wegen (10.4) und der Tatsache, daß Tt+1 genau |V | − 1 Kanten enthalt, gibt es eine Kante

e ∈ Tt+1, die nicht in E(green)t+1 liegt. Da Tt+1 keine roten Kanten enthalt, ist e noch ungefarbt.

Entfernt man e aus Tt+1, so erhalt man aus den Zusammenhangskomponenten, in die Tt+1

dann zerfallt, einen Schnitt, langs dessen man e grunfarben kann.

Bemerkungen.

• Klausel drei der Schleifeninvariante aus Lemma 10.13 sichert, daß man fur einenkonkreten Algorithmus nur eine grune Regel benotigt. Man farbt entsprechend dieserRegeln |V | − 1 Kanten grun. Der Rest gehort dann nicht zum MST. (Etwas analogesgilt fur Klausel zwei und die rote Regel.)

• In den Abschnitten 10.3.2 und 10.3.3 werden wir Algorithmen angeben, die wederSchnitte noch Kreise inspizieren. Es ist unsere Aufgabe, die dort angegeben Farbungs-regeln auf die Regeln aus Definition 10.11 zuruckzufuhren.

10.3.2 Der Algorithmus von Prim

Sei N = (G, cost), wobei G = (V, E) ein ungerichteter Graph ist, ein zusammenhangendesNetzwerk mit |E| ≥ 1. Im Algorithmus von Prim wird, von einem beliebigen, aber festenKnoten u ∈ V ausgehend, ein MST aufgebaut. Es gibt nur eine grune Farbungsregel.Nachdem man |V | − 1 Kanten grungefarbt hat, werden die restlichen Kanten rotgefarbt.

Der Algorithmus von Prim laßt sich besonders gut verstehen, wenn man auch fur ihneinen generischen Rahmen hat.

Algorithmus 10.14 (Prims generischer MST-Algorithmus)

144

Page 142: Skript Waack merged

Methodenkopf.genericPrim(Vertex u)

Vorbedingung.N = (G, cost) ist ein zusammenhangendes Netzwerk mit |E| ≥ 1.Der Knoten u gehort zu V .Alle Kanten aus E sind ungefarbt.

Nachbedingung.Alle Kanten sind gefarbt.Die grungefarbten Kanten zusammen mit V bilden einen MST von N .

Großschritt 1.Fuhre aus

”Wahle eine Prim-grunfarbbare Kante aus und farbe sie grun.“

bis daß die Anzahl der grunen Kanten gleich |V | − 1 ist.Großschritt 2.

Farbe alle noch ungefarbten Kanten rot.

Wir fixieren ein beliebige u ∈ V . Wann ist eine Kante Prim-grunfarbbar? Dazu be-trachten wir den t + 1-ten Durchlauf der Schleife in Großschritt 1 von Algorithmus 10.14.Sei

Wt := (V, e | e ist nach t Durchlaufen grungefarbt) (10.5)

der grune Wald zu diesem Zeitpunkt. (Daß es sich dabei tatsachlich um einen Wald handelt,folgt unmittelbar aus Definition 10.15.) Sei ferner Ut diejenige Zusammenhangskomponentevon Wt, zu welcher der Knoten u gehort:

u ∈ Ut. (10.6)

Vor dem ersten Duchlauf ist

W0 = (V, ∅) (10.7)

und

U0 = (u, ∅) . (10.8)

Definition 10.15 Eine bisher ungefarbte Kante e ∈ E ist im (t + 1)-ten Durchlauf derSchleife aus Großschritt 1 von Algorithmus 10.14 genau dann Prim-grunfarbbar, wenn sie

– die Zusammenhangskomponente Ut mit einer anderen Zusammenhangskomponentevon Wt verbindet;

– unter allen Kanten mit dieser Eigenschaft von minimalem Gewicht ist.

145

Page 143: Skript Waack merged

Bemerkung. Offenbar bestehen zu jedem Zeitpunkt t die von Ut verschiedenen Zusam-menhangskomponenten von Wt aus genau einem Knoten.

Um zu zeigen, daß Algorithmus 10.14 korrekt ist, genugt es, die Prim-Grunfarbbarkeitauf die Grunfarbbarkeit aus Definition 10.11 zuruckzufuhren.

Lemma 10.16 Die Prim-Grunfarbbarkeit ist eine Spezialisierung der Grunfarbbarkeit ausDefinition 10.11.

Beweis. Man muß lediglich den Schnitt angeben, langs dessen eine Kante im (t + 1)-tenDurchlauf der Schleife aus Großschritt 1 von Algorithmus 10.14 grungefarbt wird. Das ist

(Ut, V \ Ut) . (10.9)

Wir kommen zur effizienten Implementation von Algorithmus 10.14. Das Hauptproblembesteht darin, eine Kante minimalen Gewichts zu finden, die Ut mit einer anderen Zusam-menhangskomponente von Wt verbindet. Dazu benotigen wir den Begriff des Randknotensund der (zum Zeitpunkt t) hellgrunen Kante.

Definition 10.17 Ein Knoten v aus der Knotenmenge V heißt Randknoten von Ut, wenn

1. er nicht zu Ut gehort;

2. es eine Kante gibt, die v mit einem Knoten aus Ut verbindet.

Eine Kante e heißt zum Zeitpunkt t hellgrun, wenn es einen Randknoten v von Ut gibt,so daß die Kante e

1. den Knoten v mit Ut verbindet;

2. unter allen Kanten, die ebenfalls den Knoten v mit Ut verbinden, von minimalemGewicht ist.

Offensichtlich gilt.

Beobachtung 10.18 (Charakterisierung der Prim-Grunfarbbarkeit) Eine Kante istgenau dann Prim-grunfarbbar, wenn sie unter allen hellgrunen Kanten von minimalem Ge-wicht ist.

Alles, worauf es nach Beobachtung 10.18 nun ankommt, ist, eine hellgrune Kante vonminimalem Gewicht schnell aufzufinden.

Die Idee. Wir halten alle Randknoten von Ut in einer Prioritatswarteschlange q, wobeidie Prioritat eines Randknotens das Gewicht einer seiner hellgrunen Kanten ist. Im Gegen-satz zu der Prioritatswarteschlange aus Abschnitt 8.4.4 gilt hier: Je kleiner der Wert desDatenfeldes priority, desto großer die Prioritat. Dann gilt aber fur das Spitzenelementvt+1 der Warteschlange, daß man seine hellgrune Kante grunfarben kann: Ut+1 = Ut∪vt+1.

Nun muß die Warteschlange, die den Rand von Ut+1 halten soll, aktualisiert werden:

146

Page 144: Skript Waack merged

1. Der Spitzenknoten vt+1 wird aus der Warteschlange entfernt.

2. Alle zu vt+1 adjazenten Knoten w mussen besucht werden:

(a) Gehort der Knoten w nicht zum Rand von Ut, so muß er mit dem Gewicht derKante (vt+1, w), die offenbar zu diesem Zeitpunkt seine hellgrune Kante ist, indie Proritatswarteschlange q aufgenommen werden.

(b) Gehort w schon zum Rand von Ut, so kann durch das Hinzukommen von vt+1

beim Ubergang von Ut zu Ut+1 eine Veranderung in der Prioritat von w ein-getreten sein: Man muß das Gewicht der Kante (vt+1, w) mit dem Gewicht derbisherigen hellgrunen Kante von w vergleichen. Hat jene ein geringeres Gewicht,ist sie nun die hellgrune Kante von w. Der Knoten w muß dann in der Prio-ritatswarteschlange q befordert werden (siehe Algorithmus 8.84).

Wie sehen die zusatzlichen Hauptdatenfelder der Klasse Vertex aus? Die Prioritats-warteschlange q spielt fur Prims Algorithmus eine ahnliche Rolle wie die Warteschlangebzw. der Stapel fur die Algorithmen aus Abschnitt 10.2: Jeder Knoten muß genau einmalhinein und genau einmal heraus, wobei wir stets fur jeden Knoten daruber im Bilde seinmussen, in welcher der drei moglichen Phasen er gerade ist. Dazu verwalten wir ein Da-tenfeld color mit den moglichen Werten white, grey und black: Die Farbe white stehtdafur, daß der Knoten noch nicht in der Warteschlange war. Die Farbe grey zeigt seineZugehorigkeit zur Warteschlange und damit zum Rand von U — wir lassen ab jetzt denIndex

”t“ meist weg — an. Die Farbe black schließlich weist aus, daß der Knoten seinen

Platz in U eingenommen hat.Die folgenden beiden Datenfelder der Klasse Vertex sind nur dann von Bedeutung,

wenn der aktuelle Knoten Randknoten von U ist: Das Datenfeld lightgreen zeigt aufeine hellgrune Kante des aktuellen Knotens. Das Datenfeld priority tragt die Kosten derhellgrunen Kante.

Schließlich brauchen wir ein carrier-Datenfeld, um die Prioritatswarteschlange, wie inAbschnitt 8.4.4 dargestellt, effizient verwalten zu konnen.

Die Klasse Edge muß um ein Datenfeld color mit den moglichen Werten uncolored,green und red erganzt werden.

Nun zu dem Algorithmus, der uns den Rumpf der Schleife in Großschritt 2 von Algo-rithmus 10.14 implementiert.

Algorithmus 10.19 (Prims Grunfarberegel)

Methodenkopf.prim-greencoloringrule(Vertex u)

Vorbedingung.Ist U die Zusammenhangskomponente von W , zu der u gehort, so

ist |U | < |V | und die Prioritatswarteschlange q enthalt alle Randknoten von U ;

147

Page 145: Skript Waack merged

sind alle Randknoten von U grau;sind alle Knoten aus U schwarz;sind alle anderen Knoten weiß.

Nachbedingung.Die Vorbedingung bleibt erhalten.Die Menge U ist um ein Element vergroßert.

Großschritt 2.1.v← q.top(), q.remove(), v.color← black

e← v.lightgreen(), e.color← green

Großschritt 2.2.Durchlaufe mit w alle zu v adjazenten Knoten und fuhre aus.

2.2.1. Falls w.color() = white, so fuhre aus:w.lightgreen ← (w, v), w.priority← cost(w, v), w.color← grey

q.add(w)2.2.2. Falls w.color() = grey, so fuhre aus:e← (w, v)Falls cost e < w.priority(), so fuhre aus.w.lightgreen← e

q.siftup(w, cost e)

Nun ist die Zeit reif fur die finale Version von Prims Algorithmus.

Algorithmus 10.20 (Prims MST-Algorithmus)

Methodenkopf.mstPrim(Vertex u)

Vorbedingung.N = (G, cost) ist ein zusammenhangendes Netzwerk mit |E| ≥ 1.Der Knoten u gehort zu V .Alle Kanten aus E sind ungefarbt.

Nachbedingung.Alle Kanten sind gefarbt.Die grungefarbten Kanten zusammen mit V bilden einen MST von N .

Großschritt 1.Richte leere Prioritatswarteschlange q mit der Kapazitat |V | − 1 ein.Farbe u schwarz.Durchlaufe mit w alle zu u adjazenten Knoten und fuhre aus.w.lightgreen ← (u, w)w.priority ← cost(u, w)w.color← grey

q.add(w)Großschritt 2.

Fuhre aus

148

Page 146: Skript Waack merged

prim-greencoloringrule(u)

bis daß die Anzahl der grunen Kanten gleich |V | − 1 ist.Großschritt 3.

Farbe alle noch ungefarbten Kanten rot.

Wir bemerken, daß die Schleife aus Großschritt 2 von Algorithmus 10.20 genau dannabgebrochen wird, wenn die Prioritatswarteschlange leer ist.

Wie in Abschnitt 8.4.4 dargestellt, verwenden wir zur Implementation der Prioritats-warteschlage einen d-Heap. Dann gilt.

Satz 10.21 Die Laufzeit von Algorithmus 10.20 ist ein

O (d · |V | · logd |V | + |E| · logd |V |) . (10.10)

Beweis. Wir beobachten.

– Die Verwaltung der Prioritatswarteschlange ist, was die Laufzeit angeht, in Algorith-mus 10.20 dominant. Fur die Laufzeit von deren Operationen konnen wir Satz 8.87anwenden.

– Jeder Knoten wird genau einmal in die Prioritatswarteschlange eingefugt und genaueinmal herausgenommen. Der Laufzeitbedarf dafur ist

O (d · |V | · logd |V |) .

– Es gibt hochstens soviele siftup-Operationen wie Kanten. Der Beitrag dieser Ope-rationen zur Laufzeit ist ein

O (|E| · logd |V |) .

Korollar 10.22 Falls

d =

2 +|E|

|V |

︸ ︷︷ ︸

>2

(10.11)

ist, so ist die Laufzeit von Algorithmus 10.20 ein

O (|E| · logd |V |) . (10.12)

149

Page 147: Skript Waack merged

Beweis. Wegen (10.10) genugt es zu zeigen, daß

d · |V | = O (|E|)

ist. Da G zusammenhangend ist, gilt |E| ≥ |V | − 1. Wir erhalten

d · |V | =

2 +|E|

|V |

|V |

(

3 +|E|

|V |

)

|V |

= O (|E|) .

Korollar 10.23 Falls |E| = Ω (|V |1+ǫ) fur eine Konstante ǫ ∈ (0, 1) ist, so ist die Laufzeitvon Algorithmus 10.20 ein

O

(1

ǫ· |E|

)

, (10.13)

sofern d gemaß Gleichung 10.11 gewahlt wird.

Beweis. Sei

|E| ≥ γ · |V |1+ǫ

fur eine positive reelle Konstante γ. Wegen (10.12) genugt es,

logd |V | = O

(1

ǫ

)

fur

d =

2 +|E|

|V |

≥ 2 + γ · |V |ǫ

zu zeigen. Wir erhalten

logd |V | ≤ log(2+γ·|V |ǫ) |V |

=ln |V |

ln (2 + γ · |V |ǫ)

=ln |V |

γǫ ln |V | + ln

(2

γ|V |ǫ+ 1

)

︸ ︷︷ ︸

>0

<1

γǫ.

150

Page 148: Skript Waack merged

Wir bemerken abschließend, daß Korollar 10.23 besagt, daß Algorithmus 10.20 fur so-genannte dicke Graphen in linearer Zeit arbeitet.

10.3.3 Der Algorithmus von Kruskal

Kruskals generischer Algorithmus

Wie beim Algorithmus von Prim, erleichtert auch im vorliegenden Falle ein generischerAlgorithmus das Verstandnis.

Algorithmus 10.24 (Kruskals generischer MST-Algorithmus)

Methodenkopf.genericKruskal()

Vorbedingung.N = (G, cost) ist ein zusammenhangendes Netzwerk

mit n = |V | Knoten und m = |E| ≥ n− 1 Kanten.Alle Kanten aus E sind ungefarbt.

Nachbedingung.Alle Kanten sind gefarbt.Die grungefarbten Kanten zusammen mit V bilden einen MST von N .

Großschritt 1.Sortiere die Kanten aus E mit aufsteigendem Gewicht:

e1, e2, . . . , em

Großschritt 2.Fur t = 0, 1, . . . , m− 1 fuhre aus:

Wende Kruskals Farberegel auf die Kante et+1 an.

Wie sieht Kruskals Farberegel fur die Kante et+1 aus Großschritt 2 von Algorithmus10.24 aus? Sei fur t = 0, 1, . . . , m− 1

Wt := (V, e | e ist nach t Durchlaufen grungefarbt) (10.14)

der grune Wald zu diesem Zeitpunkt. (Daß es sich dabei tatsachlich um einen Wald handelt,mußte strenggenommen gezeigt werden. Diese Eigenschaft ergibt sich aus dem Folgendenunmittelbar durch vollstandige Induktion uber t.)

Definition 10.25 Die Kante et+1 aus Großschritt 2 von Algorithmus 10.24 wird genaudann grungefarbt, wenn sie zwei Zusammenhangskompenten von Wt verbindet. Anderfallswird sie rotgefarbt.

Um zu zeigen, daß Algorithmus 10.24 korrekt ist, genugt es, die Kruskal-Farbbarkeitauf die Farbbarkeit aus Definition 10.11 zuruckzufuhren.

151

Page 149: Skript Waack merged

Lemma 10.26 Die Kruskal-Grunfarbbarkeit ist eine Spezialisierung der Grunfarbbarkeitaus Definition 10.11, die Kruskal-Rotfarbbarkeit eine Spezialisierung der Rotfarbbarkeit.

Beweis. Seien T1, T2, . . ., Tk die Zusammenhangskomponenten von Wt aus Gleichung10.14, und sei et+1 = (a, b) die Kante aus Großschritt 2 von Algorithmus 10.24.

Fall 1. Die Knoten a und b gehoren beide zu Ti fur ein i = 1, 2, . . . , k. Dann schließt dieKante et+1 in Ti ∪ et+1 einen Kreis, langs dessen sie gemaß Definition 10.11 rotgefarbtwerden kann.

Fall 2. Die Knoten a und b gehoren zu unterschiedlichen Baumen Ti bzw. Tj (i 6= j) des

Waldes Wt. Dann kreuzt die Kante et+1 den Schnitt(

V (Ti),⋃

k 6=i V (Tk))

, langs dessen sie

gemaß Definition 10.11 grungefarbt werden kann.

Zur algorithmischen Umsetzung der Kruskalsche Farberegeln aus Definition 10.25 ver-wenden wir eine Union-Find-Datenstruktur.

Spezifikation der Union-Find-Datenstruktur

Wir nehmen an, daß die Menge V gleich 1, 2, . . . , n ist, wobei n zu Beginn der Anwendungfestgelegt und dann nicht mehr verandert wird. Wir wollen Partitionen einer Teilmengevon V verwalten. Die nichtleeren Teilmengen, die eine solche Partition ausmachen, heißenBlocke. Jeder Block bekommt als Schlusselinformation einen Reprasentanten aus seinerMitte zugeordnet.

Als Beispiel betrachten wir eine Partition der Teilmenge 1, 2, . . . , 10 der Menge

V = 1, 2, . . . , 11, 12 mit den Blocken V1 = 5, 4, 1, 9 V2 = 8, 2, 3, 6 V3 = 7, 10

wobei 5 der Reprasentant von V1, 8 der Reprasentant von V2 und 7 der Reprasentant vonV3 sei. Die Elemente 11 und 12 gehoren zu keinem Block.

Der Zustand unserer Datenstruktur ist eine Partition

W = V1, V2, . . . , Vk

einer Teilmenge der Menge V . Zusatzlich ist eine Funktion

rep : W→k⋃

i=1

Vi

mit

rep(Vi) ∈ Vi (∀ i = 1, 2, . . . , k),

definiert, fur die es daruber hinaus keine weiteren Anforderungen gibt. Die folgenden Ope-rationen werden unterstutzt.

152

Page 150: Skript Waack merged

empty(Integer n). Erzeugt wird die leere Union-Find-Datenstruktur – der Zustand istW = ∅ –, die zur Verwaltung von Partionen von Teilmengen der Menge 1, 2, . . . , ngeeignet ist.

makeSet(Integer x). Diese Operation hat zur Vorbedingung, daß das Element x mit1 ≤ x ≤ n in keinem der Blocke der aktuellen Partition enthalten ist. Sie garantiert,daß ein Einer-Block x erzeugt und der Partition hinzugefugt wird.

find(Integer x) returns Integer liefert den Reprasentanten rep Vi des Blockes Vi, zudem das ubergebene Element x gehort. Vorbedingung ist naturlich, daß es einensolchen Block gibt.

union(Integer x, y) hat als Vorbedingung, daß die ubergebenen Elemente x und y von-einander verschiedene Reprasentanten von Blocken des aktuellen Zustands der Da-tenstruktur sind. Die Operation vereinigt diese beiden Blocke zu einem neuen Blockund bestimmt einen Reprasentanten aus dessen Mitte.

Bemerkungen.

• Ausgehend von n Einerblocken benotigt man genau n − 1 union-Operationen, umalle Elemente in einem Block vereinigen zu konnen.

• Naturlich kann man auch Union-Find-Datenstrukturen uber Mengen von Objekteneines beliebigen Typs definieren.

Kruskals Algorithmus

Nun konnen wir unter Verwendung der Union-Find-Datenstruktur sehr leicht Algorithmus10.24 durch den folgenden Algorithmus implementieren.

Algorithmus 10.27 (Kruskals MST-Algorithmus)

Methodenkopf.mstKruskal()

Vorbedingung.N = (G, cost) ist ein zusammenhangendes Netzwerk

mit n = |V | Knoten und m = |E| ≥ 1 Kanten.Alle Kanten aus E sind ungefarbt.

Nachbedingung.Alle Kanten sind gefarbt.Die grungefarbten Kanten zusammen mit V bilden einen MST von N .

Großschritt 1.Sortiere die Kanten aus E mit aufsteigendem Gewicht:

e1, e2, . . . , em

Großschritt 2.

153

Page 151: Skript Waack merged

2.1. Erzeuge eine Union-Find-Datenstruktur greenForest:greenForest.empty(n)

2.2. Fur x = 1, 2, . . . , n fuhre aus.greenForest.makeSet(x)

2.3. Fur t = 0, 1, . . . , m− 1 fuhre aus:Weise x und y die Endpunkte der Kante et+1 zu.x← greenForest.find(x)y← greenForest.find(y)Falls x 6= y, so fuhre aus.greenForest.union(x, y)

Farbe die Kante et+1 grun.Andernfalls

farbe die Kante et+1 rot.

Es ist auf Grund der Spezifikation der Union-Find-Datenstruktur offensichtlich, daßAlgorithmus 10.27 korrekt arbeitet. Aber wie steht es um seine Laufzeit? Alles hangtvon der Implementation der Union-Find-Datenstruktur ab. Eine sehr effiziente Variantebesprechen wir im folgenden Abschnitt. Das Ergebnis nehmen wir schon an dieser Stellevorweg.

Dazu wiederholen wir die Definition des iterierten Logarithmus aus Kapitel 1.

g(0) = 1

g(j) = 2g(j−1) (j ≥ 1)

Das großte monoton wachsende zahlentheoretische Linksinverse der durch die vorste-henden Rekursionsgleichungen definierten Funktion heißt iterierte Logarithmusfunktion zurBasis 2. (Bezeichnungen: log∗

2).Die Bezeichnung iterierter Logarithmus ist durch Gleichung 1.22 aus dem Kapitel 1

motiviert:

log∗2 n := minj ∈ N | ⌈log

(j)2 n⌉ = 1

Gleichung 1.7 besagt in diesem Falle

log∗2 n =

j falls j − 1 ≥ 0 und g(j − 1) < n ≤ g(j);

0 falls n ≤ 1.

Wir ersehen aus den vorstehenden Gleichungen insbesondere, daß die Zahl log∗2 n angibt,

wie oft man die Zahl n zur Basis zwei logarithmieren muß, um eine Zahl ≤ 1 zu erhalten.Zum Abschluß dieses Abschnitts wiederholen wir die Aussage uber das Wachstum der

Funktion log∗2 n aus dem Kapitel 1 (siehe dort Gleichung 1.27).

g(0) = 1 g(1) = 2 g(2) = 4 g(3) = 16 g(4) = 216 = 65536 g(5) = 265536

154

Page 152: Skript Waack merged

Wir erhalten:

[0, 1]→ 0 (1, 2]→ 1 (2, 4]→ 2 (4, 16]→ 3 (16, 65536]→ 4 (65536, 265536]→ 5

Die Aussage, die Funktion log∗2 sei in dieser Welt kleiner oder gleich funf, ist zwar

unmathematisch aber dennoch nicht unbegrundet.

Satz 10.28 Unter Verwendung der Implementation der Union-Find-Datenstruktur ausAbschnitt 10.4 ist die Laufzeit von Algorithmus 10.27 ein

O (|E| · log2 |V |) . (10.15)

Beweis. Die Laufzeit von Großschritt 1 ist ein O (|E| · log2 |E|) = O (|E| · log2 |V |).In Großschritt 2 werden zuerst |V | makeSet-Operationen und dann |V | − 1 union- und

2|E| find-Operationen durchgefuhrt. Die Implementation der Union-Find-Datenstrukturaus Abschnitt 10.4 sichert, daß dies in Zeit O (|E| · log∗

2 |V |) geschehen kann.

10.4 Eine effiziente Implementation der Union-Find

Datenstruktur

Die Union-Find-Datenstruktur haben wir in Abschnitt 10.3.3 spezifiziert. Nun wollen wireine besonders effiziente Implementation kennenlernen. Die Elemente der Menge V =1, 2, . . . , n werden als Knoten eines zu den Wurzeln der Baume gerichteten Waldes darge-stellt, wobei ein Block einem Baum entspricht. Die Knoten des Baumes sind die Elemente,die Wurzel der Reprasentant des Blockes. Der Block wird durch seine Wurzel reprasen-tiert. Besonders bequem laßt sich ein solcher Wald durch ein Feld father : array[1 . . . n]mit Werten in den ganzen Zahlen reprasentieren, wobei father[i] genau dann gleich j > 0ist, wenn der Knoten j der Vater des Knotens i ist. Ein Knoten i gehort genau dann nochnicht zur Union-Find-Datenstruktur, wenn father[i] = 0 ist.

Sei W ein Wald uber V , sei T ein Baum dieses Waldes, und sei schließlich v ein Knotenaus T . Wir bezeichnen mit SIZE v die Anzahl der Knoten des in v wurzelnden TeilbaumesTv des Baumes T .

Wie lautet der Eintrag im father-Feld fur eine Wurzel? Will man die Operationunion(x, y) durchfuhren, wobei x und y Wurzeln sind, so ist es naheliegend, entwederden Knoten x zum Vater des Knotens y zu machen oder umgekehrt. Es ist vernunftig(siehe Lemma 10.34), die Wurzel des kleineren Baumes zum Sohn der Wurzel des großerenBaumes zu machen. Um das umsetzen zu konnen, muß man fur jede der aktuellen Wurzelnderen Große in der Datenstruktur halten. Da der father-Eintrag einer Wurzel v nicht dazugebraucht wird, auf den Vater zu verweisen, kann hier die Große des zugehorigen Baumeseingetragen werden: Fur jede Wurzel v des Waldes W ist father[v] = − SIZE v. Folglichgilt

father : array[1 . . . n] of 0,±1, . . . ,±n.

155

Page 153: Skript Waack merged

Wir betrachten ein Beispiel fur den Zustand einer Union-Find-Datenstruktur fur dieMenge V = 1, 2, . . . , 13.

4

3 11

2 5 9

12

6

1 7 8

10 (10.16)

Die Wurzeln 4, 12 und 10 sind die Reprasentanten ihrer Blocke. Das father-Feld sieht wiefolgt aus:

i 1 2 3 4 5 6 7 8 9 10 11 12 13father[i] 6 11 4 −6 11 12 6 6 11 −1 4 −5 0

(10.17)

Nun sind wir in der Lage, die empty-, die makeSet- und die union-Operation zu imple-mentieren.

Algorithmus 10.29 (empty-Operation)

Methodenkopf.empty(Integer n)

Erzeuge ein Feld father vom Typ Integer mit dem Indexbereich 1, 2, . . . , n.Initialisiere jede Komponente dieses Feldes mit 0.

Algorithmus 10.30 (makeSet-Operation)

Methodenkopf.makeSet(Integer x)

Vorbedingung.x gehort nicht zum aktuellen Wald: father[x] = 0.

father[x] ← −1

Algorithmus 10.31 (union-Operation)

156

Page 154: Skript Waack merged

Methodenkopf.union(Integer x, y)

Vorbedingung.x 6= y sind Reprasentanten.

Falls |father[x]| ≤ |father[y]|, so fuhre aus:father[y] ← father[y] + father[x]father[x] ← y

return

father[x] ← father[x] + father[y]father[y] ← x

Wir erkennen leicht, daß die Union-Find-Datenstruktur aus (10.16) nicht vermoge desAlgorithmus 10.31 zustande gekommen sein kann: Zum Zeitpunkt der Vereinigung von demin 4 wurzelnden Baum mit dem in 11 wurzelnden Baum war der in 11 wurzelnde großer.Das gleiche trifft fur die in 12 und in 6 wurzelnden Baume zum Vereinigungszeitpunkt zu.Ein mit Algorithmus 10.31 vertraglicher Zustand sieht so aus:

11

2 5 9 4

3

6

1 7 8 12

10 (10.18)

Wenden wir union(11, 6) auf (10.18) an, so erhalten wir

11

2 5 9 4

3

6

1 7 8 12

10 (10.19)

Auch an einer einfachen Implementation der find-Operation soll es an dieser Stellenicht fehlen.

Algorithmus 10.32 (Einfache find-Operation)

157

Page 155: Skript Waack merged

Methodenkopf.simpleFind(Integer x) returns Integer

Vorbedingung.x gehort zum aktuellen Wald.

Rumpf.Falls father[x] < 0, so return x.return simpleFind(father[x])

Um die Vorbedingung einer union-Operation zu erfullen, mussen insbesondere vorherentsprechende makeSet-Operationen angewandt worden sein. Eine Folge von makeSet- undunion-Operationen, deren Vorbedingungen erfullt und die damit ausfuhrbar sind, heißtzulassig.

Definition 10.33 Ein Wald uber der Menge V = 1, 2, . . . , n, der durch eine Folgezulassiger makeSet- und union-Operationen auf den anfanglichen Aufruf von empty(n)

erzeugt wurde, heißt unkomprimiert.

In Abschnitt 1.5.2 aus Kapitel 1 haben wir fur einen Knoten v eines Wurzelbaumes T

dessen Hohe heightT v eingefuhrt. Dabei handelte es sich um die Lange des langsten Wegesvon einem Blatt von T zum Knoten v. (In (10.16) hat der Knoten 4 die Hohe 2, der Knoten11 die Hohe 1.)

Lemma 10.34 Sei W ein unkomprimierter Wald gemaß Definition 10.33, und sei x einKnoten aus W . Dann ist

SIZE x ≥ 2height x.

Beweis. Der Beweis wird durch vollstandige Induktion uber die Hohe h = height x

gefuhrt.Induktionsanfang. Ist h = 0, so ist der Knoten x ein Blatt, und deshalb SIZE x =

#Tx = 1.Induktionsschritt h− 1ր h. Ist h > 0, so hat der Knoten x einen Sohn y mit der Hohe

h − 1. Nach Induktionsvorausetzung ist SIZE y ≥ 2h−1. Wir betrachten zusatzlich zumaktuellen Zeitpunkt denjenigen Zeitpunkt, zu dem der Knoten y vermoge der Operationunion(x, y) (oder der Operation union(y, x)) Sohn des Knotens x wurde (Vereinigungs-zeitpunkt):

x

y

158

Page 156: Skript Waack merged

Es galt SIZE x ≥ SIZE y. Seitdem hat sich die Große des in y wurzelnden TeilbaumesTy nicht mehr verandert, der Teilbaum, der unmittelbar vor dem Vereinigungszeitpunktgleich Tx war, kann sich bis zum aktuellen Zeitpunkt nur großert haben. Wir erhaltenSIZE x ≥ 2 · 2h−1 = 2h.

Mit Hilfe von Lemma 10.34 erkennen wir, warum in Algorithmus 10.31 die Wurzelmit der kleineren Große zum Sohn und die mit der großeren Große zum Vater gemachtwird: Der Baum wird buschig, lange Pfade konnen bis zu einem gewissen Grade vermiedenwerden.

Korollar 10.35 Alle Baume eines unkomprimierten Waldes sind in ihrer Tiefe durchO (log2 n) beschrankt.

Wir erhalten.

Satz 10.36 Implementiert man die Union-Find-Datenstruktur mit Hilfe der Algorithmen10.30, 10.31, 10.32, so haben die makeSet- und die union-Operation konstante Laufzeit.Die Laufzeit der Operation simpleFind(x) ist ein O (log2 n).

Bemerkung. Satz 10.36 komplettiert bereits den Beweis von Satz 10.28, denn die 2|E|find-Operationen kosten O (|E| log2 |V |).

Aber es geht, was die find-Operation angeht, noch besser. Die Walder aus Definition10.33 heißen nicht ohne Grund unkomprimiert. Algorithmus 10.32 hat LaufzeitO (depth x),wobei x der ubergebene Knotren ist. Diese vergeht beim

”Marsch“ von Knoten x in Rich-

tung Wurzel. Man kann Algorithmus 10.32 ohne großen Zusatzaufwand so anreichern, daßzukunfige find-Operationen schneller ablaufen konnen. Die Idee dazu heißt Pfadkompres-sion (engl. path compresssion). Auf dem Weg zur Wurzel werden alle Knoten, auf die mandabei stoßt, zu Sohnen der Wurzel gemacht:

159

Page 157: Skript Waack merged

x4

x3

x2

x1

x

⇒ x4

x3 x2 x1 x

(10.20)

Die rekursive Umsetzung der Idee der Pfadkompression gemaß (10.20) liefert den fol-genden Algorithmus.

Algorithmus 10.37 (find-Operation mit Pfadkompression)

Methodenkopf.find(Integer x) returns Integer

Vorbedingung.x gehort zum aktuellen Wald: father[x] 6= 0.

Falls father[x] < 0, so return x.root← find(father[x])father[x] ← root

return root

Das Szenario fur die Laufzeitanalyse der Union-Find-Datenstruktur unter Verwendungvon Algorithmus 10.37 sieht in Anbetracht von Algorithmus 10.27 so aus: Wir nehmen an,daß n Objekte zu verwalten sind, die nach der Ausfuhrung von n makeSet-Operationen,die ja zusammen in O (n) Zeit ausfuhrbar sind, als Einerblocke vorliegen. Nun werden 2mfind- und n−1 union-Operationen in beliebiger Reihenfolge ausgefuhrt, wobei m ≥ n−1

160

Page 158: Skript Waack merged

ist. Das ist ein typischer Anwendungsfall fur die Tilgungskostenanalyse. Deshalb beweisenwir den folgenden Satz im Abschnitt 11.2 des Kapitels 11.

Satz 10.38 Implementiert man die Union-Find-Datenstruktur mit Hilfe der Algorithmen10.30, 10.31, 10.37, so ist nach der Ausfuhrung der n makeSet-Operationen die Laufzeitder 2m find-Operationen und der n− 1 union-Operationen zusammen ein O (m · log∗

2 n).

161

Page 159: Skript Waack merged

Literaturverzeichnis

[CLRS01] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein. Introduction toAlgorithms. MIT Press, 2001.

[Tar83] R. E. Tarjan. Data Structures and Network Algorithms. SIAM, 1983.

162

Page 160: Skript Waack merged

Kapitel 11

Fortgeschrittene Analyse- undEntwurfstechniken

Dieses Kapitel ist stark an [CLRS01] angelehnt.

11.1 Rekursive Algorithmen

11.1.1 Das Mastertheorem zur Analyse rekursiver Algorithmen

Rekursive Algorithmen von der Art, wie wir sie in diesem Abschnitt studieren wollen,sind beispielsweise Algorithmus 6.3 aus Abschnitt 6.1 oder Algorithmus 8.90 (rekursivesMergesort) aus Abschnitt 8.4.5.

Seien c : N → N eine monoton wachsende zahlentheoretische Funktion, a ≥ 1 einekonstante naturliche, b > 1 eine konstante rationale und n0 ≥ b wiederum eine konstantenaturliche Zahl. Wir analysieren den folgenden generischen Algorithmus bzgl. seines Ver-brauchs einer Ressource A in Abhangigkeit vom Problemgroßeparameter n: A(n) ∈ N istder Ressourcenverbrauch auf Problemstellungen I der Große n.

Algorithmus 11.1 (Generischer rekursiver Algorithmus)

Eingabe: Problemstellung I der Große n.Großschritt 1.

Falls n ≤ n0 ist, so lose I unter konstantem Ressourcenverbrauch geeignet.Großschritt 2.

”Teile“ die Eingabe I der Große n in a Teilprobleme der Große ⌈n/b⌉.

Großschritt 3.

”Beherrsche“ die Eingabe I wie folgt.3.1. Lose die a Teilaufgaben der Große ⌈n/b⌉ rekursiv.3.2. Setze die Losungen der Teilprobleme zu einer Losung von I zusammen.

163

Page 161: Skript Waack merged

Ist c(n) der Ressourcenverbrauch in den Großschritten 2 und 3.2 beim Teilen undbeim Zusammensetzen, so gilt fur den Gesamtressourcenverbrauch des Algorithmus 11.1offensichtlich die folgende Rekursion.

A(n) =

a · A (⌈n/b⌉) + c(n) falls n > n0 ist;

Θ (1) andernfalls.(11.1)

Das folgende Mastertheorem lost die Rekursion (11.1) fur viele interessante Falle.

Satz 11.2 Es gilt.

1. Gibt es eine Konstante ǫ > 0, so daß c(n) = O(nlogb a−ǫ

)ist, so ist

A(n) = O(nlogb a

). (11.2)

2. Ist c(n) = Θ(nlogb a

), so ist

A(n) = Θ(nlogb a log2 n

). (11.3)

3. Es ist

A(n) = Θ (c(n)) , (11.4)

sofern die Funktion c bezuglich der Konstanten a und b die folgende Regularitatsbe-dingung erfullt: Es existiert eine Konstante γ ∈ (0, 1), so daß fur alle naturlichenn > b

a · c (⌈n/b⌉) ≤ γ · c(n) (11.5)

gilt.

Beweis.

Schritt 1. Zunachst wiederholen wir Gleichung 1.5 aus Abschnitt 1.2:

logb

n

n0

= minj | ⌈n/bj⌉ ≤ n0.

Schritt 2. Wir zeigen, daß aus der Regularitatsbedingung fur die Funktion c bezuglichder Konstanten a und b folgt, daß es eine Konstante ǫ > 0 so gibt, daß

c(n) = Ω(nlogb a+ǫ

)(11.6)

164

Page 162: Skript Waack merged

gilt. Es ist fur k =⌈

logbnn0

c(n) ≥

(a

γ

)k

c(⌈n/bk⌉

)

Wegen Gleichung 1.5 aus Abschnitt 1.2 und

k =

logb

n

n0

= ⌈logb n− logb n0⌉ = logb n−Θ (1) (11.7)

erhalten wir

c(n) = Ω

((a

γ

)logb n)

= Ω

(

alogb n ·

(1

γ

)logb n)

= Ω(

nlogb a · blogb( 1

γ )·logb n)

= Ω(

nlogb a · nlogb( 1

γ ))

.

Schritt 3. Wir beweisen in diesem Schritt, daß fur n > n0

A(n) = Θ(nlogb a

)+

⌈logb(n/n0)⌉−1∑

j=0

ajc(⌈n/bj⌉

)

︸ ︷︷ ︸

=:B(n)

(11.8)

ist. Sei k =⌈

logbnn0

. Durch k-faches Einsetzen der Rekursionsgleichung (11.1) in sich

selbst erhalten wir

A(n) =

k−1∑

j=0

ajc(⌈n/bj⌉

)+ O (1) ak.

Unter Verwendung von Gleichung 1.5 aus Abschnitt 1.2 und Gleichung 11.7 folgt

ak = bk logb a = Θ(nlogb a

),

woraus die Behauptung dieses Beweisschrittes folgt.

165

Page 163: Skript Waack merged

Schritt 4. Beweis von Behauptung 1. Es genugt zu zeigen, daß fur B(n) aus Gleichung11.8

B(n) = O(nlogb a

)(11.9)

gilt. Unter den Voraussetzungen von Behauptung 1 erhalten wir

B(n) = O

⌈logb(n/n0)⌉−1∑

j=0

aj⌈n/bj⌉logb a−ǫ

.

Wegen

⌈n/bj⌉logb a−ǫ ≤ (2n/bj)logb a−ǫ = O((n/bj)logb a−ǫ

)

folgt

B(n) = O

nlogb a−ǫ

⌈logb(n/n0)⌉−1∑

j=0

( a

blogb a−ǫ

)

︸ ︷︷ ︸

=bǫ

j

.

= O

nlogb a−ǫ · bǫ·⌈logb(n/n0)⌉︸ ︷︷ ︸

=O(nǫ)

,

woraus Gleichung 11.9 folgt.

Schritt 5. Beweis von Behauptung 2. Es genugt zu zeigen, daß fur B(n) aus Gleichung11.8

B(n) = O(nlogb a · log2 n

)(11.10)

gilt. Ein analoges Vorgehen wie beim Beweis von Behauptung 1 liefert die folgendeGleichungskette.

B(n) = O

⌈logb(n/n0)⌉−1∑

j=0

aj⌈n/bj⌉logb a

= O

nlogb a

⌈logb(n/n0)⌉−1∑

j=0

( a

blogb a

)j

= O(nlogb a · ⌈logb(n/n0)⌉

),

woraus unter Verwendung von Gleichung 11.7 Gleichung 11.8 und damit Behauptung2 folgt.

166

Page 164: Skript Waack merged

Schritt 6. Beweis von Behauptung 3. Wegen Schritt 2 dieses Beweises und Gleichung 11.8genugt es zu zeigen, daß

B(n) = O (C(n))

ist. Aus der Regularitatsbedingung 11.5 folgt fur alle in Rede stehenden Indizes j

aj · c(⌈n/bj⌉

)≤ γj · c(n),

woraus wir

B(n) =

⌈logb(n/n0)⌉−1∑

j=0

aj · c(⌈n/bj⌉

)

≤ c(n)

⌈logb(n/n0)⌉−1∑

j=0

γj

< c(n)∞∑

j=0

γj

= O (c(n))

erhalten.

Bemerkungen.

• Die Algorithmen aus den Abschnitten 11.1.2 und 11.1.3 sind Beispiele fur die Be-hauptung 1 des Mastertheorems.

• Die Algorithmen 6.3 und 8.90 sind Beispiele fur die Behauptung 2 des Mastertheo-rems. In beiden Fallen ist a = b = 2 und c(n) = O (n).

• Behauptung 3 ist beispielsweise in dem folgenden Fall anwendbar: a = 3, b = 4 undc(n) = n log n. Dann ist nlogb a = n0,793.... Wir uberprufen die Regularitatsbedingung:

3 · c(n/4) = 3 · (n/4) log(n/4)

≤3

4n log n︸ ︷︷ ︸

=c(n)

.

In diesem Falle ware

A(n) = Θ (n · log n) .

• Die Behauptungen des Mastertheorems beruhen auf einem Vergleich der Funktio-nen nlogb a und c(n). Die Fallunterscheidung des Mastertheorems ist jedoch nichtvollstandig. Ist beispielsweise a = b = 2 und c(n) = n log n, so ist nlogb a = n. Zwi-schen nlogb a = n und c(n) = n log n ist jedoch kein polynomialer

”Abstand“. Es ist

fur jedes ǫ > 0

limn→∞

c(n)

nlogb a+ǫ= lim

n→∞

log n

nǫ= 0.

167

Page 165: Skript Waack merged

11.1.2 Die Multiplikationsmethode von Karatsuba und Ofman

Schon in der Schule macht man sich mit dem folgenden Problem vertraut.

Problem 1 (Multiplikation von zwei naturlichen Zahlen)

Zulassige Eingaben sind zwei Felder

A = (an−1, an−2, . . . , a0) B = (bn−1, bn−2, . . . , b0) (11.11)

uber 0, 1, wobei wir annehmen, daß die Lange n der Felder eine Zweierpotenz großeroder gleich eins ist. (Wir identifizieren in diesem Abschnitt jede Bitfolge X mit derdurch sie kanonisch dargestellten naturlichen Zahl ν(X) (siehe Abschnitt 1.1).)

Komplexitatsmaß ist die Anzahl der Bitoperationen.

Ausgabe ist ein Feld

C = (cn, cn−1, . . . , c0) = A ∗B, (11.12)

wobei”∗“ in diesem Abschnitt die Multiplikation von Mehrbit-Zahlen bezeichnet.

Ist

A′ :=(an−1, an−2, . . . , an/2

)A′′ :=

(an/2−1, an/2−2, . . . , a0

)(11.13)

und

B′ :=(bn−1, bn−2, . . . , bn/2

)B′′ :=

(bn/2−1, bn/2−2, . . . , b0

), (11.14)

so ist

A = A′ · 2n/2 + A′′ B = B′ · 2n/2 + B′′

und folglich

C = A′ ∗1 B′ · 2n + [A′ ∗2 B′′ + A′′ ∗3 B′] · 2n/2 + A′′ ∗4 B′′ (11.15)

Algorithmus 11.3 (Rekursive ganzzahlige Multiplikation)

168

Page 166: Skript Waack merged

Großschritt 1.Wenn n = 1 ist, so fuhre aus.

Multipliziere die beiden Bits der Eingabe:c0 ← a0 · b0

return

Großschritt 2.Zerlege die Eingabefelder gemaß (11.13) und (11.14).

Großschritt 3.Berechne das Produkt gemaß Gleichung 11.15.

Im Falle von Algorithmus 11.3 ist die Anzahl a der rekursiven Aufrufe gleich 4, dieProblemgroße wird halbiert (b = 2), und fur das Zusammensetzen werden c(n) = O (n)Bitoperationen fur zwei Shifts um hochstens n Positionen, sofern man diese uberhauptals Bitoperationen betrachtet, und drei Additionen von 2n-Bitzahlen benotigt. Satz 11.2,Behauptung 1 ergibt als Abschatzung fur die Bitoperationen O

(nlogb a

)= O (n2). Das ist

keine Verbesserung gegenuber der wohlbekannten Schulmethode, die ebenfalls O (n2) Bit-operationen benotigt. Wir werden im folgenden aber zeigen, daß man zwei n-Bitzahlen Aund B mit weniger als 4 Multiplikationen von n/2-Bitzahlen und O (n) weiteren Bitope-rationen multiplizieren kann.

Die Losung ist uberraschend einfach: Es ist

(A′ + A′′) ∗5 (B′ + B′′) = [A′ ∗2 B′′ + A′′ ∗3 B′] + A′ ∗1 B′ + A′′ ∗4 B′′.

Wir erhalten

[A′ ∗2 B′′ + A′′ ∗3 B′] = (A′ + A′′) ∗5 (B′ + B′′)− A′ ∗1 B′ − A′′ ∗4 B′′,

woraus unter Verwendung von (11.15)

C = A′ ∗1 B′ · 2n + [(A′ + A′′) ∗5 (B′ + B′′)−A′ ∗1 B′ − A′′ ∗4 B′′] · 2n/2 + A′′ ∗4 B′′

(11.16)

folgt.

Algorithmus 11.4 (Ganzzahlige Multiplikation nach Karatsuba und Ofman)

Großschritt 1.Wenn n = 1 ist, so fuhre aus.

Multipliziere die beiden Bits der Eingabe:c0 ← a0 · b0

return

Großschritt 2.Zerlege die Eingabefelder gemaß (11.13) und (11.14).

Großschritt 3.Berechne das Produkt gemaß Gleichung 11.16.

169

Page 167: Skript Waack merged

Bemerkung. Man sieht, daß es in Großschritt 3 von Algorithmus 11.4 nur noch zudrei rekursiven Aufrufen kommt. Die Terme A′ + A′′ und B′ + B′′ aus Gleichung 11.16sind allerdings unter Umstanden (n/2 + 1)- und keine n/2-Bitzahlen. Die Behebung dieser(kleinen) Unvertraglichkeit von Algorithmus 11.4 mit Algorithmus 11.1 ist eine leichteUbungsaufgabe.

Mithilfe von Satz 11.2, Behauptung 1 erhalt man den folgenden Satz.

Satz 11.5 Algorithmus 11.4 benotigt O(nlog2 3

)Bit-Operationen.

Bemerkungen.

• Offenbar ist log2 3 ≈ 1, 5 . . ..

• Die beste bekannte obere Schranke fur die Multiplikation zweier n-Bitzahlen gehtauf Schonhage und Strassen zuruck. Sie ist O (n · log n · log log n). Allerdings ist dieKonstante groß.

11.1.3 Die schnelle Matrixmultiplikation von Strassen

Ein weiteres sehr lehrreiches Beispiel fur die Anwendung Satz 11.2, Behauptung 1 ist dasfolgende Problem.

Problem 2 (Multiplikation von zwei quadratischen Matrizen)

Zulassige Eingaben sind zwei n× n Matrizen

A = (aij)ij=1,2,...,n B = (bij)ij=1,2,...,n (11.17)

uber einem Ring R, wobei wir annehmen, daß der Grad n der Matrizen eine Zweier-potenz großer oder gleich eins ist.

Komplexitatsmaß ist die Anzahl der arithmetischen Operationen (Additionen, Multi-plikationen) in R.

Ausgabe ist eine Matrix

C = (cij)ij=1,2,...,n = A ·B

cij =

n∑

k=1

aikbkj (i, j = 1, 2, . . . , n) (11.18)

Es ist wohlbekannt, daß man fur n = 2k mit k > 1 die Multiplikation der Matrizen aus(11.17) durch Blockmatrixmultiplikation losen kann. Ist

A =

(A11 A12

A21 A22

)

B =

(B11 B12

B21 B22

)

C =

(C11 C12

C21 C22

)

, (11.19)

170

Page 168: Skript Waack merged

wobei C = A ·B (siehe Gleichung 11.18) ist, und die Aij ,Bij und Cij fur i, j = 1, 2 n2× n

2-

Matrizen uber R sind, so ist

Cij = Ai1 · B1j + Ai2 · B2j (i, j = 1, 2). (11.20)

Gleichung 11.20 besagt, daß man die Multiplikation zweier n × n-Matrizen uber R aufdie Multiplikation von zwei 2 × 2-Matrizen uber dem Ring der n

2× n

2-Matrizen uber R

zuruckfuhren kann. Dies gibt Anlaß zu dem folgenden rekursiven Algorithmus fur die Ma-trixmultiplikation.

Algorithmus 11.6 (Rekursive Matrixmultiplikation)

Großschritt 1.Wenn n = 1 ist, so fuhre aus.

Multipliziere die beiden Skalare der Eingabe:c11 ← a11 · b11.

return

Großschritt 2.Zerlege die Eingabematrizen gemaß Gleichung 11.19.

Großschritt 3.Berechne das Produkt gemaß Gleichung 11.20.

Analysiert man Algorithmus 11.6 mithilfe von Satz 11.2, Behauptung 1 – im Fallevon Algorithmus 11.6 ist die Anzahl a der rekursiven Aufrufe gleich 8, die Problemgroßewird halbiert (b = 2), und fur das Zusammensetzen werden c(n) = 4 · n2

4= n2 skalare

Additionen benotigt –, so erhalt man als Abschatzung fur die arithmetischen OperationenO(nlogb a

)= O (n3). Das ist nicht besser, als wenn man die Matrizen vermoge der Definition

aus Gleichung 11.18 multiplizierte. Aber man weiß nun, worauf es ankommt, wenn man eineVerbesserung erzielen will: Man muß eine Regel finden, nach der man zwei 2× 2-MatrizenA und B mit weniger als 8 Skalarmultiplikationen multiplizieren kann.

Wir verwenden im folgenden fur die Koeffizienten dieser Matrizen und der Produktma-trix C die Notation aus Gleichung 11.19.

Lemma 11.7 (Strassen) Man kann zwei 2× 2-Matrizen A und B mit

– 7 skalaren Multiplikationen,

– 6 skalaren Subtraktionen und

– 12 skalaren Additionen

171

Page 169: Skript Waack merged

multiplizieren: Ist

M1 := (A12 − A22) · (B21 + B22)

M2 := (A11 + A22) · (B11 + B22)

M3 := (A21 − A11) · (B11 + B12)

M4 := (A11 + A12) · B22

M5 := A11 · (B12 − B22)

M6 := A22 · (B21 − B11)

M7 := (A21 + A22) · B11

so ist

C11 = M1 + M2 −M4 + M6

C12 = M4 + M5

C21 = M6 + M7

C22 = M2 + M3 + M5 −M7.

Den Beweis von Lemma 11.7 kann man ganz einfach durch Einsetzen und Ausrechnenfuhren. Das Problem war selbstverstandlich, die Gleichungen aus Lemma 11.7 zu finden.

Lemma 11.7 ermoglicht den folgenden Algorithmus.

Algorithmus 11.8 (Rekursive Matrixmultiplikation nach Strassen)

Großschritt 1.Wenn n = 1 ist, so fuhre aus.

Multipliziere die beiden Skalare der Eingabe:c11 ← a11 · b11.

return

Großschritt 2.Zerlege die Eingabematrizen gemaß Gleichung 11.19.

Großschritt 3.Berechne das Produkt gemaß Lemma 11.7.

Mithilfe von Satz 11.2, Behauptung 1 erhalt man leicht den folgenden Satz.

Satz 11.9 Algorithmus 11.8 benotigt O(nlog2 7

)arithmetische Operationen.

Bemerkungen.

• Man beachte, daß log2 7 ≈ 2, 81 . . . ist.

• Die beste bekannte obere Schranke fur die Matrixmultiplikation ist O (n2,376). Aller-dings ist die Konstante groß.

172

Page 170: Skript Waack merged

11.2 Die Tilgungsmethode der Kostenanalyse

11.2.1 Zwei einfuhrende Anwendungsbeispiele

Der modifizierte Stapel

Wir betrachten einen Stapel, bei dem neben den ublichen Methoden create() zur Erzeu-gung eines leeren Stapels D0, empty() zur Feststellung, ob der aktuelle Stapel leer ist, addzum Hinzufugen eines Elements und remove() zum Entfernen des Spitzenelements nocheine Methode multiremove(Integer k) existiert, die genau die ersten k Elemente des ak-tuellen Stapels entfernt. Die Anwendung von remove() und multiremove(k) ist naturlichnur dann zulassig, wenn noch mindestens ein bzw. k Elemente auf dem Stapel liegen.

Ist op1 := add, op2 := remove() und op3 := multiremove(k), so geht es uns um dieLaufzeitanalyse einer beliebigen zulassigen Folge

D0 opi1 opi2 . . . opiℓ

von ℓ Operationen. Dazu ordnen wir jeder der drei Operationen sogenannte reale Kosten czu, die proportional zur Laufzeit sind: c(op1) = c(op2) = 1 und c(op3) =k. Die kanonischeAnalyse ergibt

c(D0 opi1 opi2 . . . opiℓ) = O(ℓ2).

Unser Ziel ist der Nachweis, daß

c(D0 opi1 opi2 . . . opiℓ) = O (ℓ)

ist.

Die Hashtabelle

Bei der Laufzeitanalyse des offenen Hashings war die Behandlung der Verdopplungsstar-tegie aus dem Abschnitt 8.3.4 offengeblieben. In diesem Kapitel werden wir diese Luckeschließen. Im folgenden verwenden wir die Bezeichnungen aus den Abschnitten 8.3.2 und8.3.4. Wir nehmen an, daß α0 := 1

4und α1 := 1 ist. Nach der Erzeugung haben wir eine

leere Hashtabelle D0 mit einer fixierten Anzahl von Buckets m0 = 2k0 .Ist op1 := insert, op2 := delete, so geht es uns um die mittlere Laufzeitanalyse einer

beliebigen zulassigen Folge

D0 opi1 opi2 . . . opiℓ

von ℓ Operationen. Wiederum ordnen wir jeder der zwei Operationen auf eine Hashtabellemit m = 2k Buckets reale Kosten zu, die proportional zur mittleren Laufzeit sind:

– c(op1) = c(op2) = 1, falls nach dem Einfugen bzw. Streichen α < 1 bzw. 14

< α ist.

173

Page 171: Skript Waack merged

– c(op1) = m, falls nach dem Einfugen α = 1 ist.

– c(op2) = m2, falls nach dem Streichen α = 1

4ist.

Wie beim modifizierten Stapel auch schon, ergibt die kanonische Analyse

c(D0 opi1 opi2 . . . opiℓ) = O(ℓ2).

Wir streben den Beweis fur

c(D0 opi1 opi2 . . . opiℓ) = O (ℓ)

an.

11.2.2 Eine allgemeine Beschreibung des Problems

Wir haben eine Datenstruktur von einem wohldefinierten Typ, die nach ihrer Erzeugungim Zustand D0 ist. Zu dieser Datenstruktur gehoren Operationen op1, op2, . . ., opr. (ZurErinnerung, der Zustand einer Datenstruktur wird durch die Werte ihrer Datenfelder be-stimmt.) Wir messen die Kosten der Operationsausfuhrung bezuglich eines Aufwandsma-ßes A wie folgt: Jeder denkbaren Uberfuhrung der Datenstruktur von einem Zustand Din einen Zustand D′ vermoge einer Operation opi (i = 1, 2, . . . , r) ordnen wir sogenanntereale ganzahlige Kosten c(D, opi) so zu, daß

c(D, opi) = Θ (Aopi(D)) (11.21)

ist. Wir suchen fur jede Operationsausfuhrung

Dopi→ D′

sogenannte Tilgungskosten

c(D, opi) ∈ [0,∞).

Fur jede zulassige Folge von Operationen

adm = D0 opi1 opi2 . . . opiℓ (11.22)

muß unter Verwendung der Bezeichnungen

Dj := D0 opi1 opi2 . . . opij (j = 1, 2, . . . , ℓ) (11.23)

cj := c(Dj−1, opij) (j = 1, 2, . . . , ℓ) (11.24)

cj := c(Dj−1, opij) (j = 1, 2, . . . , ℓ) (11.25)

174

Page 172: Skript Waack merged

die Tilgungsbedingung

ℓ∑

j=1

cj ≤

ℓ∑

j=1

cj (11.26)

erfullt sein. Dabei heißt die Operationenfolge aus Gleichung 11.22 zulassig, wenn die Ope-ration opi1 auf D0 ausfuhrbar ist, und fur j = 1, . . . , ℓ−1 die Nachbedingung von Operationopij zusammen mit der Klasseninvarianten die Vorbedingung der Operation opij+1

garan-tiert.

Die Ermittlung von Tilgungskosten je Operationsausfuhrung war dann sinnvoll, wenndiese wesentlich geringeren Schwankungen unterliegen, als es die realen Kosten tun. (For-mal gesehen sind ja auch die realen Kosten Tilgungskosten.) In unseren Beispielen werdendie Tilgungskosten je Operationsausfuhrung ein O (1) sein, so daß wegen Gleichung 11.21und der Tilgungsbedingung gemaß Gleichung 11.26 der Aufwand fur die Ausfuhrung derOperationenfolge aus Gleichung 11.22 ein O (ℓ) ist.

Um zu einer Verteilung der realen Kosten zu kommen, gibt es unter Verwendung derBezeichnungen aus den Gleichungen 11.23, 11.24 und 11.25 zwei Arten von Operationen:

– Die Operation opj heißt Ansparoperation, wenn

cj > cj

ist. Die hoheren Tilgungkosten werden auf die”hohe Kante“ gelegt.

– Die Operation opj heißt Konsumoperation, wenn

cj ≤ cj

ist. Die hoheren realen Kosten werden aus den angesparten Uberschussen der voran-gegangenen Ansparoperationen bezahlt.

Um die Uberschusse aus Ansparoperationen zu verwalten, ist ein Konto nicht schlecht,fur das aber wegen der allgegenwartigen Tilgungsbedingung aus Gleichung 11.26 keinerleiUberziehung gewahrt werden kann, wenn eine Konsumoperation ansteht.

11.2.3 Die Kontomethode

Wir verwenden die Bezeichnungen aus den Gleichungen 11.22, 11.23, 11.24 und 11.25. SeiK ein Konto, und sei

Kj := der Kontostand nach der Ausfuhrung von opij in der Folge aus Gl. 11.22.

Uber die gesamte Laufzeit der Ausfuhrung jeder zulassigen Operationenfolge (Gleichung11.22) mussen die folgenden Kontoklauseln erfullt sein:

175

Page 173: Skript Waack merged

Kontoeroffnungsbedingung. Man bekommt nichts geschenkt: Es ist

K0 = 0. (11.27)

Kontobewegungbedingung. Es geht alles uber das eine Konto, Schwarzgeldkonten sind nichterlaubt: Fur jedes j = 1, 2, . . . , ℓ ist

Kj = Kj−1 + (cj − cj) . (11.28)

Kontoabschlußbedingung. Man muß am Ende ein Plus gemacht haben: Es ist

Kℓ ≥ 0. (11.29)

Lemma 11.10 Fur jede zulassige Operationenfolge (11.22) folgt aus der Gultigkeit derKontoklauseln die Gultigkeit der Tilgungsbedingung gemaß Gleichung 11.26.

Beweis. Aus

0 ≤ Kℓ = Kℓ−1 + (cℓ − cℓ)

= Kℓ−2 + (cℓ + cℓ−1)− (cℓ + cℓ−1)

= . . .

= K0︸︷︷︸

=0

+

ℓ∑

j=1

cj −

ℓ∑

j=1

cj

folgt die Behauptung.

Nun sind wir in der Lage, die Laufzeitanalyse fur den modifizierten Stapel durch-zufuhren. Wir legen folgendes fest.

cadd := 2 cremove := cmultiremove := 0.

Die Kosten fur das Entfernen, gleichgultig ob vermoge der Operation remove oder vermogeder Operation multiremove, wird beim Hinzufugen bereits mitbezahlt und auf dem Konto

”gebunkert“. Wir erhalten.

Satz 11.11 Fur den modifizierten Stapel aus Abschnitt 11.2.1 ist der Zeitbedarf fur jedeFolge zulassiger Operationen der Lange ℓ ein O (ℓ).

176

Page 174: Skript Waack merged

11.2.4 Die Potentialmethode

Wir verwenden wiederum die Bezeichnungen aus den Gleichungen 11.22, 11.23, 11.24 und11.25.

Jeder Inkarnation D unserer Datenstruktur wird ein lokaler Kontostand, ein Potential

Φ(D) ∈ [0,∞),

zugeordnet. Die Zahl Φ(D) ist fur jede zulassige Folge von Operationen von D0 zu D eineuntere Schranke fur die Uberschusse aus den Ansparoperationen gegenuber den Konsum-operationen. Bei einer Konsumoperation mussen die Mehrkosten aus der Potentialdifferenzbezahlt werden konnen. Naturlich wird einem am Anfang nichts geschenkt, und es gibt auchkeine negativen Potentiale, also keine Schulden. Etwas formaler aufgeschrieben, mussen diefolgenden Potentialklauseln erfullt sein.

– Das Anfangspotential, das Potential von D0, ist null. Alle Potentiale sind nichtnega-tiv.

– Fur jede zulassige Folge von Operationen (11.22) gilt:

– Ist opij eine Ansparoperation, so ist

cj − cj ≥ Φ(Dj)− Φ(Dj−1). (11.30)

– Ist opij eine Konsumoperation, so ist

cj − cj ≤ Φ(Dj−1)− Φ(Dj). (11.31)

Wir bemerken, daß die Bedingung aus Gleichung 11.30 die Bedingung aus Gleichung 11.31miterfaßt. (Die Umkehrung ist ebenfalls richtig.) Fur jede Operation muß folglich gelten,daß die Differenz der Potentiale des Ziels und der Quelle die Differenz aus den Tilgungs-und den realen Kosten nach unten abschatzt.

Lemma 11.12 Fur jede zulassige Operationenfolge (11.22) folgt aus der Gultigkeit derPotentialklauseln die Gultigkeit der Tilgungsbedingung gemaß Gleichung 11.26.

Beweis. Wir betrachten eine Folge zulassiger Operationen gemaß (11.22). Es ist

cℓ − cℓ ≥ Φ(Dℓ)− Φ(Dℓ−1)

cℓ−1 − cℓ−1 ≥ Φ(Dℓ−1)− Φ(Dℓ−2)

. . . . . .

c1 − c1 ≥ Φ(D1)− Φ(D0)

177

Page 175: Skript Waack merged

Indem wir die vorstehenden Gleichungen aufaddieren, erhalten wir

ℓ∑

j=1

cj −ℓ∑

j=1

cj = Φ(Dℓ)︸ ︷︷ ︸

≥0

−Φ(D0)︸ ︷︷ ︸

=0

≥ 0.

Wir schließen die Laufzeitanalyse fur das offene Hashing mit Hilfe der Potentialmethodeab. Sei D eine Hashtabelle mit Bucketzahl m, Schlusselzahl n und Auslastungsfaktor α.Wir setzen

Φ(D) :=

|2n−m| falls m > m0;

2n−m falls m = m0 und α ≥ 12;

0 falls m = m0 und α < 12;

und

cdelete := cinsert := 3.

Um zu zeigen, daß die vorstehende Potentiale und Tilgungskosten zusammen mit denin Abschnitt 11.2.1 definierten realen Kosten die Potentialklauseln erfullen, uberlegen wiruns folgendes. Wir beschranken uns auf den Fall m > m0. Die Analyse fur m = m0 isteinfacher.

1. Ist α = 12, also n = m

2, so ist Φ(D) = 0.

2. Der unmittelbare Weg vom Auslastungsfaktor α = 12

zum Auslastungsfaktor α = 14

bei einer Bucketzahl m fuhrt uber genau m4delete-Operationen. Folglich muß man,

um auf diesem Weg vom Potential null auf das Potential m2

zu kommen, auf die realenKosten fur das Streichen einen Aufschlag von zwei erheben. Nun wird umgespeichert.Das verursacht reale Kosten von m

2. Danach ist das Potential null. Die Umspeicherung

ist vollstandig aus dem Potential bezahlt worden.

3. Um das Potential von m fur α = 1 von null fur α = 12

beginnend auf dem dafurungunstigsten Weg von m

2insert-Operationen

”ansparen“ zu konnen, muß man bei

den realen Kosten fur das Einfugen einen Aufschlag von zwei erheben. Nun wirdumgespeichert. Das verursacht reale Kosten von m. Danach ist das Potential null.Die Umspeicherung ist wiederum vollstandig aus dem Potential bezahlt worden.

Wir haben bewiesen.

Satz 11.13 Fur das offene Hashing aus Abschnitt 8.3.2 mit der Verdopplungsstrategie ausAbschnitt 8.3.4 ist der Zeitbedarf fur jede Folge zulassiger Operationen der Lange ℓ einO (ℓ).

178

Page 176: Skript Waack merged

Zum Abschluß dieses Abschnittes wollen wir analysieren, wieviele Bitoperationen dasAufwartszahlen in Einerschritten von null auf ℓ kostet. (Die Anzahl der Bitoperationen furdas Abwartszahlen ist die gleiche.)

Sei Dj (i = 1, 2, . . . , ℓ) der Zustand des binaren Zahlers (dessen Wert) nach der j-tenInkrementation. Der Anfangswert D0 ist gleich null.

Wir machen uns zunachst klar, wieviele Bitoperationen der Ubergang von Dj−1 nachDj kostet. Sei tj−1 die Anzahl der 1 am Ende (niederwertige Bits) der Binardarstellungvon Dj−1. Die Inkrementierung von Dj−1 bedarf cj = tj−1 +1 Operationen: Die ersten tj−1

Bits mussen auf null, das (tj−1 + 1)-te Bit auf eins gesetzt werden. Damit haben wir auchdie realen Kosten festgelegt: Sie sind dieses Mal dem Aufwand gleich.

Sei fur j = 1, 2, . . . , ℓ die Zahl bj die Haufigkeit des Vorkommens der Ziffer 1 in Dj . Wirdefinieren Φ(Dj) := bj . Da beim Ubergang von Dj−1 nach Dj die ersten tj−1 Bits zu nullund das tj−1 + 1-te Bit zu eins wird, gilt:

bj − bj−1 ≤ 1− tj−1 = 2− (tj−1 + 1)︸ ︷︷ ︸

=cj

.

Setzen wir die Tilgungskosten cj fur alle j = 1, 2, . . . , ℓ mit zwei an, so ist Ungleichung11.30 erfult. Die Gultigkeit der anderen Potentialklausel ist offensichtlich.

Wir haben den folgenden Satz bewiesen.

Satz 11.14 Fur das oben beschriebene binare Aufwartszahlen von 0 bis ℓ benotigt man 2 ·ℓRechenschritte. Dasselbe gilt fur das Abwartszahlen von ℓ bis 0.

11.2.5 Die Analyse der Union-Find-Datenstruktur

Nicht alle Probleme der Tilgungskostenanalyse lassen sich mit der Konto- oder mit derPotentialmethode losen. Ein Beispiel dafur ist die Laufzeitanalyse der effizienten Imple-mentation der Union-Find-Datenstruktur aus Abschnitt 10.4. Im folgenden verwenden wirdie Bezeichnungen aus diesem Abschnitt.

Die Situation. Wir nehmen an, daß n Objekte zu verwalten sind, die nach der Ausfuhrungvon n makeSet-Operationen als Einerblocke vorliegen. Letzteres sei die Datenstruktur D0.Nun werden m find- und n − 1 union-Operationen in beliebiger Reihenfolge ausgefuhrt,wobei m ≥ 2(n− 1) ist. Die Anzahl ℓ der Operationen ist in unserem Falle folglich gleichm + n− 1.

Wir identifizieren den Zustand Dj (j = 1, 2, . . . , ℓ) unserer Union-Find-Datenstrukturaus Gleichung 11.23 mit dem zu diesem Zeitpunkt vorliegenden Wald. Ferner sei Wj derin Definition 10.33 definierte unkomprimierte Wald, den man hatte, wenn man anstelleder find-Operation mit Pfadkompression nach Algorithmus 10.37 stets die einfache find-Operation nach Algorithmus 10.32 genommen hatte. Wir nennen deshalb Wj den virtuellenWald zum Zeitpunkt j.

Aus Bequemlichkeit wiederholen wir hier nochmals die Definition des iterierten Loga-rithmus aus Kapitel 1.

log∗2 n := minj ∈ N | ⌈log

(j)2 n⌉ = 1 (11.32)

179

Page 177: Skript Waack merged

Ist die Funktion durch die beiden Rekursionsgleichungen

g(0) = 1 (11.33)

g(ρ) = 2g(ρ−1) (ρ ≥ 1) (11.34)

definiert, so ist

log∗2 n =

0 falls n ≤ 1;

ρ falls ρ− 1 ≥ 0 und g(ρ− 1) < n ≤ g(ρ).(11.35)

Definition 11.15 Zu jedem Zeitpunkt j = 1, 2, . . . , ℓ sei der Rang eines Elementes x ∈ Vdie Hohe des Knotens x in Wj:

rankj x := heightWjx. (11.36)

Lemma 10.34 aus Kapitel 10 besagt dann fur jeden Zeitpunkt j = 1, 2, . . . , ℓ, daß

SIZEj x ≥ 2rankj x (11.37)

ist, wobei die Große SIZEj x des Knotens x zum Zeitpunkt j die Anzahl der Knoten desin x wurzelnden Teilbaumes von Wj ist.

Bemerkung. Wir lassen den Index j bei der Bezeichnung des Ranges und der Großeeines Knotens aus V in Zukunft gerne weg, wenn der betrachtete Zeitpunkt aus demZusammenhang klar ist.

Lemma 11.16 Zu jedem Zeitpunkt j = 1, 2, . . . , ℓ gibt es hochstens n2r viele Elemente aus

V mit dem Rang r.

Beweis. Sei Vj(r) ⊆ V die Menge derjenigen Elemente aus V , die zum Zeitpunkt j denRang r haben. Aus Ungleichung 11.37 folgt, daß es in allen Teilbaumen Tx von Wj mitx ∈ Vj(r) zusammen mindestens

|Vj(r)| 2r

viele Knoten gibt. Da diese Zahl durch die Zahl n aller Knoten nach oben beschrankt ist,folgt die Behauptung.

Bemerkungen.

• Jeder Knoten durchlauft fur j = 1, 2, . . . , ℓ eine Wurzelphase, in der er Wurzel einesTeilbaumes in Dj und Wj ist, die (bis auf einen Knoten) von der Nachwurzelphase(nach Anwendung einer entsprechenden union-Operation) gefolgt wird.

• In der Wurzelphase kann der Rang eines Elementes anwachsen. Mit Beginn der Nach-wurzelphase bleibt er konstant.

180

Page 178: Skript Waack merged

Lemma 11.17 Zu jedem Zeitpunkt j = 1, 2, . . . , ℓ gilt: Ist Knoten x Sohn von Knoten yin Dj, so ist rank y > rank x.

Beweis. Vorbemerkung. Eine analoge Aussage ist nach Definition des Ranges fur denvirtuellen Wald Wj offensichtlich.

Fur den Beweis der Aussage des Lemmas genugt es wegen der dem Lemma vorange-gangenen Bemerkungen, den Zeitpunkt j0 ins Auge zu fassen, zu dem Knoten x zum Sohnvon Knoten y wird. Wir mussen zwei Falle unterscheiden.

Fall 1. Knoten x wird zum Sohn von Knoten y durch eine union-Operation. Dann istaber Knoten x auch im virtuellen Wald Wj0 Sohn von Knoten y. Die Vorbemerkung istanwendbar.

Fall 2. Knoten x wird zum Sohn von Knoten y durch eine Pfadkompression. Dann istKnoten x im virtuellen Wald Wj0 Nachfahre von Knoten y. Die Vorbemerkung ist wiederumanwendbar.

Definition 11.18 Zu jedem Zeitpunkt j = 1, 2, . . . , ℓ gehort jeder Knoten x ∈ V zurRanggruppe log∗

2(rankx). Die Zahl log∗2(rankx) heißt der Ranggruppenindex des Elements

x.

Lemma 11.19 Fur jeden Zeitpunkt j = 1, 2, . . . , ℓ gilt:

1. Nur die Ranggruppen mit Indizes von 0 bis log∗2 n− 1 konnen nichtleer sein.

2. Fur jeden Ranggruppenindex ρ ∈ [0, log∗2 n− 1] ist

N(ρ) := |x |Knoten x gehort zur Ranggruppe mit dem Index ρ| ≤n

g(ρ), (11.38)

wobei die Funktion g durch die durch die Gleichungen 11.33 und 11.34 gegebeneRekursion definiert ist.

Beweis. Wir fixieren einen Zeitpunkt j ∈ 1, 2, . . . , ℓ.Beweis von Behauptung 1. Zur Ranggruppe null gehoren Elemente mit den Rangen null

und eins. Wegen Ungleichung 11.37 ist fur jedes x ∈ V

log2 n ≥ rank x.

Folglich ist der Ranggruppenindex von Element x durch

log∗2(log2 n) ≤ log∗

2 n − 1

nach oben beschrankt (siehe Gleichung 11.32).Beweis von Behauptung 2. Fur den Ranggruppenindex ρ = 0 ist g(ρ) = 1 und Unglei-

chung 11.38 folglich trivial.

181

Page 179: Skript Waack merged

Fur ρ > 0 haben nach Gleichung 11.35 die Range r mit

g(ρ− 1) + 1 ≤ r ≤ g(ρ)

den Ranggruppenindex ρ. Nach Lemma 11.16 haben hochstens n2r Elemente den Rang r.

Folglich gehoren hochstens∑g(ρ)

r=g(ρ−1)+1n2r Elemente zur Ranggruppe ρ. Es ist

g(ρ)∑

r=g(ρ−1)+1

n

2r<

n

2g(ρ−1)+1·

∞∑

i=0

1

2i

=2 · n

2g(ρ−1)+1=

n

g(ρ).

Nun kommen wir zum

Beweis von Satz 10.38. Es genugt, den Zeitbedarf der m find-Operationen mit Pfad-kompression durch O (m · log∗

2 n) abzuschatzen, da jede einzelne union-Operation offen-sichtlich nur konstanten Zeitbedarf hat.

Wird find(x) zum Zeitpunkt j + 1 ausgefuhrt, so sei

x = x0, x1, . . . , xt−1, xt (11.39)

der Weg von x zur Wurzel xt des Baumes aus Dj , zu dem x gehort. Wir setzen die realenKosten mit t + 1 an und ordnen jede Kosteneinheit einem Knoten des Weges von x zurWurzel xt fest zu. Nach Eigenschaften des Tragerknotens y klassifizieren wir die Kostenwie folgt.

Grenzzoll. Es ist y ∈ xt, xt−1 oder y = xi fur ein i < t − 1 so, daß die Ranggruppe desVaters von y großer ist als die Ranggruppe von y.

Wegezoll. Es ist y = xi fur ein i < t − 1 so, daß die Ranggruppe des Vaters von y gleichder Ranggruppe von y ist.

Zunachst schatzen wir den Grenzzoll fur die in Rede stehende find(x)-Operation ab.Es gibt nach Lemma 11.19, Behauptung 1 log∗2 n − 1 nichttriviale Ranggruppenindizes,also auf dem Weg (11.39) hochstens log∗

2 n− 2 Ranggruppenubergange. Da fur xt und xt−1

ebenfalls Grenzzoll fallig wird, ist dieser fur die Operation find(x) durch log∗2 n nach oben

beschrankt.Da es m find-Operationen gibt, ist der Gesamtgrenzzoll ein O (m · log∗

2 n).

Wir schatzen den Gesamtwegezoll, der fur einen festen Knoten y uber die gesamte Lauf-zeit fallig wird, nach oben ab. Wegezoll fallt fur den Knoten y nach Definition nur in seinerNachwurzelzeit an. Folglich sind Rang r und Ranggruppe ρ von y zu jedem Zeitpunkt, zudem fur y Wegezoll erhoben wird, gleich. Da der Knoten y unmittelbar vor einer Wegezoll-Erhebung definitionsgemaß auch nicht Sohn einer Wurzel ist, wachst nach Lemma 11.17

182

Page 180: Skript Waack merged

nach jeder solchen Erhebung der Rang des Vaters von y an, da es sich dabei nunmehr umdie Wurzel handelt. Wie oft kann es zu einer Vergroßerung des Ranges des Vaters von ykommen? Nur so oft, bis daß der Vater von Knoten y in einer hoheren Ranggruppe liegtals y selbst. (Danach kann fur y nur noch Grenzzoll anfallen.) Nun haben nach Gleichung11.35 hochstens g(ρ) von r verschiedene Range denselben Ranggruppenindex ρ wie derKnoten y. Folglich konnen fur den Knoten y uber die gesamte Laufzeit nur hochstens g(ρ)Wegezolleinheiten erhoben werden. Spatestens dann muß der Vater von y die Ranggruppevon y verlassen haben.

Ist N(ρ) die Anzahl der Elemente der Ranggruppe ρ mit ρ ∈ [0, log∗2 n−1] zum Zeitpunktℓ – spatestens dann hat jeder Knoten, fur den jemals uber die Gesamtlaufzeit Wegezollerhoben wird, die Ranggruppe seiner Nachwurzelzeit erreicht –, so ist die Gesamtzahl derWegezolleinheiten durch

∑log∗2 n−1ρ=0 N(ρ)g(ρ) nach oben beschrankt. Nach Lemma 11.19 ist

log∗2 n−1∑

ρ=0

N(ρ)g(ρ) ≤ n ·

log∗2 n−1∑

ρ=0

1

= n · log∗2 n.

Wegen m ≥ 2(n− 1) ist der Gesamtwegezoll ein O (m · log∗2 n).

11.3 Kombinatorische Optimierungsprobleme

Bereits im Abschnitt 6.1 haben wir das Rucksackoptimierungsproblem eingefuhrt. Wirwiederholen seine Spezifikation hier.

Problem 3 (Maximierungsproblem MaxKNAPSACK)

Zulassige Eingaben sind Folgen naturlicher Zahlen

I := (w1, w2, . . . , wn, c1, c2, . . . , cn, W ) ∈ N2n+1

in kanonischer binarer Darstellung. Die Problemgroße von I ist im

Einheitskostenmaß 2n + 1;

logarithmischen Kostenmaß |I| :=∑n

i=1 | bin ci| +∑n

i=1 | binwi| + | bin W |.

Zulassige Losungen sind alle Booleschen Vektoren β = (β1, β2, . . . , βn) aus 0, 1n, dieder Bedingung

n∑

i=1

βiwi ≤W (11.40)

genugen.

183

Page 181: Skript Waack merged

Bewertungsfunktion:

Val(I, β) :=n∑

i=1

βici (11.41)

Optimierungsziel: Suche eine zulassige Losung β von I so, daß Val(I, β) maximiert wird.

Die lebenserfahrene Leserin weiß es: Es gibt Menschen, die der”Tonnenideologie“

fronen. Fur diese ist die folgende vereinfachende Variante von MaxKNAPSACK das rich-tige.

Problem 4 (Maximierungsproblem MaxSimpleKNAPSACK)

Zulassige Eingaben sind Folgen naturlicher Zahlen

I := (w1, w2, . . . , wn, W ) ∈ Nn+1

in kanonischer binarer Darstellung.

Die Problemgroße von I ist im

Einheitskostenmaß n + 1;

logarithmischen Kostenmaß |I| :=∑n

i=1 | bin wi| + | binW |.

Zulassige Losungen sind alle Booleschen Vektoren β = (β1, β2, . . . , βn) aus 0, 1n, dieder Bedingung

n∑

i=1

βiwi ≤W

genugen.

Bewertungsfunktion:

Val(I, β) :=

n∑

i=1

βiwi

Optimierungsziel: Suche eine zulassige Losung β von I so, daß Val(I, β) maximiert wird.

Bemerkung. Der Hauptunterschied des Einheitskostenmaßes zum logarithmischen Ko-stenmaß bei der Bestimmung der Problemgroße besteht in der Annahme, daß Zahlen Ko-sten eins verursachen (siehe Abschnitt 12.5.2). Dieser Annahme liegt die meist stillschwei-gende Voraussetzung zu Grunde, daß ihre Darstellung innerhalb der Verarbeitungsbreiteliegt.

Allgemein besteht ein kombinatorisches Optimierungsproblem Π aus

184

Page 182: Skript Waack merged

– einer Menge von zulassigen Eingaben Input Π, die naturlich uber dem Alphabet 0, 1codiert sind;

– zu jeder zulassigen Eingabe I aus einer endlichen Menge Sol I ⊆ 0, 1+ zulassigerLosungen;

– einer Funktion Val(I, s), der Bewertungs- oder Zielfunktion, die jedem Paar bestehendaus einer zulassigen Eingabe I ∈ Input Π und einer zulassigen Losung s ∈ Sol I einenaturliche Zahl zuordnet.

Die Laufzeit wird grundsatzlich in der binaren Lange |I| der Eingabe gemessen.

Die Bestandteile mussen die folgenden Bedingungen erfullen:

– Man muß in Polynomialzeit testen konnen, ob eine Zeichenkette uber 0, 1∗ einezulassige Eingabe verschlusselt:

Input Π ∈ P.

– Die Relation

AdmRelΠ = (I, s) | I ∈ Input Π, s ∈ Sol I

ist eine Polynomialzeitrelation.

– Fur jedes Argument (I, s) ist der Funktionswert Val(I, s) in Polynomialzeit berechen-bar.

Erstes Ziel der algorithmischen Behandlung eine kombinatorischen Optimierungspro-blems Π ist fur jede zulassige Eingabe I die Berechnung eines sopt ∈ OptSol I, wobeiOptSol I diejenige Teilmenge zulassiger Losungen aus Sol I ist, fur die Val(I, s) bei fe-stem I je nach Problemstellung maximiert oder minimiert wird. Wir sprechen von einemMaximierungs- bzw. Minimierungsproblem. In beiden Fallen bezeichnen wir mit

Opt I := Val(I, sopt) (fur ein sopt ∈ OptSol I)

den Wert einer optimalen Losung auf die Eingabe I.

Nun kann es sein, daß sich ein kombinatorisches Optimierungsproblem einer effizientenexakten Losung hartnackig widersetzt. Dann sind wir vielleicht mit einer approximativenLosung dieses Problems zufrieden.

Definition 11.20 Sei Π ein kombinatorisches Optimierungsproblem.Ein Polynomialzeitalgorithmus A, der zu jeder zulassigen Eingabe I ∈ Π eine zulassige

Losung A(I) ∈ Sol I berechnet, heißt polynomialer Approximationsalgorithmus (PTA) furdas Problem Π.

185

Page 183: Skript Waack merged

Definition 11.21 Die Gute Γ(I, A(I)) eines PTA A fur eine zulassige Eingabe I eineskombinatorischen Optimierungsproblems ist ein Maß dafur, wie weit der Wert der von Aauf I berechneten Losung vom Optimum fur I abweicht:

Γ(I, A(I)) :=

Opt I

Val(I,A(I))falls Π eine Maximierungsproblem ist;

Val(I,A(I))Opt I

falls Π eine Minimierungsproblem ist.

11.4 Dynamische Programmierung

Wie im Abschnitt 11.1 wird bei der Berechnung einer Losung eines Optimierungsproblemsvermoge dynamischer Programmierung auf Losungen von Teilproblemen zuruckgegriffen.Im Gegensatz zu rekursiven Algorithmen wird uber die Losungen der Teilprobleme in einerTabelle buchgefuhrt.

Wir machen uns die Technik des dynamischen Programmierens am Beispiel des Rucksack-Optimierungsproblems MaxKNAPSACK klar.

11.4.1 Identifikation einer geeigneten Teilproblemstruktur

Sei

I := (w1, w2, . . . , wn, c1, c2, . . . , cn, W ) ∈ N2n+1

eine zulassige Eingabe des Problems 3, wobei wir unterstellen, daß alle Gegenstande einpositives Gewicht haben. Fur k = 0, 1, . . . , n und V = 0, 1, . . . , W definieren wir dasTeilproblem

I(k, V ) := (w1, w2, . . . , wk, c1, c2, . . . , ck, V ) (11.42)

und ein (n + 1)× (W + 1)-Feld

Opt := (Opt[k, V ]) k=0,1,...,nV =0,1,...,W

, (11.43)

wobei Opt[k, V ] fur den Wert einer optimalen Losung des Teilproblems I(k, V ) vorgesehenist.

11.4.2 Optimalitatsgleichungen

Nun muß gezeigt werden, wie man die Tabelle (11.43) fur die Teilprobleme (11.42) ausfullt.Dazu dienen die sogenannten Optimalitatsgleichungen.

Sicherlich kann man aus null Gegenstanden keinerlei Gewinn erzielen. Dasselbe gilt,wenn man keine Gegenstande in den Rucksack legen darf:

Opt[k, 0] = 0 (k ∈ [0, n]) (11.44)

Opt[0, V ] = 0 (V ∈ [1, W ]) (11.45)

186

Page 184: Skript Waack merged

Fur eine optimale Losung des Problems I(k, V ) (k · V > 0) gibt es zwei Moglichkeiten:Sie umfaßt den Gegenstand k, oder das ist nicht der Fall. Der erste Fall ist naturlich nurmoglich, wenn V ≥ wk ist. Wir erhalten:

Opt[k, V ] =

maxOpt[k − 1, V ], Opt[k − 1, V − wk] + ck falls V ≥ wk;

Opt[k − 1, V ] andernfalls.(11.46)

11.4.3 Backtracing

Liegt die Tabelle 11.43 ausgefullt vor, kann man daraus eine optimale Losung berechnen.Dazu dient ein Boolscher Vektor β der Lange n, der mit dem Nullvektor initialisiert ist.Er wird mit fallendem Feldindex ausgefullt. Wir verfahren nach dem Sparsamkeitsprinzipund legen einen Gegenstand nur in den Rucksack, wenn es nicht anders geht. Haben wirfur die Gegenstande n, . . . , k + 1 bereits entschieden, ob sie in den Rucksack mussen, undsteht die Entscheidung uber den Gegenstand k an, so ist

V = W −k+1∑

j=n

βjwj (11.47)

das noch verfugbare Restgewicht. Ist

Opt[k, V ] > Opt[k − 1, V ], (11.48)

so muß der Gegenstand k in den Rucksack, denn anderfalls bekamen wir keine optimaleLosung:

βk =

1 falls Ungleichung 11.48 erfullt ist;

0 sonst.(11.49)

11.4.4 Algorithmus

Wir fassen unsere Erkenntnisse aus den Abschnitten 11.4.1, 11.4.2 und 11.4.3 in dem fol-genden Algorithmus fur das Problem 3 zusammen.

Algorithmus 11.22 (Dynamische Programmierung fur MaxKNAPSACK)

Eingabe: Problemstellung I := (w1, w2, . . . , wn, c1, c2, . . . , cn, W ) des Problems 3.Großschritt 1.

Erzeuge Opt[0 . . . , n, 0 . . . , W ].Initialisiere Opt gemaß (11.44) und (11.45).β ← (0, 0, . . . , 0)

Großschritt 2:

187

Page 185: Skript Waack merged

Fur k = 1, 2, . . . , n fuhre aus.Fur V = 1, 2, . . . , W fuhre aus.

Falls V ≥ wk, som← Opt[k − 1, V − wk] + ck

Andernfallsm← 0.

Opt[k, V ]← maxOpt[k − 1, V ], mGroßschritt 3.

V ←WFur k = n, n− 1, . . . , 1 fuhre aus.

Falls Opt[k, V ] > Opt[k − 1, V ], soβk ← 1V ← V − wk.

Ausgabe: β.

Wir erhalten:

Satz 11.23 Algorithmus 11.22 arbeitet korrekt. Seine Laufzeit im Einheitskostenmaß istfur jede Eingabe ein O (n ·W ), wobei n die Anzahl der Gegenstande und W das zulassigeGesamtgewicht des Rucksacks ist.

11.5 Greedy-Algorithmen

Greedy-Algorithmen versichern sich grundsatzlich der”dicksten Brocken“ zuerst. Im Fal-

le des Rucksack-Optimierungsproblems MaxKNAPSACK bedeutet das, die Gegenstandezuerst nach ihrer

”Nutzendichte“ fallend zu sortieren, um dann zu versuchen, sie in dieser

Reihenfolge in den Rucksack zu legen.

Algorithmus 11.24 (PTA SimpleGreedyKnapsack fur MaxKNAPSACK)

Eingabe: Problemstellung I := (w1, w2, . . . , wn, c1, c2, . . . , cn, W ) des Problems 3.Großschritt 1.

Numeriere die n Gegenstande so um, daß danachc1w1≥ c2

w2≥ . . . ≥ cn

wn

gilt.Großschritt 2: Initialisierung.

R←W (Restgewicht)i← 0 (Index des letzten visitierten Gegenstandes)β ← (0, 0, . . . , 0) (Befullung des Rucksacks)

Großschritt 3.Solange (R > 0 und i < n) fuhre aus.

i← i + 1Falls wi ≤ R, so

188

Page 186: Skript Waack merged

βi ← 1R← R− wi.

Ausgabe: β.

Die Laufzeit von Algorithmus 11.24 ist mit O (n log n), wobei n die Anzahl der Ge-genstande ist, sicherlich gut. Seine Gute dagegen ist, naturlich nur fur sehr ungunstigeEingaben In (n ∈ N), beliebig schlecht:

Das zulassige Gesamtgewicht sei W = 2n. Ferner seien

c1 = 1 c2 = W − 1 c3 = 1 . . . . . . cn = 1

w1 = 1 w2 = W w3 = 2 . . . . . . wn = 2

Man erkennt leicht, daß Algorithmus 11.24 auf In die Befullung (1, 0, 1, . . . , 1) mit demNutzen n − 1 und dem Gewicht 2n − 3 ausgibt. Optimal ist die Befullung (0, 1, 0, . . . , 0)mit dem Nutzen W − 1 und dem Gewicht W . Folglich ist die Gute von Algorithmus 11.24auf In gleich

Γ(In, SimpleGreedyKnapsack(In)) =W − 1

n− 1=

2n − 1

n− 1.

Wir sehen, daß fur n → ∞ die Gute Γ(In, SimpleGreedyKnapsack(In)) mit hoher Rategegen unendlich geht.

Ursachlich dafur, daß Algorithmus 11.24 auf den vorstehend definierten Eingaben In

schwachelt, ist die Unteilbarkeit der Gegenstande. Wir wollen das genauer untersuchen undbetrachten eine Variante des Rucksack-Optimierungsproblems, bei dem die Gegenstandebeliebig teilbar sind.

Problem 5 (Maximierungsproblem FractionalKNAPSACK)

Zulassige Eingaben sind Folgen naturlicher Zahlen

I := (w1, w2, . . . , wn, c1, c2, . . . , cn, W ) ∈ N2n+1

in kanonischer binarer Darstellung. Die Problemgroße von I ist im

Einheitskostenmaß 2n + 1;

logarithmischen Kostenmaß |I| :=∑n

i=1 | bin ci| +∑n

i=1 | binwi| + | bin W |.

Zulassige Losungen sind alle Booleschen Vektoren β = (β1, β2, . . . , βn) aus [0, 1]n, dieder Bedingung

n∑

i=1

βiwi ≤W (11.50)

genugen.

189

Page 187: Skript Waack merged

Bewertungsfunktion:

Val(I, β) :=

n∑

i=1

βici (11.51)

Optimierungsziel: Suche eine zulassige Losung β von I so, daß Val(I, β) maximiert wird.

Wir passen Algorithmus 11.24 an die Besonderheiten des Problems 5 an und erhaltenden folgenden Algorithmus.

Algorithmus 11.25 (GreedyFractionalKnapsack fur FractionalKNAPSACK)

Eingabe: Problemstellung I := (w1, w2, . . . , wn, c1, c2, . . . , cn, W ) des Problems 5.Großschritt 1.

Numeriere die n Gegenstande so um, daß danachc1w1≥ c2

w2≥ . . . ≥ cn

wn

gilt.Großschritt 2: Initialisierung.

R←W (Restgewicht)i← 0 (Index des letzten visitierten Gegenstandes)β ← (0, 0, . . . , 0) (Befullung des Rucksacks)

Großschritt 3.Solange (R > 0 und i < n) fuhre aus.

i← i + 1Falls wi ≤ R, so

βi ← 1R← R− wi.

Andernfallsβi ←

Rwi

R← 0.Ausgabe: β.

Da man im Falle des Problems 5 die Gegenstande beliebig teilen kann, besteht die op-timale Strategie offensichtlich darin, niemals etwas von einem Gegenstand von geringererNutzenhaltigkeit einzupacken, wenn noch etwas von einem Gegenstand von hoherer Nut-zenhaltigkeit vorhanden ist. Folglich berechnet Algorithmus 11.25 fur das Problem 5 stetseine optimale Losung. Diese ist eindeutig bestimmt und sieht unter der Voraussetzung, daßfur die Gegenstande c1

w1≥ c2

w2≥ . . . ≥ cn

wngilt, so aus

βopt = (1, . . . , 1, βi0, 0, . . . , 0),

wobei i0 der letzte Gegenstand ist, von dem noch ein Teil in den Rucksack paßt. Die Zahlβ0 ∈ (0, 1] gibt diesen Teil bezogen auf das Gewicht wi0 an.

190

Page 188: Skript Waack merged

Bemerkung. Der Nutzen dieser optimalen Losung des Problems 5 ist eine obere Schrankefur den Nutzen einer optimalen Losung des Problems 3.

Zum Abschluß dieses Abschnittes entwerfen wir einen von einem zusatzlichen ganz-zahligen Parameter k abhangenden Algorithmus BasisGreedyKnapsackk, der das Optimie-rungsproblem MaxSimpleKNAPSACK(Problem 4) mit einer Gute kleiner als 1+ 1

kin Zeit

O(nk+1

)lost. Die Idee ist einfach. Ausgehend von allen denkbaren Anfangsbefullungen

unseres Rucksacks mit hochstens k Gegenstanden wird Algorithmus 11.24 angewendet.Eine beste Losung, auf die man dabei stoßt, wird ausgegeben.

Die”Algorithmenschar“ BasisGreedyKnapsackk (k ∈ N) ist ein Beispiel fur ein poly-

nomiales Approximationsschema (PTAS) Ak (k ∈ N): Der Algorithmus Ak muß auf jedezulassige Eingabe I in Laufzeit |I|O(1) eine Ausgabe der Gute kleiner oder gleich 1 + 1

k

liefern (siehe Abschnitt 16.1 fur eine Klassifikation der Approximationsalgorithmen nachdem asymtotischen Verhalten ihrer Gute).

Algorithmus 11.26 (PTAS BasisGreedyKnapsackk fur MaxSimpleKNAPSACK)

Eingabe: Problemstellung I := (w1, w2, . . . , wn, W ) des Problems 4.Großschritt 1.

Numeriere die n Gegenstande so um, daß danachw1 ≥ w2 ≥ . . . ≥ wn

gilt.Großschritt 2: Initialisierung.

opt← 0 (Wert der besten bisherigen Befullung des Rucksacks)β ← (0, 0, . . . , 0) (beste bisherige Befullung des Rucksacks)Erzeuge ein

Feld τ[

1 . . .∑k

ν=1

(nν

)]

von Booleschen Vektoren der Lange n;

Feld γ[

1 . . .∑k

ν=1

(nν

)]

von naturlichen Zahlen

und initialisiere diese Felder wie folgt:

τ[

1 . . .∑k

ν=1

(nν

)]

halt alle Teilmengen von 1, . . . , n

mit hochstens k Elementen als charakteristische Vektoren.

Fur alle j = 1, 2, . . . ,∑k

ν=1

(nν

)ist

γ[j] =∑n

i=1 τ [j]iwi.Großschritt 3.

Fur j = 1, 2, . . . ,∑k

ν=1

(nν

)fuhre aus.

R←W − γ[j]i← 0.Solange (R > 0 und i < n) fuhre aus.

i← i + 1Falls wi ≤ R und τ [j]i = 0, so

τ [j]i ← 1

191

Page 189: Skript Waack merged

R← R− wi

γ[j]← γ[j] + wi.Falls γ[j] > opt, so fuhre aus.

opt← γ[j]β ← τ [j].

Ausgabe: β.

Satz 11.27 Algorithmus 11.26 hat fur jede zulassige Eingabe I mit n Gegenstanden eineLaufzeit von O

(nk+1

)und eine durch 1 + 1

knach oben beschrankte Gute.

Beweis.

Schritt 1. Die Großen der Felder τ und γ sind nach Satz 2.2 ein

k∑

ν=1

(n

ν

)

≤(e · n

k

)k

= O(nk).

Eine Inspektion des Pseudocodes ergibt, daß in Großschritt 3 je Feldeintrag eine durchO (n) beschrankte Rechenzeit anfallt. Folglich hat Großschritt 3 einen Zeitbedarf vonO(nk+1

), der den der anderen Schritte dominiert.

Schritt 2. Wir beweisen die folgende Hilfsaussage. Ist r1 ≥ r2 ≥ . . . ≥ rm ≥ 0, und istr =

∑mi=1 ri, so gilt fur alle i = 1, 2, . . . , m die Ungleichung r

i≥ ri.

Angenommen, das Gegenteil ware richtig. Dann gabe es einen Index i ∈ 1, 2, . . . , mmit r

i< ri. Dann ware aber bereits die Summe der ersten i Zahlen großer als r. Das

steht im Widerspruch dazu, daß die Summe aller m Zahlen gleich r ist.

Schritt 3. Sei I = (w1, w2, . . . , wn, W ) eine Eingabe des Problems 4.

Fall 1. Es existiert eine optimale Losung, die der Algorithmus BasisGreedyKnapsackk

erreicht. Dann gilt

Γ(I, BasisGreedyKnapsackk(I)) = 1.

Fall 2. Fall 1 tritt nicht ein. Sei

βopt = i1 < i2 < . . . < ip

eine optimale Losung. Da BasisGreedyKnapsackk diese Losung wahrend seiner Rech-nung auf I nie erreicht, ist p > k. Startet BasisGreedyKnapsackk von der Anfangs-befullung

β0 := i1 < i2 < . . . < ik

seine Greedy-Strategie, so berechnet er die Losung

β1 ⊃ β0,

192

Page 190: Skript Waack merged

die er anschließend mit der bisher ermittelten besten Losung vergleicht.

Da βopt 6⊆ β1 ist, gibt es einen Index q mit k + 1 ≤ q ≤ p, so daß iq 6∈ β1 ist.

Warum gelingt es BasisGreedyKnapsackk nicht, den Gegenstand iq in den Rucksack zulegen? Er paßt zu dem Zeitpunkt der Entscheidung daruber nicht mehr hinein. Darausfolgt

Val(I, β1) + wiq > W ≥ Opt I.

Da die zulassige Losung β1 nicht besser sein kann als diejenige Losung, die Algorithmus11.26 auf die Eingabe I letztendlich ausgibt, ist

Val(I, BasisGreedyKnapsackk(I)) + wiq > Opt I.

Unter Verwendung von

Opt I =

p∑

j=1

wij

und von

wi1 ≥ . . . ≥ wiq ≥ . . . ≥ wip

folgt aus der in Schritt 2 bewiesenen Hilfsaussage

Opt I

k + 1≥

Opt I

q≥ wiq .

Wir erhalten

Val(I, BasisGreedyKnapsackk(I)) +Opt I

k + 1> Opt I,

woraus die Behauptung folgt.

11.6 Backtracking

Wir beziehen uns in diesem Abschnitt auf ein Maximierungsproblem Π, wie wir es inAbschnitt 11.3 definiert haben. Es wird stets eine optimale Losung berechnet, aber zurBeschrankung der Laufzeit sind zusatzliche Annahmen in Bezug auf die Struktur des Pro-blems notwendig. Diese sind jedoch so allgemein, daß sie fast immer erfullt sind. Allerdingsergibt sich fur viele interessante Probleme nicht fur jede Eingabe ein bedeutender Lauf-zeitvorteil: Sie bleibt im schlechtesten Fall exponentiell.

193

Page 191: Skript Waack merged

11.6.1 Backtrack-Baum. Generischer Algorithmus

Die allgemeine Situation

Sei n ∈ N eine naturliche Zahl, und seien

M1 = a1 < a2 < . . . < aα

M2 = b1 < b2 < . . . < bβ

. . . . . .

Mn = z1 < z2 < . . . < zω

total geordnete endliche Menge derart, daß fur jede zulassige Eingabe I ∈ Input Π der

”Große“ n

Sol I ⊆M(n) := M1 ×M2 × . . .×Mn

ist. Wie wir aus Abschnitt 11.3 wissen, muß die Menge Sol I durch einen Polynomialzeit-algorithmus in M(n) identifizierbar sein sein.

Bemerkung. Der Parameter n ist nicht die binare Lange von |I|. Haufig steht er inpolynomieller Relation zur Problemgroße von I im Einheitskostenmaß (siehe Abschnitt12.5.2).

Der Backtrack-Baum zu Eingaben der Große n des Problems Π ist ein gerichtetergeordneter Wurzelbaum (siehe Abschnitt 1.5.2), der wie folgt definiert ist.

– Die Menge seiner Knoten ist gleich

V = ∪n⋃

r=1

M1 × . . .×Mr.

– Die Wurzel ist mit jedem Knoten aus M1 durch eine Kante verbunden.

– Fur jedes r = 1, 2, . . . , n− 1 ist jeder Knoten (m1, . . . , mr) ∈M1× . . .×Mr fur jedesmr+1 ∈ Mr+1 mit (m1, . . . , mr, mr+1) ∈ M1 × . . . × Mr × Mr+1 durch eine Kanteverbunden.

– Fur r = 1, 2, . . . , n − 1 ergibt sich die Anordnung der Sohne (m1, . . . , mr, mr+1)(mr+1 ∈ Mr+1) des Knotens (m1, . . . , mr) kanonisch aus der Ordnung der Elementeder Menge der Mr+1.

– Die Blatter des Backtrack-Baumes sind alle Elemente aus M1 × . . .×Mn.

Jeder Weg im Backtrack-Baum von der Wurzel zu einem Blatt entspricht fur jedeEingabe I der Große n umkehrbar eindeutig dem Aufbau einer potentiellen Losung fur Ivon links nach rechts. Ob diese Losung auch zulassig ist, hangt von der aktuellen EingabeI ab.

194

Page 192: Skript Waack merged

Auf der Suche nach einer optimalen Losung durchlaufen wir die Knoten des Back-trackbaumes zur Problemgroße n in Vorordnung (siehe Definition 1.37). Der Trick zurBeschrankung der Laufzeit besteht darin, fur moglichst viele Knoten u, die kein Blatt sind,nach der Inspektion von u den in u wurzelnden Teilbaum Tu zu entfernen. Dazu gibt eszwei Grunde:

1. Kein Blatt des Baumes Tu ist eine zulassige Losung.

2. Der Baum Tu hat zwar Blatter, die zulassigen Losungen entsprechen, aber die zu-gehorigen Werte liegen unterhalb einer uns zu diesem Zeitpunkt bereits bekanntenunteren Schranke fur die optimale Losung.

Um diese Idee umzusetzen, betten wir unsere Algorithmen in eine Rahmenklasse ein,die neben Datenfeldern, welche die aktuelle Eingabe I der Große n und die Mengen Mr

(r = 1, 2, . . . , n) geeignet halten, zusatzlich

– ein Datenfeld optSol fur die beste bisher erreichte zulassige Losung von I, die jaBlattern des Backtrack-Baumes entsprechen, und

– ein Datenfeld globalLower fur eine untere Schranke fur Opt I

hat.Wie wir im weiteren (siehe Algorithmus 11.31, vorletzte Zeile) sehen werden, kann es

Zeitpunkte zur Laufzeit geben, zu denen der Wert Val von optSol bezogen auf die aktuelleEingabe I kleiner als der Wert von globalLower ist.

Das Abschneiden von Teilbaumen besorgt eine Methode pruning, die wir zunachst nurspezifizieren wollen:

Algorithmus 11.28 (Spezifikation des Abschneidens von Teilbaumen)

Methodenkopf:pruning(m1, . . . , mr) returns Boolean

Vorbedingung:u = (m1, . . . , mr) ist ein Knoten aber kein Blatt des Backtrack-Baumes

zur aktuellen Eingabe I der Große n.Nachbedingung:

Wird true zuruckgegeben, so gilt fur alle mr+1 ∈Mr+1, . . . , mn ∈Mn:- Es ist (m1, . . . , mr, mr+1, . . . , mn) 6∈ Sol I, oder- falls v = (m1, . . . , mr, mr+1, . . . , mn) zulassig ist, so ist

Val(I, v) < globalLower.

Das Backtracking laßt sich nun besonders kompakt als rekusiver Algorithmus schreiben:

Algorithmus 11.29 (Generischer Backtracking-Algorithmus)

195

Page 193: Skript Waack merged

Methodenkopf:backtracking(u)

Vorbedingung:u ist ein Knoten des Backtrack-Baumes

zur aktuellen Eingabe I der Große n.Großschritt 1.

Falls u Blatt ist, und Val(I, u) ≥ globalLower gilt, so fuhre aus.optSol← uglobalLower ← Val(I, u)return.

Großschritt 2.Ist u = (m1, . . . , mr) kein Blatt, und ist pruning(u) = false, so

fuhre fur alle mr+1 ∈Mr+1 den rekursiven Aufrufbacktracking(m1, . . . , mr, mr+1)

aus.

Die Suche insgesamt wird durch den Aufruf backtracking( ) des Algorithmus 11.29gestartet. Es ist eine leichte Ubungsaufgabe zu zeigen, daß nach seinem Ende das DatenfeldoptSol eine optimale Losung halt, sofern es uberhaupt eine zulassige Losung gibt.

MaxKNAPSACK als Beispiel

Der Parameter n ist die Anzahl der Gegenstande, die in einen Rucksack gelegt werdenkonnen. Fur jede Eingabe

I = (w1, w2, . . . , wn, c1, c2, . . . , cn, W )

des Problems 3 der Große n ist

M1 = M2 = . . . = Mn = 0 < 1.

11.6.2 Beschneidung des Backtrack-Baumes I

In diesem Abschnitt geht es darum, Teilbaume des Backtrack-Baumes zu entfernen, derenBlatter unzulassig sind.

Die allgemeine Situation

Fur jede Eingabe I ∈ Input Π der Große n gibt es ein effizient berechenbares Pradikat PI

auf der Menge der Knoten des zu n gehorigen Backtrack-Baumes so, daß

|= PI(m1, m2, . . . , mr) :⇐⇒ ∀mr+1 . . .∀mn : (m1, m2, . . . , mr, mr+1, . . . , mn) 6∈ Sol I(11.52)

196

Page 194: Skript Waack merged

ist.Unsere erste Implementation der Methode pruning (Algorithmus 11.28) verwendet nur

das Pradikat aus (11.52).

Algorithmus 11.30 (Abschneiden unzulassiger Teilbaume)

Methodenkopf:pruning(m1, . . . , mr) returns Boolean

Rumpf:Falls |= PI(m1, m2, . . . , mr), so return true.return false.

Setzt man Algorithmus 11.30 in Algorithmus 11.29 ein, so erreicht man damit, daßdiejenigen Unterbaume abgeschnitten werden, deren Blatter keine zulassigen Losungensind.

MaxKNAPSACK als Beispiel

Fur alle m1, m2, . . . , mr ∈ 0, 1 ist

|= PI(m1, m2, . . . , mr) :⇐⇒

r∑

i=1

miwi > W.

11.6.3 Beschneidung des Backtrack-Baumes II

Zur Verkleinerung des Backtrack-Baumes kann man mehr tun, als in Abschnitt 11.6.2 dar-gestellt wurde. Man kann sich von Teilbaumen trennen, deren Blatter keine Verbesserungdes bisherigen Ergebnisses versprechen.

Die allgemeine Situation

Es gibt zwei effizient berechenbare Funktionen lower(u) und upper(u), wobei

u = (m1, m2, . . . , mr)

ein Knoten aber kein Blatt des Backtrack-Baumes fur Eingaben der Große n ist, so daßfur jede Eingabe I der Große n gilt: Ist 6|= PI(u), so liegt

max Val(I, (u, mr+1, . . . , mn)) |mr+1 ∈Mr+1, . . . , mn ∈Mn, (u, mr+1, . . . , mn) ∈ Sol I

in dem Intervall

[lower(u), upper(u)] .

Wir rusten Algorithmus 11.30 wie folgt auf: Sind einige Blatter des Teilbaumes Tu zwarzulassig, gilt aber upper(u) < globalLower, so lohnt sich ein Betreten dieses Teilbaumesnicht. Seine Batter sind offensichtlich unzulanglich.

197

Page 195: Skript Waack merged

Algorithmus 11.31 (Abschneiden unzulassiger oder unzulanglicher Teilbaume)

Methodenkopf:pruning(m1, . . . , mr) returns Boolean

Rumpf:Falls |= PI(m1, m2, . . . , mr), so return true.Falls upper(m1, m2, . . . , mr) < globalLower, so return true.globalLower← max globalLower, lower(m1, m2, . . . , mr)return false.

Algorithmus 11.29 mit Algorithmus 11.31 ist unser allgemeines Backtracking-Schema.

MaxKNAPSACK als Beispiel

Um die Funktionen lower und upper fur das Problem 3 auf eine Eingabe

I = (w1, w2, . . . , wn, c1, c2, . . . , cn, W )

zu implementieren, bedienen wir uns der Algorithmen 11.24 (SimpleGreedyKnapsack) und11.25 (GreedyFractionalKnapsack). Ist

u = (m1, . . . , mr) ∈ 0, 1r

und ist

I(u) :=

(

wr+1, wr+2, . . . , wn, cr+1, cr+2, . . . , cn, W −

r∑

i=1

miwi

)

,

so ist

lower(u) =

r∑

i=1

mici + Val(I(u), SimpleGreedyKnapsack(I(u)))

und

upper(u) =r∑

i=1

mici + Val(I(u), GreedyFractionalKnapsack(I(u)))

Verfahrt man fur das Rucksack-Optimierungsproblem wie vorstehend beschrieben, kannman viele Eingaben in akzeptierbarer Zeit bewaltigen. Man kann jedoch zeigen, daß mankeinen Polynomialzeit-Algorithmus erhalten hat.

198

Page 196: Skript Waack merged

Literaturverzeichnis

[CLRS01] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein. Introduction toAlgorithms. MIT Press, 2001.

199

Page 197: Skript Waack merged

Kapitel 12

NP–Vollstandigkeit

12.1 Einleitung

Bereits im Abschnitt 6.1 haben wir das Rucksack-Entscheidungsproblem eingefuhrt.

Problem 6 (Rucksack-Entscheidungsproblem KNAPSACK)

Eingaben sind Folgen naturlicher Zahlen

I := (w1, w2, . . . , wm, c1, c2, . . . , cm, W, C) ∈ N2m+2

in kanonischer Darstellung.

Die Problemgroße n = n(I) von I uber 0, 1 ist ein

Θ

(m∑

i=1

| bin wi| +

m∑

i=1

| bin ci| + | binC| + | binW |

)

,

denn es ist sinnvoll, die Zahlen durch geeignete Symbole zu trennen.

Ausgabe: Akzeptiere, falls es eine Losung (β1, β2, . . . , βm) ∈ 0, 1m mit

m∑

i=1

βiwi ≤W undm∑

i=1

βici ≥ C (12.1)

gibt. (Andernfalls akzeptiere nicht.)

Bemerkung. Zunachst ist man geneigt zu fordern, ein Algorithmus zur Losung desProblems 6 musse eine Eingabe verwerfen, wenn die Akzeptierungsbedingung 12.1 nichterfullt ist. (Der Unterschied von unserer Definition zu dieser Forderung wird am Beispieleiner Rechnung deutlich, die in einer unendlichen Schleife mundet. Diese akzeptiert wedernoch verwirft sie.) Algorithmen, die auf jeden Rechengang halten und entweder akzeptieren

195

Page 198: Skript Waack merged

oder verwerfen heißen Entscheidungsalgorithmen. Wir werden sehen, daß die Algorithmendieses Kapitels mit geringem Aufwand zu Entscheidungsalgorithmen aufgerustet werdenkonnen (siehe Satz 12.19 aus Abschnitt 12.6). Es ist jedoch unublich, eine solche Forderungbereits in der Definition zu erheben.

Wir haben bereits darauf hingewiesen, daß wir Eingaben uber 0, 1 codieren. Wie mandas machen kann, sehen wir etwas weiter unten. Auf diese Weise konnen wir dem Problem6 eine formale Sprache uber 0, 1 zuordnen, die wir in diesem und in ahnlich gelagertenFallen mit dem zugrunde liegenden Entscheidungsproblem identifizieren:

KNAPSACK := I | I erfullt die Akzeptierungsbedingung 12.1. (12.2)

Im Kapitel 11 haben wir unter Verwendung verschiedenartiger Entwurfsprinzipien meh-rere vergebliche Versuche unternommen, einen Polynomialzeit-Algorithmus fur das Rucksack-Optimierungsproblem 3 zu konstruieren. Die dem Problem 3 innewohnende algorithmischeKompliziertheit scheint zu groß zu sein. Naturlich ware es optimal, den Nachweis zu fuhren,daß es keinen solchen Algorithmus gibt. Aber das ist gegenwartig nicht moglich.

Um trotzdem zu interessanten Aussagen zu kommen, betrachten wir, wie bereits mitProblem 6 geschehen, statt des Optimierungsproblems seine Entscheidungsvariante. Mankann aus einem Polynomialzeit-Algorithmus fur das Rucksack-Entscheidungsproblem 6 mitHilfe von binarer Suche zu einem Polynomialzeit-Algorithmus fur das Rucksack-Optimie-rungsproblem 3 kommen (siehe Kapitel 14). Die andere Richtung ist offensichtlich: Hatman einen Polynomialzeit-Algorithmus fur das Optimierungsproblem, so kann man denNutzen einer optimalen Losung ausrechnen und testen, ob er oberhalb der angegebenenSchwelle liegt. Wir beschranken uns in diesem Kapitel auf Entscheidungsprobleme.

Es sind zwei entscheidende Ideen, die Klassifikationen der algorithmischen Kompliziert-heit von Entscheidungsproblemen in unserem und in ahnlich gelagerten Fallen ermoglichen.

Nichtdeterminismus

Wir betrachten das Rucksack-Entscheidungsproblem 6. Hat man einen moglichen Zeugen– eine mogliche Losung – geraten, so kann man in Polynomialzeit verifizieren, ob die Ak-zeptierungsbedingung erfullt ist, es sich um einen wirklichen Zeugen handelt. Um diesenGedanken umsetzen zu konnen, studieren wir nichtdeterministische Algorithmen, die inder Lage sind zu raten.

Wir verfeinern und erweitern Algorithmus 6.11 aus Abschnitt 6.1 geringfugig zu demfolgenden Algorithmus, der beliebige Worter I ∈ 0, 1∗ bearbeitet.

Algorithmus 12.1 (NP–Algorithmus fur das Rucksack-Entscheidungsproblem)

196

Page 199: Skript Waack merged

Großschritt 0 [Syntaxcheck, Einlesevorgang].0.1 Teste, ob I eine Eingabe des Rucksack-Entscheidungsproblems verschlusselt.

Ist das nicht der Fall, so verwirf I.Andernfalls fahre fort.

0.2. Lies I bitweise ein, so daßci, wi (i = 1, 2, . . . , m), C, Wnun zur Verfugung stehen.

Großschritt 1 [Rate–Phase].Rate eine Losung (β1, β2, . . . βm) ∈ 0, 1m.

Großschritt 2 [Verifikationsphase].Uberprufe, ob

∑mi=1 βiwi ≤W gilt.

Uberprufe, ob∑m

i=1 βici ≥ C gilt.Ist beides der Fall, so akzeptiere I.

Wir gehen Algorithmus 12.1 schrittweise durch.

1. Der Syntaxcheck ist weder hier noch spater ein Problem. Die Codierung der Pro-blemstellungen uber 0, 1 folgt stets dem gleichen Muster. Die Verschlusselung derInstanzen des Rucksackproblems ist ein typisches Beispiel. Wir verfahren wie folgt.

– Zunachst wird die Eingabe I uber dem Alphabet 0, 1, #, reprasentiert:

I 7→ bin w1# bin w2# . . .# bin wm bin c1# bin c2# . . .# bin cm bin W bin C

– Anschließend wird der folgende Blockcode angewandt:

0 7→ 00

# 7→ 01

7→ 10

1 7→ 11

Der Test, ob es sich bei einer Zeichenkette uber 0, 1 um eine Problemstellung desRucksack-Entscheidungsproblems handelt, laßt sich nicht nur in polynomialer Zeit,sondern sogar mit logarithmisch beschranktem Speicher (siehe Abschnitt 12.2) durch-fuhren.

Im weiteren lassen wir den Syntaxcheck meist weg. Er ist jedoch stets vorgeschaltet.Ferner identifizieren wir die Problemstellung mit dem Wort, das sie binar codiert.

Fur den Einlesevorgang mussen wir unsere RAM mit Befehlen aufrusten, die einbitweises Einlesen der uber 0, 1n codierten Problemstellung von einem Eingabebandin Register ermoglicht. Wir werden das in Abschnitt 12.5.2 genauer besprechen. Andieser Stelle reicht es uns die Feststellung, daß das Einlesen eines Bits eine Zeiteinheitkostet.

197

Page 200: Skript Waack merged

Bei Algorithmen, die lediglich sublinear beschrankten Speicher zur Verfugung haben(siehe Algorithmus DPATH in Abschnitt 12.5.2), kann die Problemstellung naturlichnicht vollstandig eingelesen werden. Man muß sich vielmehr auf sinnvolle Teilworterbeschranken, fur die der Speicher ausreicht. Dieses Problem haben wir bei Algorith-mus 12.1 jedoch nicht.

2. Fur das Raten benotigen wir einen Befehl CHOICE r, wobei r ein Register aus derMenge R1 bis R25 bezeichnet (siehe auch Abschnitt 12.5.2). Dieser Befehl inkremen-tiert den Befehlszahler und weist dem Register r ein Element aus 0, 1 zu; er rat einBit. Auf dieser Grundlage ist es nicht schwer, eine Hochsprachen-Routine choice()

zu implementieren, mit deren Hilfe Großschritt 1 die folgende Gestalt erhalt:

Fur i = 1, 2, . . . , m fuhre aus:βi ← choice()

Durch das Raten gibt es auf jede Eingabe mehrere Rechengange: Der Algorithmusist nichtdeterministisch.

3. Um akzeptieren und verwerfen zu konnen, benotigen wir neben dem END-Befehl zweineue Befehle fur das Programmende: ACCEPT und REJECT (siehe Abschnitt 12.5.2).

4. In welchem Sinne akzeptiert ein nichtdeterministischer Algorithmus das Rucksack-Entscheidungsproblem?

Ist I ∈ KNAPSACK, so muß es auf I einen Rechengang geben, der I akzeptiert.

Ist I 6∈ KNAPSACK, so gibt es auf I keinen Rechengang, der I akzeptiert.

5. Bei der Ermittlung der Laufzeit einer Rechnung zahlen wir Bitoperationen (sie-he Abschnitt 12.5.2). Wollen wir die Laufzeit des Algorithmus 12.1 insgesamt be-urteilen, so werden uns sehr großzugige Bedingungen gewahrt: Nur die EingabenI ∈ KNAPSACK werden bewertet, und bei diesen zahlt nur der beste akzeptierendeRechengang.

6. Nun ist unmittelbar klar, daß Algorithmus 12.1 ein nichtdeterministischer Poly-nomialzeitalgorithmus ist, der KNAPSACK akzeptiert:

– Ist I ∈ KNAPSACK, so zahlt nur ein Rechengang, bei dem wir eine fur unsgunstige Befullung des Rucksacks geraten haben. Die Verifikationsphase laufthier auch dann in Polynomialzeit ab, wenn wir die Bitoperationen zahlen.

– Ist dagegen I 6∈ KNAPSACK, so konnen wir keine Befullung des Rucksacksraten, fur welche die Verifikationsphase mit einer Akzeptierung endet.

Bereits im Abschnitt 6.1 haben wir die Komplexitatsklassen P und NP gewissermaßenvorlaufig eingefuhrt. Naturlich ist P ⊆ NP.

198

Page 201: Skript Waack merged

Warum ist Algorithmus 12.1 kein echter Polynomialzeit-Algorithmus fur das Rucksack-Entscheidungsproblem, der dessen Zugehorigkeit zur Klasse P sichert? Das liegt nicht dar-an, daß kein realer Rechner eine Methode choice() mit der oben beschriebenen Spezifikati-on unterstutzt. Man konnte sie in ahnlicher Weise wie die Methode random() aus Abschnitt8.3.6 implementieren. Der Hauptgrund ist vielmehr, daß es Eingaben I ∈ KNAPSACKgibt, fur die nur ein verschwindend geringer Anteil aller moglichen Befullungen des Ruck-sacks zu einer Akzeptierung fuhrt.

Um zu der Frage etwas sagen zu konnen, ob Rate-Phasen in nichtdeterministischenPolynomialzeit-Algorithmen einen echten Vorteil gegenuber deterministischen Polynomialzeit-Algorithmen gewahren, brauchen wir die folgende zweite Idee, die in Abschnitt 12.8 vollstandigdargestellt ist.

Vollstandigkeit

Gibt es fur zwei durch ihre formalen Sprachen L1 und L2 dargestellten Entscheidungspro-bleme eine in deterministischer Polynomialzeit berechenbare Transformation f der Einga-ben I1 des ersten Problems auf Eingaben f(I1) des zweiten Problems so, daß

I1 ∈ L1 ⇐⇒ f(I1) ∈ L2

ist, so kann man bezogen auf Polynomialzeitalgorithmen sagen, das Problem L1 sei nichtschwerer als das Problem L2 (siehe Algorithmus 12.24).

Es wird sich zeigen, daß das Rucksack-Entscheidungsproblem in diesem Sinne unterallen Problemen, die einen nichtdeterministischen Polynomialzeit-Algorithmus haben, einschwerstes Problem ist. Solche Probleme nennt man NP-vollstandig.

Man sieht sofort: Es gibt fur NP-vollstandige Probleme genau dann einen echtenPolynomialzeit-Algorithmus, wenn man fur jeden nichtdeterministischen Polynomialzeit-Algorithmus einen aquivalenten deterministischen finden kann. Letzteres heißt P = NP.Es gibt mehr als 1000 praktisch relevante Probleme aus allen Teilen der Informatik, fur diedasselbe gilt.

Zusammenfassung

Wir haben bereits betont, daß es das Beste ware, die Ungleichung P 6= NP zu beweisen.Leider sieht es so aus, als lage der Beweis jenseits der Reichweite der verfugbaren Tech-niken. Unsere Methoden zum Entwurf effizienter Algorithmen sind dagegen weit besserentwickelt. Da es trotzdem nicht gelungen ist, einen Polynomialzeit-Algorithmus fur einNP-vollstandiges Problem zu entwerfen, wird allgemein angenommen, daß P 6= NP ist.Wer diese Vermutung akzeptiert, fur den ist der Nachweis der NP-Vollstandigkeit fur einProblem gleichbedeutend damit, daß es keinen Polynomialzeit-Algorithmus hat.

199

Page 202: Skript Waack merged

12.2 Turingakzeptoren und Komplexitatsklassen

Unser bisheriges Rechnermodell war die Registermaschine. Im Abschnitt 12.1 haben wir unsmit ihrer Hilfe mit dem Begriff des Nichtdeterminismus bekanntgemacht. Warum fuhrenwir nun ein neues Modell ein?

Um vernuftig Komplexitatstheorie betreiben zu konnen, mussen wir Rechenvorschriften(Programme) selbst zum Gegenstand von Rechnungen machen. Dazu ist es sehr hilfreich,die Architektur des Modell weiter einzuschranken, ohne daß die Moglichkeiten, effizienteAlgorithmen zu implementieren, nennenswert schrumpfen: Der wahlfreie Zugriff auf jedeSpeicherzelle wird zu Gunsten einer relativ engen Nachbarschaftsrelation aufgegeben. Wei-terhin konnen Speicherzellen nicht mehr eine beliebige ganze Zahl sondern nur noch Sym-bole aus einem endlichen

”Arbeitsalphabet“ Γ enthalten. Die letztgenannte Einschrankung

wird uns dadurch versußt, daß nunmehr der Wechsel von einem Symbol in jedes beliebigeandere moglich ist. (Registermaschinen ließen ja nur arithmetische, logische und Verschie-beoperationen zu.)

· · · · · ·B B B· · ·yr1 yr2 yrνr

Zwei–Wege–Arbeitsband

· · · · · ·B B By11 y12y1ν1· · ·

Zwei–Wege–Arbeitsband

w1 w2⊲ wnwn−1

⊳· · ·

Zwei–Wege–Eingabeband

Q: endliche Menge von Zustanden

des nachsten Schrittesq0 ∈ Q: initialer Zustandq+ ∈ Q: akzeptierender Zustandq−∈ Q: verwerfender Zustand

......

...

Endliche Kontrolle

δ: Uberfuhrungsrelation zur Berechnung

Abbildung 12.1: Nichtdeterministischer Turingakzeptor

Ein nichtdeterministischer Turingakzeptor (NTA) ist in Abbildung 12.1 dargestellt. DieEingabe w = w1w2 . . . wn uber dem Alphabet 0, 1 steht auf einem Eingabeband, wobei

200

Page 203: Skript Waack merged

jede”Zelle“ genau einen Buchstaben enthalt. Die Symbole ⊲ und ⊳ heißen linker bzw.

rechter Randbegrenzer.Die Inhalte der Zellen der Arbeitsbander gehoren zu einem endlichen Alphabet Γ∪B

(B 6∈ Γ), wobei Γ das Arbeitsalphabet und B das Blanksymbol heißt. Es ist sicherlich sinnvollaber nicht zwingend, die Inklusion 0, 1 ⊆ Γ zu fordern. Das Blanksymbol steht furden unberuhrten Zustand der Zellen auf den Arbeitsbandern vor Beginn jeder Rechnung.Wurde in Laufe einer Rechnung in eine Zelle etwas geschrieben, so gibt es zu diesemAnfangszustand keine Ruckkehr mehr: Das Blanksymbol kann nicht geschrieben werden.

Ganz am Anfang einer Rechnung auf eine Eingabe w = w1w2 . . . wn befindet sich dieMaschine im initialen Zustand q0, der Lesekopf des Eingabebandes steht auf dem linkenRandbegrenzer ⊲ und alle Arbeitsbander sind leer.

Ein Rechenschritt von M auf w = w1w2 . . . wn hangt von der lokalen Situation

(q, b, y1, y2, . . . , yr)

der Maschine ab, wobei

– q ∈ Q den aktuelle Zustand,

– b den Inhalt der Zelle, auf dem der Lesekopf des Eingabebandes steht,

– (y1, y2, . . . , yr) den Inhalt der Zellen, auf denen die Lese–Schreib–Kopfe der Ar-beitsbander stehen,

bezeichnet.

In einem Rechenschritt

– andert die Maschine den inneren Zustand;

– verandert die Buchstaben unter den Lese–Schreib–Kopfen der Arbeitsbander, wobeiB nicht geschrieben werden darf;

– bewegt die Kopfe der Bander um hochstens eine Position nach links oder rechts,wobei die Randbegrenzer ⊲ und ⊳ auf dem Eingabeband nicht uberschritten werdendurfen.

Wann ist die Rechnung beendet? Aus technischen Grunden werden wir NTAs so defi-nieren, daß jede Rechnung syntaktisch bis in alle Ewigkeit weitergeht. Um ein semantischesEnde einer Rechnung definieren zu konnen, fordern wir fur jeden NTA M , daß sich stetsnichts mehr tut, wenn M einen terminalen Zustand (q+ oder q−) erreicht hat: Die Ma-schine bleibt in dem entsprechenden Zustand, bewegt ihre Kopfe nicht mehr und erneuertdie Inhalte der aktuellen Zellen der Arbeitsbander. Anders ausgedruckt, ein NTA M ist

201

Page 204: Skript Waack merged

so definiert, daß er aus keiner lokalen Situation, deren erste Komponente ein terminalerZustand ist, wieder herauskommt.

Wir sagen, die Maschine wurde stoppen oder halten, wenn sie einen terminalen Zustanderreicht hat.

Es ist nicht ausgeschlossen, daß lokale Situationen, deren erste Komponente kein termi-naler Zustand ist, fur einen NTA M in der soeben beschriebenen Weise zur Falle werden.Wir sprechen trotzdem nicht davon, daß die Maschine gehalten hat. Diese Situation inter-pretieren wir vielmehr so, daß M sich in einer unendlichen Schleife (mit leerem Rumpf)befindet.

Die Maschine M akzeptiert die Eingabe w, wenn es einen Rechengang von M auf wgibt, der in den akzeptierenden Zustand q+ fuhrt.

Man beachte jedoch, daß Eingaben w, die von M nicht akzeptiert werden, nicht injedem Falle dadurch verworfen werden, daß jede Rechnung von M auf w zum verwerfendenZustand fuhrt. Es ist lediglich garantiert, daß es keine Rechnung zu q+ gibt.

Formal gesehen ist das Entscheidende an einem NTA M dessen UberfuhrungsrelationδM . Sie ist das konkrete

”Programm“. Die Relation δM besteht aus Elementen der folgenden

Art:

( (q, b, y1, y2, . . . , yr)︸ ︷︷ ︸

∈Q×0,1,⊲,⊳×(Γ∪B)r

Argumentteil

, (q′, ρ0, (y′1, ρ1), (y

′2, ρ2), . . . , (y

′r, ρr))

︸ ︷︷ ︸

∈Q×L,R,N×(Γ×L,R,N)r

Wertteil

) (12.3)

Der Argumentteil (q, b, y1, y2, . . . , yr) ist die lokale Situation, in der sich die Maschinebefindet. Mit q′ ist der Nachfolgezustand bezeichnet. Die Maschine uberschreibt fur al-le j = 1, 2, . . . , r den Inhalt yj der aktuellen Zelle des j–ten Arbeitsbandes mit y′

j undbewegt dann samtliche Kopfe gemaß ρi (i = 0, 1, . . . , r). Das Symbol L steht fur

”Bewege

den Kopf nach links.“, R fur”Bewege den Kopf nach rechts.“ und N fur

”Bewege den Kopf

nicht.“.Die vorstehend dargestellten Verabredungen lassen sich nun formal wie folgt fassen:

1. Die Implikationen

b = ⊲⇒ ρ0 6= L

und

b = ⊳⇒ ρ0 6= R

stehen fur das Verbot, die Randbegrenzer zu uberschreiten.

2. Die Forderung, daß es fur jeden zulassigen Argumentteil α mindestens einen Wertteilω mit (α, ω) ∈ δM gibt, beschreibt, daß keine Rechnung syntaktisch gesehen jemalsendet.

202

Page 205: Skript Waack merged

3. Die Implikationen

(q = qf )⇒ (q′ = qf , ρ0 = ρ1 = . . . = ρr = N, y1 = y′1, . . . , yr = y′

r) (qf ∈ q+, q−)

bedeuten, daß die Rechnung semantisch zu Ende ist, wenn die Maschine einen ter-minalen Zustand erreicht hat.

Bemerkung. Die syntaktische Umsetzung eines Loschvorgangs auf den Arbeitsbandernmuß mit einem speziellen Element B′ ∈ Γ, dem sogenannten Pseudoblank, erfolgen.

Um fur das Weitere gerustet zu sein, benotigen wir die folgenden Begriffe.

Definition 12.2 Sei M ein NTA mit r Arbeitsbandern.

1. Eine Konfiguration C von M auf die Eingabe w = w1, w2 . . . wn ist ein Tupel

C := (q, (w, k0), (u1, k1), (u2, k2), . . . , (ur, kr)) , (12.4)

wobei

– q der Zustand ist, in dem sich M gerade befindet;

– w = w1w2 . . . wn die Eingabe ist;

– k0 ∈ [0, n + 1] die Position des Lesekopfes auf dem Eingabeband beschreibt,wobei 0 und n + 1 dafur stehen, daß ⊲ bzw. ⊳ gelesen wird;

– uj der von B verschiedene Inhalt des j–ten Arbeitsbandes ist (j = 1, 2, . . . , r);

– die Zahl kj (kj ∈ [0, |uj| + 1]) die Kopfposition auf dem j–ten Arbeitsband ist(j = 1, 2, . . . , r). (Steht der Lese–Schreibkopf auf dem Blank–Symbol unmittel-bar links (rechts) vom nichtleeren Inhalt des j–ten Arbeitsbandes, so schreibenwir dafur kj = 0 (kj = |uj| + 1]). Dabei bezeichnet |wj| die Lange der Zeichen-kette uj.)

2. Eine Konfiguration C = (q, (w, k0), (u1, k1), (u2, k2), . . . , (ur, kr)), wenn q = q+ (q =q−) heißt akzeptierend (verwerfend).

3. Die initiale Konfiguration von M auf w ∈ 0, 1∗ ist

C0(w) := (q0, (w, 0), (ǫ, 0), (ǫ, 0), . . . , (ǫ, 0)).

(Der Lesekopf des Eingabebandes steht auf dem linken Randbegrenzer ⊲, die Ar-beitsbander sind leer. Die Maschine ist im initialen Zustand q0.)

4. Eine Konfiguration C ′ = (q, (w, k′0), (u

′1, k

′1), (u

′2, k

′2), . . . , (u

′r, k

′r)) ist unmittelbarer

Nachfolger von C = (q, (w, k0), (u1, k1), (u2, k2), . . . , (ur, kr)) (Bezeichnung: C ⊢δ C ′

oder C ⊢ C ′), wenn C ′ aus C durch genau einen Rechenschritt aus C hervorgeht.

203

Page 206: Skript Waack merged

5. Eine Rechnung von M auf eine Eingabe w ist eine Folge CM(w) := C0(w) ⊢ C1 ⊢C2 ⊢ . . . ⊢ Ct. Der Wert von t heißt die Lange der Rechnung. (Die Lange kann auchgleich ∞ sein.)

6. Eine Rechnung CM(w) von M auf w endlicher Lange t heißt akzeptierend (verwer-fend), wenn Ct eine akzeptierende (verwerfende) Konfiguration ist.

7. Die durch M akzeptierte formale Sprache L(M) ist die Menge aller Eingaben w ∈0, 1∗, fur die es eine akzeptierende Berechnung gibt.

L(M) := w ∈ 0, 1∗ | ∃ CM(w) : C0(w) ⊢∗ Ct, Ct ist akzeptierende Konfiguration

8. Sei t : N → N eine monoton wachsende Funktion. Die Maschine M heißt t–zeit-beschrankt, wenn es fur jedes w ∈ L(M) eine akzeptierende Berechnung mit einerLange gibt, die nach oben durch t(|w|) beschrankt ist. (Man beachte, daß diese Defi-nition außerordentlich großzugig ist. In Betracht kommen nur akzeptierende Berech-nungen, und da auch nur die fur eine Eingabe jeweils beste.)

9. Der Speicherbedarf einer Konfiguration

C = (q, (w, k0), (u1, k1), (u2, k2), . . . , (ur, kr))

ist gleich der Anzahl der beschriebenen Zellen auf den Arbeitsbandern:

space(C) :=r∑

i=1

|ui|.

10. Der Speicherbedarf einer Rechnung

CM(w) = C0(w) ⊢ C1 ⊢ C2 ⊢ . . . ⊢ Ct

der Maschine M auf w ist gleich dem Maximum des Speicherbedarfs der beteiligtenKonfigurationen:

space(CM(w)) := max1≤i≤t

space(Ci).

Da das Blank B nicht geschrieben werden darf, gilt:

space(CM(w)) = space(Ct).

11. Sei s : N→ N eine monoton wachsende Funktion. Die Maschine M heißt s–speicher-beschrankt, wenn es fur jedes w ∈ L(M) eine akzeptierende Rechnung gibt, derenSpeicherbedarf nach oben durch s(|w|) beschrankt ist. (Wiederum kommen nur diejeweils besten akzeptierenden Berechnungen in Betracht.)

204

Page 207: Skript Waack merged

Eine nichtdeterministische Turingmaschine M ist kein Algorithmus im landlaufigen Sinne.Im Abschnitt 6.1 und im Abschnitt 12.1 haben wir das Rucksack–Entscheidungsproblembetrachtet. Um herauszufinden, ob es eine Befullung des Rucksacks mit den gefordertenEigenschaften gibt, darf die Maschine eine solche raten. Dies entspricht der Tatsache, daßes fur manche Argumentteile α mehrere Wertteile β mit (α, β) ∈ δM gibt. (Aus Definition12.2 wissen wir, daß es vollig uninteressant ist, was passiert wenn falsch geraten wird, oderwenn es nichts zu raten gibt.) Ein Algorithmus ist jedoch determiniert: Jede Konfigurationdarf nur hochstens einen Nachfolger haben.

Definition 12.3 Ein NTA M , fur dessen Uberfuhrungsrelation δM zu jedem Argumentteilα genau ein Wertteile β mit (α, β) ∈ δM existiert, heißt deterministisch (Akurzung: DTA).Statt (α, β) ∈ δM schreibt man in diesem Fall naturlich δM (α) = β.

Wir fuhren die folgenden Komplexitatsklassen ein.

Definition 12.4 Wir betrachten formale Sprachen L uber dem Alphabet 0, 1.

1. Die Komplexitatsklasse DTIME (t) (NTIME (t)) ist die Familie aller formalenSprachen, die durch einen O (t)–zeitbeschrankten DTA (NTA) akzeptiert werdenkonnen:

DTIME (t) := L |Es gibt einen O (t) -zeitbeschrankten DTA M mit L(M) = L.

NTIME (t) := L |Es gibt einen O (t) -zeitbeschrankten NTA M mit L(M) = L.

2. Die Komplexitatsklasse P besteht aus allen formalen Sprachen, fur die es einen po-lynomialzeitbeschrankten DTA gibt, der sie akzeptiert:

P :=

∞⋃

k=0

DTIME(nk)

3. Die Komplexitatsklasse NP besteht aus allen formalen Sprachen, fur die es einenpolynomialzeitbeschrankten NTA gibt, der sie akzeptiert:

NP :=

∞⋃

k=0

NTIME(nk)

4. Die Komplexitatsklasse DSPACE (s) (NSPACE (s)) ist die Familie aller formalenSprachen, die durch einen O (s)–speicherbeschrankten DTA (NTA) akzeptiert werdenkonnen:

DSPACE (s) := L |Es gibt einen O (s) -speicherbeschrankten DTA M mit L(M) = L.

NSPACE (s) := L |Es gibt einen O (s) -speicherbeschrankten NTA M mit L(M) = L.

205

Page 208: Skript Waack merged

5. Die Komplexitatsklasse L besteht aus allen formalen Sprachen, fur die es einen loga-rithmisch speicherbeschrankten DTA gibt, der sie akzeptiert:

L := DSPACE (log(n))

6. Die Komplexitatsklasse NL besteht aus allen formalen Sprachen, fur die es einenlogarithmisch speicherbeschrankten NTA gibt, der sie akzeptiert:

NL := NSPACE (log(n))

7. Die Komplexitatsklasse PSPACE (NPSPACE) ist die Familie aller formalen Spra-chen, die durch einen nO(1)–speicherbeschrankten DTA (NTA) akzeptiert werdenkonnen:

PSPACE :=

∞⋃

k=0

DSPACE(nk)

NPSPACE :=

∞⋃

k=0

NSPACE(nk)

Beispiele.

• Im Grundkurs Informatik I/II sind zahlreiche Beispiele von Entscheidungsproblemenaus P besprochen worden. Eine Zusammenfassung findet sich im Abschnitt 6.1, eineausfuhrliche Darstellung im Teil II.

• Das Studium wichtiger Vertreter der Klasse NP bilden den Hauptgegenstand diesesKapitels. Ein Beispiel kennen wir bereits aus dem Abschnitt 6.1 bzw. dem Abschnitt12.1: Das Rucksack-Entscheidungsproblem.

• Das Graph-Accessibility-Problem (GAP) ist wie folgt definiert. Gegeben ist ein gerich-teter Graph G = (V, E), dessen Knotenmenge o.B.d.A. die Menge 1, 2, . . . , m ist.G steht als eine kanonische binare Codierung der Adjazenzlisten auf dem Eingabe-band zur Verfugung: Fur jeden Knoten i ∈ 1, 2, . . . , m wird dessen Nachfolgerlisteals Zeichenkette i#j1#j2# . . .#jλi

uber dem Alphabet 0, 1, #, dargestellt undwie in Abschnitt 12.1 geschildert uber 0, 1 codiert. Der Graph G wird durch dieVerkettung dieser Worter fur jeden seiner Knoten dargestellt. Seine Eingabenlangen ist dann ein O (m2 log m).Die formale Sprache GAP besteht aus allen binaren Codierungen von solchen Gra-phen, fur die es einen gerichteten Weg vom Knoten 1 zum Knoten m gibt.

Wir beschreiben einen O (log n)-speicherbeschrankten NTA M , der GAP akzeptiert.Angesetzt auf einen Graphen G mit m Knoten rat M einen Pfad in G, der mit 1beginnt. Um einen Pfad v1 = 1, vi2 , . . . zu erzeugen, muß M den aktuellen Knoten vij

auf einem Arbeitsband halten. Das ist mit log m-beschranktem Speicher moglich. Ausder Nachfolgerliste auf dem Eingabeband entscheidet sich M fur einen der Nachfolger

206

Page 209: Skript Waack merged

von vij im Wege des Ratens. Anschließend aktualisiert M den gehaltenen Knoten undtestet, ob es sich dabei um m handelt.

Der Platzbedarf der oben beschriebenen Maschine M ist aus O (log m) ⊆ O (log n).

Wir werden im Abschnitt 12.9 sehen, daß GAP fur die Klasse NL ein algorithmischschwerstes Problem ist.

• Das Problem GAP1 ist wie folgt definiert. Gegeben ist ein gerichteter Graph G =(V, E), dessen Knotenmenge o.B.d.A. die Menge 1, 2, . . . , m ist. Wiederum ist Gdurch eine kanonische binare Codierung der Adjazenzlisten gegeben ist. Die formaleSprache GAP1 besteht aus allen binaren Codierungen von solchen Graphen, fur diees einen gerichteten Weg vom Knoten 1 zum Knoten m gibt, und fur die uberdiesfolgendes gilt: Fur jeden Knoten von G gibt es hochstens einen Nachbarknoten.

Die Beschreibung eines O (log n)-speicherbeschrankten DTA M , der GAP1 akzep-tiert, ist eine leichte Ubungsaufgabe.

Man kann formalisieren, daß GAP1 fur die Klasse L ein algorithmisch schwerstesProblem ist.

Logarithmischer Raum ist also nicht viel mehr als die Modellierung eines Lesezeichensfur das Eingabeband.

• Die Auswertung einer Booleschen Formel (formale Definition siehe Abschnitt 12.10)benotigt nur logarithmisch beschrankten Raum. Folglich gehort die Sprache, die ausallen Paaren (F (x1, x2, . . . , xn), b = (b1, b2, . . . , bn)), wobei F eine Boolesche Formelin den Variablen x1, x2, . . . , xn und b ein Boolescher Vektor ist, fur den F (b) = 1 ist,zur Komplexitatsklasse L.

• In Informatik I/II haben wir regulare Sprachen kennengelernt. Ist L eine regulareSprache uber 0, 1, so wissen wir, daß ein endlicher Automat fur jedes x die Ent-scheidung x ∈ L? fallen kann. Folglich gehort L zu L. Fur eine kontextfreie SpracheL weiß man lediglich, daß L ∈ DSPACE

(log2 n

)ist.

• Eine quantifizierte Boolesche Formel (QBF) ist ein Ausdruck der Form

E = Q1x1Q2x2 . . . Qmxm F (x1, x2, . . . , xm) , (12.5)

wobei jedes Qi entweder der Allquantor ∀ oder der Existenzquantor ∃ ist, undF (x1, x2, . . . , xm) eine Boolesche Formel in den Booleschen Variablen x1, x2, . . . , xm

bezeichnet.

Beispiele fur Boolesche Formeln sind x∧y oder (x∨y)∧z. Boolesche Formeln definie-ren auf kanonische Weise Boolesche Funktionen. Die formale Einfuhrung BoolescherFormeln findet sich in Definition 12.33.

Werden alle Variablen einer Booleschen Formel durch Quantoren gebunden, so erhaltman eine Aussage, die entweder wahr oder falsch ist.

Die Aussage ∀x∃y(x ∨ y) ist offenbar wahr, ∀x∃y(x ∧ y) dagegen falsch.

Die formale Sprache QBF besteht aus allen binaren Codierungen wahrer quantifizier-ter Boolescher Formeln.

207

Page 210: Skript Waack merged

Wann ist die QBF E aus Gleichung 12.5 wahr? Das ist genau dann der Fall, wenn

m = 0 und F ≡ 1 oder (12.6)

Q1 = ∃ und E0 oder E1 sind wahr oder (12.7)

Q1 = ∀ und E0 und E1 sind wahr, (12.8)

wobei F0 und F1 diejenigen Formeln bezeichnen, die man aus F erhalt, indem man dieVariable x1 durch 0 bzw. 1 ersetzt, und Ei = Q2x2 . . . Qmxm Fi (x2, . . . , xm) (i = 0, 1)ist.

Es ist nicht schwer, einen Algorithmus zu schreiben, der unter Verwendung der Glei-chungen 12.6, 12.7 und 12.8 mit O (m + |F |) beschrankten Platz entscheidet, obdie QBF E aus Gleichung 12.5 wahr ist. Dabei ist |F | die Lange einer kanonischenbinaren Codierung der Formel F = F (x1, x2, . . . , xm).

Das Problem QBF ist folglich in PSPACE.

Wir werden im Abschnitt 12.9 sehen, daß QBF fur die Klasse PSPACE ein algo-rithmisch schwerstes Problem ist.

Fur eine Zeitschranke t setzen wir stets voraus, daß sie monoton wachsend ist und stetst(n) = Ω(n) ist. Letzteres wird angenommen, damit die Eingabe auch gelesen werdenkann.Fur Speicherschranken s gilt neben der Monotonie wie bei Zeitschranken immer s(n) =Ω(log n).

12.3 Turingtransduktoren und Funktionenklassen

Turingtransduktoren (TT) sind stets deterministisch. In Abbildung 12.2 ist ein TT darge-stellt.

Die Definition eines TT M mit r Arbeitsbandern gleicht bis auf die folgenden Modifi-kationen der eines DTA (siehe Definition 12.2):

1. Die Uberfuhrungsfunktion δM ist wie folgt spezifiziert:

δM : Q× 0, 1, ⊲, ⊳ × (Γ ∪ B)r → Q× L, R, N × (Γ× L, R, N)r × 0, 1, ǫ

(q, b, u1, u2, . . . , ur)→ (q′, ρ0, (u′1, ρ1), (u

′2, ρ2), . . . , (u

′r, ρr), y),

(12.9)

wobei die letzte Komponente y des Bildes die Ausgabe bezeichnet, die in diesemSchritt getatigt wird. (Diese ist entweder ein Bit oder aber das leere Wort. Die Ma-schine ist also nicht gezwungen, in jedem Schritt etwas auszugeben.)

2. Die Implikationen

(q = qterm)⇒ (q′ = qterm, ρ0 = ρ1 = . . . = ρr = N, u1 = u′1, . . . , ur = u′

r, y = ǫ)

208

Page 211: Skript Waack merged

......

...

Endliche Kontrolle

y1 y2 y3 · · ·· · · · · · yk−1 yk

Ein–Weg–Ausgabeband

δ: Uberfuhrungsfunktion zur Berechnung

Q: endliche Menge von Zustanden

q0 ∈ Q: initialer Zustand

des nachsten Schrittes

qterm ∈ Q: terminaler Zustand

Zwei–Wege–Eingabeband

Zwei–Wege–Arbeitsband

Zwei–Wege–Arbeitsband

· · ·

· · · · · ·B B B· · ·

· · · · · ·B B B· · ·ur2ur1 urνr

u12u11u1ν1

x1 xnx2 xn−1 ⊳⊲

Abbildung 12.2: Turingtransduktor

bedeuten auch hier, daß die Rechnung semantisch zu Ende ist, wenn die Maschine denterminalen Zustand erreicht hat. Insbesondere wird dann nichts mehr ausgegeben.(Eine andere Regelung ließe sich schwerlich mit unserer Terminologie vereinbaren,nach der die Maschine halt, wenn sie qterm erreicht hat.)

3. Eine Konfiguration C von M auf die Eingabe x = x1x2 . . . xn ist ein Tupel

C := (q, (x, k0), (u1, k1), (u2, k2), . . . , (ur, kr), y) , (12.10)

wobei y ∈ 0, 1k die bisher getatigte Ausgabe uber dem Alphabet 0, 1 ist.

4. Eine Konfiguration

C = (q, (x, k0), (u1, k1), (u2, k2), . . . , (ur, kr), y = y1y2 . . . ym)

mit q = qterm heißt terminal.

209

Page 212: Skript Waack merged

5. Die initiale Konfiguration von M auf x ∈ 0, 1∗ ist

C0(x) := (q, (x, 0), (ǫ, 0), (ǫ, 0), . . . , (ǫ, 0), ǫ).

6. Bei der Messung des Speicherbedarfs einer Konfiguration zahlt die Ausgabe nichtmit.

7. Die Maschine M halt auf eine Eingabe x, wenn

C0(x) ⊢∗ (qterm, (x, k0), (u1, k1), (u2, k2), . . . , (ur, kr), y)

gilt. In diesem Falle heißt y die Ausgabe von M auf x. Falls die Maschine M auf xnicht halt, gibt sie auf x auch nichts aus. Folglich berechnet M eine partielle Funktion

f : 0, 1∗⊇−→ 0, 1∗.

8. Eine Funktion

f : 0, 1∗⊇−→ 0, 1∗.

heißt turingberechenbar, wenn es einen TT M gibt, der f wie unter 7.) beschriebenberechnet.

9. Die Komplexitatsklasse FP besteht aus allen total definierten Funktionen f , diedurch einen polynomialzeitbeschrankten Turingtransduktor berechenbar sind:

FP := f | f ist durch eine nO(1)-zeitbeschrankten TT berechenbar

10. Die Komplexitatsklasse FL besteht aus allen total definierten Funktionen f , diedurch einen Turingtransduktor berechenbar sind, der mit logarithmisch beschranktemSpeicher auskommt:

FL := f | f ist durch eine O (log n) -speicherbeschrankten TT berechenbar

Das Kurzel”TM“ steht ab jetzt sowohl fur eventuell nichtdeterministische Turingakzep-

toren als auch fur Turingtransduktoren.

Es folgen einige Eigenschaften der Funktionenklassen FP und FL, die wir im Abschnitt12.8 bei der sinnvollen Einfuhrung der many-one-Reduzierbarkeit einer formalen Spracheauf eine andere brauchen werden.

Definition 12.5 Eine TM M simuliert eine TM M ′ Schritt fur Schritt, wenn jeder SchrittCi ⊢ Ci+1 der Maschine M einer Folge von Schritten Cji

⊢ Cji+1 ⊢ . . . ⊢ Cji+li der MaschineM ′ entspricht.

Lemma 12.6 Die Klasse FP ist abgeschlossen gegenuber Verkettung.

210

Page 213: Skript Waack merged

Beweis. Sei fur i = 1, 2 Mi ein TT, der eine Funktion fi ∈ FP nki-zeitbeschranktberechnet. Wir konstruieren einen TT M , der f2 f1 berechnet.

Angesetzt auf eine Eingabe x simuliert M in einer ersten Phase Schritt-fur-Schritt M1,wobei er ein zusatzliches Arbeitsband als Hilfsausgabeband nutzt.

Anschließend simuliert M Schritt-fur-Schritt M2, wobei das zusatzliche Arbeitsbandnun als Hilfseingabeband dient. Das Eingabeband wird in dieser Phase nicht gebraucht.Die Ausgabe erfolgt auf dem Ausgabeband.

Man uberlegt sich sofort, daß die Laufzeit von M auf jede Eingabe der Lange n durchnk1 + nk1·k2 nach oben beschrankt ist.

Lemma 12.7 Die Klasse FL ist in der Klasse FP enthalten.

Beweis. Sei M ein TT, der eine Funktion f ∈ FL berechnet. Der TT M halt auf jedeEingabe x ∈ 0, 1∗, gibt f(x) aus und benutzt auf seinen r Arbeitsbandern hochstensO (log n) Zellen.

Fur eine Eingabe x sieht eine Konfiguration von M auf x gemaß Gleichung 12.10 soaus:

C :=

q, (x, k0), (u1, k1), (u2, k2), . . . , (ur, kr)︸ ︷︷ ︸

Eingabe- und Arbeitsteil

, y1y2 . . . yℓ︸ ︷︷ ︸

Ausgabeteil

.

Ist die Maschine M in der Konfiguration C, so hangt der weitere Verlauf der Rechnungnur von deren Eingabe- und Arbeitsteil ab. Die bisher getatigte Ausgabe y1y2 . . . yℓ darf janicht mehr inspiziert werden.

Da fur jedes solche C und jedes i = 1, 2, . . . , r fur die Inschrift des i-ten Arbeitsbandes|ui| = O (log |x|) ist, gibt es auf eine Eingabe der Lange n nur nO(1) viele verschiedeneEingabe- und Arbeitsteile von Konfigurationen auf diese Eingabe.

Gabe es eine Eingabe x derart, daß M auf x mehr Schritte machte als es Eingabe- undArbeitsteile von Konfigurationen auf x gibt, so kame M in eine Schleife und konnte f(x)nicht ausgeben.

Bemerkung. Es ist offensichtlich, daß jede Funktion f ∈ FP in dem folgenden Sinnepolynomial langenbeschrankt ist: Fur jedes w ∈ 0, 1∗ ist |f(w)| = |w|O(1).

Lemma 12.8 Die Klasse FL ist abgeschlossen gegenuber Verkettung.

Beweis. Zunachst ist man geneigt, genauso zu verfahren wie beim Beweis von Lemma12.6. Das Problem ist, daß im allgemeinen die Lange der Zeichenkette f1(x) zu groß ist,um sie auf ein Arbeitsband der Maschine fur f2 f1 zu schreiben.

Wir beschreiben einen TT M , der angesetzt auf eine Eingabe x den TT M2, angesetztauf f1(x), Schritt-fur-Schritt simuliert. Dazu halt M auf einem zusatzlichen Arbeitsbandeinen Zahler z fur den Index des nachsten Bits von f1(x), der von M2 gelesen werden muß.

211

Page 214: Skript Waack merged

Simulation des Leseschritts von M2. M erzeugt auf einem zusatzlichen Arbeitsbandeine Arbeitskopie z von z und startet eine Simulation von M1 angesetzt auf x. Allerdingswird, sofern die simulierte Maschine M1 ein Bit ausgeben will, diese Ausgabe unterdruckt.Es wird lediglich der Zahler z dekrementiert. Ist der Zahlerstand gleich null, so ist das Bit,das bei M1 gerade zur Ausgabe anstunde, das gesuchte Bit von f1(w).

Simulation der Bewegung des Lesekopfes von M2. Im wesentlichen wird der Zahlerz inkrementiert bzw. dekrementiert. Allerdings muß vor jeder Inkrementierung getestetwerden, ob f1(x) uberhaupt ein solches Bit hat. Das geschieht in einer Weise, die zurSimulation des Leseschritts von M2 analog ist.

Die Simulation der Aktionen von M2 auf seinen Arbeitsbandern erfolgt direkt. Dafurhat M zusatzliche Arbeitsbander in gleicher Zahl.

Die Speicherschranke ist gewahrt, da fur jedes x der Wert f1(x) eine Lange hat, diedurch ein Polynom in |x| beschrankt ist. Folglich benotigt die Darstellung des Zahlers znur O (log |x|)-beschrankten Platz.

Beispiele.

• Alle effizienten Algorithmen, die wir in dieser Vorlesung kennengelernt haben, be-rechnen Funktionen aus FP. Man muß lediglich die binare Große der Eingabezahlenunter Kontrolle halten und darauf achten, daß man keine Befehle der multiplikativenArithmetik verwendet. Warum das so ist, besprechen wir im Abschnitt 12.5.

• Man kann sich davon uberzeugen, daß die Addition und die Multiplikation zweiern-Bitzahlen Funktionen sind, die zu FL gehoren.

Man vermutet, daß nicht alle Funktionen aus FP in FL liegen. Beweisen kann man dasjedoch nicht.

12.4 Elementare Techniken des Rechnens mit Turing-

maschinen

Die”Programmierung“ von Turingmaschinen ist schwierig. Die folgenden Techniken, die

zur Erweiterung bereits vorhandener TMs dienen, schaffen etwas Erleichterung. Wir folgender Darstellung aus [Rei99].

12.4.1 Speicherung im endlichen Gedachtnis

Ohne den Speicher zu benutzen, kann sich eine Turingmaschine eine beschrankte Mengevon Informationen merken. Etwas formaler gesagt, kann man einen beliebigen endlichenAutomaten uber dem Eingabealphabet 0, 1 in eine Turingmaschine integrieren (sieheTeil II).

212

Page 215: Skript Waack merged

12.4.2 Spuren auf den Arbeitsbandern

In (12.11) ist ein Arbeitsband mit r Spuren dargestellt. In jeder dieser Spuren stehenElemente aus dem alten Arbeitsalphabet Γ ∪ B. Formal werden Spuren dadurch einge-richtet, daß man das Arbeitsalphabet Γ durch (Γ ∪ B)r \ (B, B, . . . , B) ersetzt. DasTupel (B, B, . . . , B) wird das neue Blanksymbol.

. . . b1,i−2 b1,i−1 b1,i b1,i+1 b1,i+2 . . .

. . . b2,i−2 b2,i−1 b2,i b2,i+1 b2,i+2 . . ....

......

......

. . . br,i−2 br,i−1 br,i br,i+1 r2,i+2 . . .

(12.11)

Der Aufwartspfeil ↑ verweist auf die Zelle mit dem Inhalt (b1,i, b2,i, . . . , br,i) ∈ (Γ∪B)r.Dieses Tupel wird in einem Rechenschritt gelesen und als Ganzes verandert. Das bedeutetnaturlich nicht, daß der Inhalt jeder einzelnen Spur verandert werden muß.

12.4.3 Simulation eines zweiseitig unendlichen Bandes durch eineinseitiges

Ein zweiseitig unendliches Band kann durch ein einseitiges simuliert werden, indem manes wie folgt faltet:

. . . b−2 b−1 b0 b1 b2 . . . →b0 b1 b2 b3 . . .⊲ b−1 b−2 b−3 . . .

(12.12)

Die Simulation ist ohne Zeitverzug und Speicherverlust moglich. Man muß sich imendlichen Gedachtnis (siehe Abschnitt 12.4.1) lediglich merken, ob man sich auf der oberenoder auf der unteren Spur befindet.

12.4.4 Markieren von Speicherzellen

Sei M ⊇ ⋆, N, eine endliche Menge von Marken. Wir konnen den Spurtrick (sieheAbschnitt 12.4.2) dazu verwenden, einzelne Speicherzellen durch Plazierung von Elementenaus M auf der zweiten Spur zu markieren:

. . . bj bj+1 bj+2 bj+3 bj+4 bj+5 bj+6 bj+7 . . .

. . . ⋆ B B N B B B . . .(12.13)

12.4.5 Kopieren und Verschieben von Blocken

Ein Block ist eine konsekutive Folge von Speicherzellen.

213

Page 216: Skript Waack merged

Es soll ein Block der Lange λ an eine andere Stelle kopiert werden. Steht ein zweitesBand zur Verfugung, so wird der Block zunachst auf dieses Band ggf. unter Verwendungeiner zusatzlichen Spur umkopiert, um von dort an seine endgultige Position zu gelangen.Der Zeitaufwand dafur ist O (λ).

Ohne ein zusatzliches Band werden Anfangsposition () und Endposition () desBlockes und die Anfangsposition (⊲) desjenigen Abschnitts auf dem Arbeitsband, wo-hin der Block kopiert werden soll, auf einer zusatzlichen Spur markiert. Nun wird jedeseinzelne Symbol des Blockes kopiert. Dazu mussen das Ende der aktuellen Kopie (⊳) undder nachste Buchstabe (↑), der zur Kopie ansteht, ebenfalls markiert werden:

. . . b1 b2 . . . bi−1 bi bi+1 . . . bλ . . . . . . . . . b1 b2 . . . bi−1 . . .

. . . B . . . B ↑ B . . . . . . . . . . . . ⊲ B . . . ⊳ . . .(12.14)

Da der Kopf zum Transport jedes Symbols um 2 · δ Zellen bewegt werden muß, wobei δder geplante Abstand zwischen Original und Kopie ist, und noch eine Verschiebung derMarkierungen hinzukommt, ist der Zeitaufwand dafur O (λ · δ).

Bei der Verschiebung von Blocken geht man ahnlich vor. Der Zeitaufwand ist O (λ),sofern ein zusatzliches Band zur Verfugung steht. Andernfalls liegt er bei O (λ · δ). DieZahlen λ und δ haben die gleiche Bedeutung wie oben.

12.4.6 Zahler

Auf einer zusatzlichen Spur wird ein binarer Zahler Z = zβ−1zβ−2 . . . z0 mit einem vor-gegeben Anfangswert mitgefuhrt. Das niederwertigste Bit befindet sich immer auf Hohedes Kopfes. Wenn vorhanden, ist es naturlich bequemer, ein zusatzliches Band dafur zuverwenden. Gezahlt wird nun, indem der Zahler nach den aus der Schule bekannten Regeln(Schulmethode) der binaren Addition (Subtraktion) inkrementiert (dekrementiert) wird.

Wir betrachten zwei Anwendungen. In beiden Fallen setzen wir der Einfachheit voraus,daß wir fur den Zahler ein zusatzliches Arbeitsband zur Verfugung haben.

Zahlen der Rechenschritte

Hierbei handelt es sich eigentlich um eine Simulation. Der Schrittzahler wird mit 0 initia-lisiert. Jeder Rechenschritt der Maschine, deren Schritte gezahlt werden sollen, wird nundadurch simuliert, daß zunachst der eigentliche Schritt ausgefuhrt und anschließend derZahler inkrementiert wird.

Markierung eines Bandabschnittes

Angenommen, auf einem zusatzlichen Arbeitsband ist die Lange Z > 0 desjenigen Blocksauf einem Arbeitsband gespeichert, der markiert werden soll. Wir wollen der Einfachheitannehmen, daß das in Rede stehende Arbeitsband leer ist.

Wir markieren auf einer zusatzlichen Spur den linken und gleich rechts daneben denrechten Randbegrenzer des zu markierenden Blocks. Nun verschieben wir den rechten

214

Page 217: Skript Waack merged

Randbegrenzer um eine Zelle nach rechts und dekrementieren den Zahler solange, bis daßder Zahler gleich null ist.

Zeit– und Speicherplatzanalyse

Die Speicherplatzanalyse der vorstehenden Algorithmen ist einfach. Nach Lemma 1.1 wer-den ⌈log2(Zmax+1)⌉ zusatzliche Speicherzellen gebraucht, wobei Zmax der maximale Zahler-stand ist.

Die Zeitanalyse fur das Aufwartszahlen von null bis N und fur das Abwartszahlen vonN bis null haben wir bereits im Abschnitt 11.2.4 durchgefuhrt. Nach Satz 11.11 werden2 ·N Rechenschritte gebraucht.

12.4.7 Bandreduktion

Wie kann man r Arbeitsbander durch ein Arbeitsband simulieren? Das geschieht unter Ein-satz von Spuren auf dem simulierenden Band (siehe Abschnitt 12.4.2). Die lokale Situationder r Bander

. . . b1,i−2 b1,i−1 b1,i b1,i+1 b1,i+2 . . . Band 1

↑ Kopfposition 1

. . . b2,i−2 b2,i−1 b2,i b2,i+1 b2,i−2 . . . Band 2

↑ Kopfposition 2

......

......

...

. . . br,i−2 br,i−1 br,i br,i+1 r2,i−2 . . . Band r

↑ Kopfposition r

wird durch ein Band gemaß (12.11) reprasentiert.Ein Rechenschritt auf den r Bandern entspricht leider nicht nur einem Rechenschritt

auf dem simulierenden Band, da sich die Kopfe auf den zu simulierenden Bandern in unter-schiedliche Richtungen bewegen konnen. Das muß durch eine Verschiebung der Spurinhalteausgeglichen werden. Ist s das Maximum uber den auf den r zu simulierenden Bandernzum aktuellen Zeitpunkt belegten Speicher, so sind dazu nach Abschnitt 12.4.5 O (r · s)Schritte notwendig.

Der Speicherbedarf auf dem simulierenden Band ist ebenfalls ein O (r · s).Bemerkung. Naturlich kann man auch das Eingabeband in die vorstehende Simulation

mit einbeziehen.

12.4.8 Nichtdeterministisches Raten

Ein NTA rat in einer Konfiguration C ein Element aus einer endlichen Menge A, falls ervon C ausgehend eine Folge nichtdetermistischer Schritte ausfuhrt, die er in eine von |A|moglichen Konfigurationen C1, C2, . . . , C|A| uberfuhrt.

215

Page 218: Skript Waack merged

Soll beispielsweise ein Element aus 0, 1k geraten und auf ein Arbeitsband geschriebenwerden, so wird auf einer zusatzlichen Spur oder, falls es vorhanden ist, auf einem weiterenArbeitsband ein Zahler installiert und mit bin k initialisiert. Nun wird durch nichtdetermi-nistischen Ubergang ein Bit auf das Arbeitsband geschrieben, der Kopf nach rechts bewegtund der Zahler dekrementiert, bis daß der Zahlerinhalt gleich null ist. Aus Abschnitt 12.4.6folgt, daß der soeben beschriebene Vorgang O (k) Rechenschritte kostet.

Dem Leser sollte nun klar sein, wie z.B. die Rate-Phase des Algorithmus 6.11 auf einerTM zu implementieren ist.

12.5 Uber die Robustheit der Klasse P

Wir haben Komplexitatsklassen wie P, FP, NP, L, FL und NL mit Hilfe des Rechner-modells der k-Band Turingmaschine eingefuhrt. Eine Komplexitatsklasse kann nur dannvon wirklich zentraler Bedeutung sein, wenn ihr Umfang nicht von den technischen Beson-derheiten eines Maschinenmodells abhangt.

In diesem Abschnitt werden wir zur Stutzung der folgenden These beitragen: Die Kom-plexitatsklasse P, die fur den Theoretischen Informatiker fur alle Entscheidungsproblemesteht, die eine effiziente Losung zulassen, ist von der Wahl eines heutzutage realistischenMaschinenmodells unabhangig.

– Im Abschnitt 12.5.1 zeigen wir unter Verwendung der Techniken aus Abschnitt 12.4,daß die Klasse P nicht von der konkreten Ausgestaltung des Modells der Turingma-schine abhangt.

– Im Abschnitt 12.5.2 fuhren wir fur Registermaschine die logarithmischen Kostenmaßeein. Die Simulationsergebnisse dieses Abschnitts zeigen: Definierte man fur Register-maschinen eine zu P analoge Klasse, so fiele diese mit P zusammen.

Ferner werden wir nutzen, daß diese Simulationen den Speicheraufwand jeweils nurum einen konstanten Faktor vergroßern: Zum Entwurf von Algorithmen fur Turing-maschinen mit z.B. logarithmisch beschranktem Speicher konnen wir uns nun derRegistermaschine bedienen.

Erst Rechner, wie die Quantenrechner, die ganzlich anders konzipiert sind, scheinen dieRobustheit der Klasse P erschuttern zu konnen.

12.5.1 Simulationen unter Turingmaschinen

k-Band TM gegen 1-Band TM

Satz 12.9 Jede t-zeit– und s-speicherbeschrankte r-Band-TM M laßt sich durch eineO (s · t)-zeit und O (s)-speicherbeschrankte 1-Band-TM M ′ mit einseitig unendlichem Ar-beitsband Schritt fur Schritt simulieren.

216

Page 219: Skript Waack merged

Beweis. Die Aussage ist eine unmittelbare Folgerung unserer Uberlegungen aus Ab-schnitt 12.4.7 und 12.4.3.

Aus Satz 12.9 folgt, daß sich beispielsweise die Komplexitatsklassen P, FP, NP, L undNL nicht veranderten, wenn man sich bei ihrer Definition auf 1-Band-TM beschrankte.

Der einfache nichtdeterministische Turingakzeptor ENTA

Die Turingmaschine wurde von Alan Turing 1936 mit dem Ziele eingefuhrt, algorithmischeBerechnungen von der Art zu formalisieren, wie sie ein Menschen ublicherweise durchfuhrt.Dieses

”Urmodell“ hatte nur ein einziges einseitig unendliches Band uber einem Alphabet

Σ, das als Eingabe-, Arbeits- und Ausgabeband diente.Wir greifen nun diese Form der Turingmaschine auf, beschranken uns auf Akzeptoren,

erlauben aber Nichtdeterminismus. Von dem Arbeitsalphabet Σ nehmen wir an, daß esdie Menge 0, 1 umfaßt. Aus technischen Grunden (siehe Beweis des Satzes 12.38) wirdder linke Rand des Bandes durch zwei Randbegrenzer ⊲ markiert. Wir werden sehen, daßder linke der beiden Randbegrenzer vom Lese-Schreib-Kopf der Maschine niemals besuchtwird. Wir sprechen von einfachen nichtdeterministischen Turingakzeptoren (ENTA).

Ist M ein ENTA, so ist die Uberfuhrungsrelation δM eine Teilmenge von

Q× (Σ ∪ ⊲, B)︸ ︷︷ ︸

Argumentteil

×Q× (Σ ∪ ⊲)× L, R, N︸ ︷︷ ︸

Wertteil

,

die die Eigenschaften aus Abschnitt 12.2 hat. Ist insbesondere (q, σ, q′, σ′, ρ) ∈ δM so gilt.

– Ist σ = ⊲, so ist σ′ = ⊲ und ρ 6= L.

– Stets ist σ′ 6= B.

Diese Vereinbarungen sichern, daß jede Konfiguration

| ⊲ |⊲ |σ1 |σ2 | . . . |σℓ |γ1 |γ2 | . . . |γr |B |B | . . .↑q

(12.15)

mit σi, γj ∈ Σ (i = 1, 2, . . . , ℓ, r = 1, 2, . . . , r) sich eindeutig als Wort

⊲ ⊲ σ1σ2 . . . σℓ q γ1γ2 . . . γr (12.16)

uber Σ ∪ ⊲ darstellen laßt. Die initiale Konfiguration auf eine Eingabe w1w2 . . . wn ∈0, 1n

| ⊲ |⊲ |w1 |w2 | . . . |wn |B |B | . . .↑q0

(12.17)

hat dann die Darstellung

⊲ q0 ⊲ w1w2 . . . wn. (12.18)

Aus den Ergebnissen des Abschnitts 12.4 ergibt sich leicht.

217

Page 220: Skript Waack merged

Satz 12.10 Jeder Polynomialzeit-NTA laßt sich durch einen Polynomialzeit-ENTA Schrittfur Schritt simulieren.

12.5.2 Registermaschinen gegen Turingmaschinen

Im Abschnitt 12.4 haben wir einige Techniken zur Programmierung von Turingmaschinenbesprochen. Mußten wir damit jeden effizienten Algorithmus, den wir bisher kennengelernthaben, auf Turingmaschinen implementieren, waren wir auf langere Zeit ausgelastet. Wirbrauchen Aussagen zur effizienten Simulation von Registermaschinen durch Turingmaschi-nen und umgekehrt. Durch sie werden unsere Erkenntnisse uber effiziente Algorithmen,die wir in dieser Vorlesung erworben haben, in die Welt der Turingmaschinen ubertragen:Alle dort besprochenen Probleme gehoren zur Komplexitatsklasse P, sofern es sich umEntscheidungsprobleme handelt, und zur Komplexitatsklasse FP andernfalls. Haben wirumgekehrt effiziente Algorithmen fur Turingmaschinen entworfen, so lassen sich diese mitertraglichem Verlust auf Registermaschinen ubertragen.

Um Registermaschinen mit Turingmaschinen fair vergleichen zu konnen, mussen wirjedoch statt des Einheitskostenmaßes das logarithmische Kostenmaß verwenden.

Registermaschinen mit logarithmischem Kostenmaß

Um unsere GRAM mit der Turingmaschine vergleichbar zu machen, mussen wir sie miteinem Ein– und einem Ausgabeband uber 0, 1 und den zugehorigen Befehlen ausrusten,die fur den Datenfluß zwischen dem Register R1 und den beiden Bandern sorgen:

INPUT Lesen eines Eingabesymbols.OUTPUT Schreiben eines Ausgabesymbols.MOVE L Bewegung des Eingabekopfes nach links.MOVE R Bewegung des Eingabekopfes nach rechts.

Die Elemente des Eingabealphabets 0, 1 werden mit den entsprechenden naturlichenZahlen identifiziert. Liest der Eingabekopf bei einer INPUT-Operation ein Symbol aus 0, 1,so wird die zugehorige Zahl in das Register R1 geschrieben. Eine OUTPUT-Operation schreibtR1 mod 2 auf das Ausgabeband.

Wie bereits im Abschnitt 12.1 dargelegt, benotigen wir neben dem Befehl END fur dasProgrammende noch die Befehle ACCEPT und REJECT. Sie stehen fur das akzeptierendebzw. verwerfende Ende einer Rechnung und werden eingesetzt, wenn es darum geht, Ent-scheidungsprobleme zu losen. Bei der Berechnung von Funktionen bleibt es bei dem BefehlEND.

Schließlich kann man in Analogie zur nichtdeterministischen Turingmaschine den Be-fehlssatz um den Befehl CHOICE r (r eines der Register R1-25) erweitern. Dieser Befehlinkrementiert den Befehlszahler PC und weist dem Register r den Wert 0 oder den Wert 1zu: Er rat ein Bit.

Das Einheitskostenmaß aus Abschnitt 7.2 hat zur Grundlage, daß die binare Lange derRegister- und Speicherzelleninhalte sowie der verwendeten Adressen die Verarbeitungsbrei-te des aktuellen Rechners nicht ubersteigt. Beim Studium der theoretischen Grundlagen

218

Page 221: Skript Waack merged

der Informatik ist eine solche Annahme nicht sinnvoll. Viele in der Praxis vorkommendeProbleme blieben unverstandlich. Wir benotigen das logarithmische Kostenmaß, das denRessourcenverbrauch einer Rechnung auch von der binaren Lange (siehe Abschnitt 1.1) derverwendeten Zahlen und Adressen abhangen laßt.

Wir betrachten die Registermaschine (GRAM) aus Abschnitt 7.1 ohne die Befehleder multiplikativen Arithmetik, die wir mit GRAM+ bezeichnen. (Den Grund fur diesenAusschluß besprechen wir spater. Einem besorgten Zeitgenossen, der einwenden mag, daßman ohne Multiplikation nicht auskomme, halten wir entgegen, daß wir bereits in der Schulegelernt haben, wie man die multiplikative auf die additive Arithmetik zuruckfuhrt.) Ist Xeine Speicherzelle oder ein Register, so bezeichnet λ(X) die binare Lange des Inhalts von X.Wir sprechen auch von der (aktuellen) binaren Lange des Registers bzw. der Speicherzelle.

Logarithmisches Zeitmaß. Die Ausfuhrung jedes Befehls aus Tabelle 7.1 benotigt sovieleZeittakte, wie die Summe der binaren Langen der beteiligten Register, Speicherzellen,Adressen und Konstanten angibt (siehe Tabelle 12.1). Die Befehle zur Kommunikationdes Registers R1 mit dem Eingabe– und dem Ausgabeband, zum Programmende undzum Raten eines Bits benotigen einen Zeittakt.

Programmende

END, ACCEPT, REJECT 1

Transportbefehle

LOAD r1,a(r2) λ(r1) + λ(r2) + λ(a)

STORE a(r1),r2 λ(r1) + λ(r2) + λ(a)

C-LOAD r,m λ(r) + λ(m)

Additive Arithmetik

ADD r1,r2,r3 λ(r1) + λ(r2) + λ(r3)

C-ADD r1,r2,m λ(r1) + λ(r2) + λ(m)

SUB r1,r2,r3 λ(r1) + λ(r2) + λ(r3)

Ordnung

SLT r1,r2,r3 λ(r1) + λ(r2) + λ(r3)

Sprunge

JMP r λ(r)

JAL r λ(r)

Verzweigungen

BEQ r,a λ(r) + λ(a)

BNQ r,a λ(r) + λ(a)

Tabelle 12.1: Logarithmische Zeitkosten der Assemblerbefehle der GRAM aus Tabelle 7.1

Um das logarithmisches Speichermaß fur die Rechnung einer GRAM auf eine Eingabesinnvoll zu definieren, mussen wir uns einige Gedanken mehr machen.

219

Page 222: Skript Waack merged

Seien

0 ≤α1 < α2< . . .< αh−1 <αh

−1 ≥β1 > β2> . . .> βs−1 >βs

die Adressen der Speicherzelle auf der Halde bzw. auf dem Laufzeitstapel (siehe Abbildung7.1), die im gesamten Verlauf der Rechnung benutzt werden, und seien µ(α1), µ(α2), . . .,µ(αh) bzw. µ(β1), µ(β2), . . ., µ(βs) die zugehorigen Speicherzellen selbst. Ist X ein Registeroder eine Speicherzelle, so bezeichnet λmax(X) das Maximum uber die λ(X), wobei uberjeden Zeitpunkt der Rechnung maximiert wird.

Zuerst denkt man daran, die Zahl

31∑

i=1

λmax(Ri) +

h∑

i=1

| bin αi| +

s∑

i=1

| bin−βi| +

h∑

i=1

λmax(µ(αi)) +

s∑

i=1

λmax(µ(βi))

(12.19)

als Speicherbedarf der in Rede stehenden Rechnung zu definieren. Man uberlegt sich aberleicht, daß man hier zu hoch greift. Griffe man namlich im Zuge der Rechnung auf denHauptspeicher der GRAM nur zu wie eine 1-Band-Turingmaschine auf ihr Arbeitsband,und betriebe man auf diese Weise die GRAM wie eine Turingmaschine, so hatte nach Term12.19 diese

”Turingmaschine“ einen Speicherbedarf, der um einen logarithmischen Faktor

großer ware, als der in Definition 12.2 festgelegte.Kleinmutig geworden, konnten man nun auf den Gedanken kommen, die Adressen bei

der Definition des Speicherbedarfs ganz wegzulassen und den Ausdruck

31∑

i=1

λmax(Ri) +h∑

i=1

λmax(µ(αi)) +s∑

i=1

λmax(µ(βi)) (12.20)

zu verwenden. Dann allerdings ware man in der Lage, durch Auswahl nur weniger Regi-ster aus einem großen Bereich zusatzlich Informationen speichern, ohne den Speicherbedarfdafur vollstandig in Rechnung gestellt zu bekommen. Die Zahl m etwa ware mit Speicher-bedarf eins darzustellen: Die Speicherzelle µ(m) erhalt den Wert eins, die Speicherzellenµ(i) bleiben fur i = 0, 1, . . . , m − 1 unberuhrt. Erst µ(−1) ist wieder benutzt. Allgemeinkonnten die Abstande zwischen den benutzten Speicherzellen als impliziter dafur aber fastkostenloser Speicher angesehen werden. Eine solche Definition ware verfehlt.

Die Losung liegt in der Mitte. Wir definieren

31∑

i=1

λmax(Ri) +

h∑

i=1

| bin(αi − αi−1)| +s∑

i=1

| bin(βi−1 − βi)| +

h∑

i=1

λmax(µ(αi)) +

s∑

i=1

λmax(µ(βi))

(12.21)

als den Speicherbedarf der Rechnung, wobei α0 := 0 und β0 := −1 ist. Wir erreichen da-durch, daß die GRAM+, wenn sie wie eine 1-Band-TM betrieben wird, auch den Speicherbe-darf gemaß Definition 12.2 hat. Ferner vermeiden wir den im vorigen Absatz beschriebenenEffekt.

220

Page 223: Skript Waack merged

Wechselseitige Simulation von GRAM+ und TM

Nun sind wir in der Lage, die Aussagen zur wechselseitigen Simulation von Register- undTuringmaschinen formulieren zu konnen. Auf Beweise wollen wir verzichten. Der interes-sierte Leser findet sie in [Rei99].

Satz 12.11 (Simulation von GRAMs durch TM) Sei R eine im logarithmischen Maßt-zeit- und s-speicherbeschrankte GRAM+. Dann existiert eine O (s · t)-zeit- und O (s)-speicherbeschrankte DTM, die R simuliert.

Warum haben wir auf die Befehle der multiplikativen Arithmetik verzichtet? Andern-falls laßt sich Satz 12.11 nicht beweisen.

Satz 12.12 (Simulation von TM durch GRAMs) Eine t-zeit- und s-speicherbeschrank-te DTM kann durch eine GRAM+ simuliert werden, die

1. im Einheitskostenmaß O (t)-zeit- und O (s)-speicherbeschrankt ist;

2. im logarithmischen Kostenmaß O (t · log s)-zeit- und O (s)-speicherbeschrankt ist.

Wann arbeitet eine GRAM+ mit o(n)-beschranktem Speicher?

Die”Programmierung“ von Turingmaschinen ist auch unter Einsatz der Techniken aus

Abschnitt 12.4 sperrig. Indem wir Satz 12.11 nutzen, konnen wir uns auf die GRAM+

mit Ein- und Ausgabeband zuruckziehen. Wann arbeitet ein Algorithmus auf der GRAM+

unter Verwendung des logarithmischen Kostenmaßes o(n)-speicherbeschrankt? Wir behan-deln exemplarisch eine hinreichende Bedingung dafur, daß der Speicherbedarf ein O (log n)ist. Sei dazu n die binare Lange der Eingabe.

– Weder die Eingabe noch in der Regel die Ausgabe konnen intern vollstandig gespei-chert werden. Man muß vielmehr den Speicheraufwand fur die Ein- und die Aus-gabe vom Speicherbedarf der Rechnung trennen. Letzterer muß sich logarithmischbeschranken lassen.

Es konnen nur jeweils O (log n) Bits der Eingabe zu einer Zeit im Hauptspeichergehalten werden.

Zur Berechnung eines Ausgabebits kann man nur auf O (log n) bisher schon ausge-gebene Bits zugreifen, denn nur dazu reicht der Arbeitsspeicher.

– Zu jedem Zeitpunkt ist die Summe der binaren Langen der Datenfelder samtlicherObjekte auf der Halde ein O (log n). Die großte wahrend der Laufzeit vergebeneAdresse auf der Halde ist ein nO(1).

– Bei der Auswertung eines beliebigen arithmetischen Ausdrucks mussen alle dabei auf-tretenden Zwischenergebnisse mit O (log n) Bits darstellbar sein. (Wir gehen davonaus, daß diese Zwischenergebnisse in einem Register stehen.)

221

Page 224: Skript Waack merged

– Zu jeder Zeit der Rechnung muß die im logarithmischen Kostenmaß gemessene Hohedes Laufzeitstapel ein O (log n) sein. Das ist insbesondere dann der Fall, wenn

– zu jeder Zeit hochstens O (1) Rahmen auf dem Laufzeitstapel liegen;

– bei jedem Methodenaufruf jeder Aktualparameter und jede lokale Variable mitO (log n) Bits darstellbar ist.

Alternativ kann die Anzahl der Inkarnationsrahmen auf dem Laufzeitstapel auchein O (log n) sein. Dann muß jeder Aktualparameter, jede lokale Variable und jedesRegister durch O (1) viele Bits darstellbar sein.

Wir betrachten als Beispiel das im Abschnitt 12.2 eingefuhrte Graph-Accessibility-Problem GAP. Es liegt in NL. Welche deterministische Speicherkomplexitat hat diesesProblem?

Satz 12.13 (Satz von Savitch) Es ist GAP ∈ DSPACE(log2 n

).

Beweis. Sei G = (1, 2, . . . , m, E) ein gerichteter Graph auf der Knotenmenge 1, 2, . . . , m.Wir bemerken folgendes. Fur zwei Knoten x 6= y ∈ 1, 2, . . . , m

1. hat jeder gerichteten Weg von x nach y in G die Lange kleiner oder gleich m;

2. gibt es einen gerichtete Weg von x nach y in G der Lange kleiner oder gleich k(2 ≤ k ≤ m), wenn es einen Mittelknoten z mit den folgenden Eigenschaften gibt:

– Die Knoten x und z sind in G durch einen gerichteten Weg der Lange kleineroder gleich ⌊k/2⌋ verbunden.

– Es gibt in G einen gerichteten Weg der Lange kleiner oder gleich ⌈k/2⌉ von znach y.

Wir entwerfen nun auf der GRAM+ mit logarithmischem Kostenmaß einen AlgorithmusDPATH(x, y, k) returns 0, 1

mit der folgenden Spezifikation: Angesetzt auf G gibt DPATH(x, y, k) gibt genau dann 1zuruck, wenn es in G einen gerichteten Pfad von x nach y der Lange kleiner oder gleich kgibt. Anderfalls wird 0 zuruckgegeben.

Algorithmus DPATH(x, y, k)

Großschritt 1. [Basis]Falls x = y, return 1.Falls k = 1, so fuhre aus.

Falls (x, y) ∈ E, return 1.Andernfalls return 0.

Großschritt 2. [Rekursion]b← 0

222

Page 225: Skript Waack merged

Fur z = 1, 2, . . . , m fuhre aus.bb← DPATH(x, z, ⌊k/2⌋) ∧ DPATH(z, y, ⌈k/2⌉)b← b ∨ bb

return b.

Zur Laufzeit von DPATH(x, y, k) sind samtliche vorkommenden Variablen in ihrer binarenLange durch eine Funktion aus O (log m) beschrankt. Aus Gleichung 1.4 folgt, daß auf demLaufzeitstapel zu keiner Zeit mehr als ⌈log2 k⌉ Inkarnationsblatter der Methode DPATH lie-gen. Folglich hat DPATH(x, y, k) einen durch O (log2 m · log2 k) beschrankten Speicherbe-darf.

Angesetzt auf G entscheidet DPATH(1, m, m), ob es in G einen gerichteten Weg von 1nach m gibt. Das geschieht mit O

(log2 m

)beschranktem Speicher.

Der Algorithmus DPATH aus dem Beweis von Satz 12.13 hat relativ weitreichende Aus-wirkungen.

Korollar 12.14 Fur jede von uns betrachtete Speicherschranke s ist

NSPACE (s(n)) ⊆ DSPACE(s2(n)

).

Der Beweis von Korollar 12.14 wird mit der sogenannten Erreichbarkeitstechnik gefuhrt,die hier kurz skizziert werden soll. (Wer es genauer wissen will, der sei auf [Pap94], Ab-schnitt 7.3 verwiesen.) Ist M ein s-speicherbeschrankter NTA und x ∈ 0, 1n eine Eingabe— wegen Satz 12.9 konnen wir uns auf einen 1-Band-NTA beschranken —, so definiert manden Graphen der partiellen Konfigurationen von M auf x wie folgt:

– Die Knoten sind die partiellen Konfigurationen von M auf Eingaben der Lange |x|.Aus einer Konfiguration von M auf die Eingabe x

C := (q, (x, k0), (u1, k1))

mit |u1| ≤ s(|x|) (siehe Defintion 12.2, Gleichung 12.4) erhalt man eine partielleKonfiguration, indem man die Eingabe x weglaßt:

C := (q, k0, (u1, k1)) .

Als Restriktion bleibt fur die naturliche Zahl k0, die die Position des Lesekopfes aufdem Eingabeband beschreibt, die Ungleichungskette 0 ≤ k0 ≤ |x|+ 1 bestehen.

– Seien D = C und D′ := C ′ zwei partielle Konfiguration, wobei C und C ′ zweiKonfigurationen von M auf x sind. Dann ist D mit D′ durch eine Kante im Graphender partiellen Konfigurationen von M auf x verbunden, wenn C ⊢ C ′ ist.

Fur den Graphen der partiellen Konfigurationen von M auf x gilt offenbar folgendes:

223

Page 226: Skript Waack merged

– Jeder Knoten laßt sich mit O (s(|x|))-beschrankten Speicher auf einem Arbeitsbanddarstellen. Hatte man die Eingabe aus der Konfiguration nicht gestrichen, ginge dasfur sublineare Speicherschranken s nicht.

– Der NTA M akzeptiert die Eingabe x genau dann, wenn es in dem Graphen einengerichteten Weg von der initialen partiellen Konfiguration zu einer terminalen gibt.

Zum Beweis von Korollar 12.14 wird M auf x simuliert, indem man den AlgorithmusDPATH auf den Graphen der partieller Konfigurationen von M auf x anwendet. Das geht,weil die aktuelle vollstandige Konfiguration von M auf x mit s-beschranktem Speichergehalten werden kann: Die Eingabe x steht auf dem Eingabeband, die aktuelle partielleKonfiguration ist intern gespeichert.

Aus Korollar 12.14 folgt sofort.

Korollar 12.15 Es istPSPACE = NPSPACE.

12.6 Konstruierbarkeit

Man mag sich daran stoßen, daß unser Akzeptierungsbegriff aus Definition 12.2 sowohl furzeit- als auch fur speicherbeschrankte Berechnungen so großzugig ist: Nur die gunstigstenakzeptierenden Rechnungen zahlen. Abhilfe schaffen die folgenden beiden Begriffe.

Definition 12.16 – Eine Zeitschranke t heißt konstruierbar, wenn es eine determini-stische k-Band Turingmaschine gibt, die angesetzt auf eine beliebige Eingabe derLange n ≥ 1 die Zeichenkette bin t(n) auf einem Arbeitsband berechnet und dafurinsgesamt nur O (t(n)) Schritte benotigt.

– Eine Speicherschranke s heißt konstruierbar, wenn es eine deterministische k-BandTuringmaschine gibt, die angesetzt auf eine beliebige Eingabe der Lange n ≥ 1die Zeichenkette bin s(n) auf einem Arbeitsband berechnet und dafur insgesamt nurO (s(n)) Speicherzellen auf den Arbeitsbandern benotigt.

Fur eine Ressourcenschranke f gilt offenbar folgendes. Ist f als Zeitsschranke konstruier-bar, so ist f auch als Platzschranke konstruierbar. Man kann dazu dieselbe TuringmaschineM nehmen. Da M O (f(n))-zeitbeschrankt ist, kann sie auch nur O (f(n)) Speicherzellenbenutzen.

Zunachst hat man den Eindruck, daß Konstruierbarkeit eine recht exklusive Eigenschaftfur Komplexitatsschranken sein muß. Gemessen an der Gesamtheit aller nur denkbarenSchranken ist das auch der Fall. Aber alle wichtigen Ressourcenschranken sind konstruier-bar. Wir begnugen uns mit einigen Beispielen.

Lemma 12.17 Sowohl die Speicherschranke ⌊log2 n⌋ als auch die Speicherschranke ⌈log2 n⌉sind konstruierbar

224

Page 227: Skript Waack merged

Beweis. Wir begnugen uns mit der Speicherschranke ⌊log2 n⌋. Aus Lemma 1.10 wissenwir, daß ⌊log2 n⌋ = | bin n|+ 1 ist.

Wir beschreiben eine Turingmaschine M , die das Gewunschte leistet. In ihrer erstenPhase richtet M auf einem Arbeitsband einen Zahler Z mit dem Anfangswert 0 ein. Nunlauft M die Eingabe x der Lange n ab und inkrementiert fur jedes gelesene Bit den Zahler.Hat M die Eingabe gelesen, ist der Zahlerinhalt gleich |x| = n, binar dargestellt. Wirwissen, daß die binare Lange dieses Zahlers um eins vergroßert gleich ⌊log2 n⌋ ist. Deshalbist es zielfuhrend, wenn M in einer zweiten Phase den Zahler Z um ein beliebiges Bitverlangert und mit dieser Zeichenkette nochmals das gleiche macht wie soeben mit derEingabe. Der Inhalt dieses zweiten Zahlers ist dann die Binardarstellung von ⌊log2 n⌋.

Der Speicherbedarf von M wird dominiert von der maximalen Lange des ersten Zahlers.

Lemma 12.18 Fur jedes feste naturliche k ≥ 1 ist die Zeitschranke nk konstruierbar.

Beweis. Wir fuhren den Beweis induktiv uber k.Anfang: k = 1. Die Turingmaschine M1 verhalt sich so wie die Maschine aus dem

Beweis von Lemma 12.17 in ihrer ersten Phase. Die Aussage uber die Rechenzeit habenwir in Abschnitt 11.2.4 bewiesen.

Schritt: k auf k + 1. Die Maschine Mk+1 simuliert zunachst Mk. Danach befindet sichdas Wort bin nk auf einem Arbeitsband. Wir fassen dieses Arbeitsband als AbwartszahlerA mit dem Inhalt nk auf. Nun simuliert M nk mal die Maschine M1, wobei der Zahler Zden M1 inkrementiert, bei jeder neuen Iteration nicht zuruckgesetzt wird.

Ist A gleich null und die letzte Simulation von M1 abgeschlossen, so ist der Inhalt desBinarzahlers Z gleich nk+1.

Die Rechenzeit ist nach Abschnitt 12.4.6 O(nk+1 + nk

)= O

(nk+1

).

Satz 12.19 Sei t eine konstruierbare Zeitschranke. Dann laßt sich jeder t-zeitbeschrank-te NTA M ′ durch einen O (t)-zeitbeschrankten NTA M simulieren, dessen samtliche Re-chengange eine Lange haben, die ein O (t) ist.

Beweis. Angesetzt auf eine Eingabe x der Lange n richtet M auf einem zusatzlichenArbeitsband einen Abwartszahler A ein und initialisiert ihn mit der Binardarstellung vont(n). Das ist in Zeit O (t(n)) moglich, da die Zeitschranke t konstruierbar ist.

Nun simuliert M den NTA M ′ Schritt-fur-Schritt, dekrementiert aber nach jedem simu-lierten Schritt den Zahler A um eins. Solange der Zahler noch nicht gleich null ist, verhaltsich M was die Akzeptierung oder Verwerfung angeht wie M ′. Ist der Zahlerstand dagegengleich null, und hat der letzte Schritt nicht zu einem terminalen Zustand gefuhrt, verwirftM wegen Zeituberschreitung.

Diese Verwerfungen sind unschadlich, weil alle von M ′ akzeptierten Eingaben x eineakzeptierende Berechnung haben, deren Lange kleiner oder gleich t(|x|) ist.

225

Page 228: Skript Waack merged

Satz 12.20 Sei s eine konstruierbare Speicherschranke. Dann laßt sich jeder s-speicher-beschrankte NTA M ′ durch einen O (s)-speicherbeschrankten NTA M simulieren, dessensamtliche Rechengange nur O (s)-beschrankten Speicher benotigen.

Beweis. Zunachst konnen wir gemaß Abschnitt 12.4.3 annehmen, daß alle Arbeitsbandervon M ′ nur einseitig unendlich sind.

Angesetzt auf eine Eingabe x der Lange n berechnet M auf einem zusatzlichen Arbeits-band die Binardarstellung von s(n). Das geht in O (s(n))-beschranktem Speicher, da s einekonstruierbare Speicherschranke ist. Anschließend markiert M auf allen Arbeitsbandernvon M ′ auf einer zusatzlichen Spur gemaß Abschnitt 12.4.4 Anfangsstucke der Lange s(n).

Nun simuliert M den NTA M ′ Schritt-fur-Schritt und verhalt sich dabei was die Akzep-tierung oder Verwerfung angeht wie M ′. Versucht die Simulation von M ′ dagegen, einenmarkierten Bereich zu verlassen, so verwirft M wegen Speicheruberschreitung.

Diese Verwerfungen sind unschadlich, weil alle von M ′ akzeptierten Eingabe x eineakzeptierende Berechnung haben, die mit Speicherbedarf kleiner oder gleich t(|x|) auskom-men.

Bemerkungen.

• Als unmittelbare Folgerung aus dem Inhalt dieses Abschnitts erhalten wir, daß furkonstruierbare Zeit- bzw. Speicherschranken die zugehorige deterministische Kom-plexitatsklasse abgeschlossen gegenuber Komplementbildung ist: Gehort eine formaleSprache L dazu, so auch ihr Komplement 0, 1∗ \ L.

• Fur nichtdeterministische Speicherkomplexitatsklassen NSPACE (s) gilt ebenfalllsdie Abgeschlossenheit gegenuber Komplementbildung. Der Beweis ist jedoch nichttrivial.

• Fur nichtdeterministische Zeitkomplexitatsklassen gilt die Abgeschlossenheit gegenuberKomplementbildung dagegen als sehr unwahrscheinlich. Insbesondere ist das fur dieKlasse NP beachtlich.

12.7 Hierarchiesatze

Aus der Programmierpraxis ist die Evidenz fur die folgenden beiden Aussagen uberwalti-gend.

Satz 12.21 (Zeithierarchiesatz) Seien t und T Zeitschranken, und sei die ZeitschrankeT konstruierbar.

Ist t · log t = o(T ), so ist

DTIME (t) ⊂ DTIME (T ) .

Satz 12.22 (Speicherhierarchiesatz) Seien s und S Speicherschranken, und sei dieSpeicherschranke S konstruierbar.

226

Page 229: Skript Waack merged

Ist s = o(S), so ist

DSPACE (s) ⊂ DSPACE (S) .

Bemerkungen.

• Man beachte unsere generelle Voraussetzungen uber Ressourcenschranken vom Endevon Abschnitt 12.2.

• Was die Beweise angeht, so stelle man sich nicht vor, daß man von einer interes-santen Sprache z.B. aus DSPACE (S) zeigt, daß sie nicht in DSPACE (s) liegt.Der Kern der Beweise ist vielmehr ein Diagonalisierungsargument. Der Nachweis un-terer Schranken fur konkret definierte Probleme ist bis auf wenige Ausnahmen einungelostes Problem.

• Auch fur nichtdeterminitische Komplexitatsklassen kann man ahnliche Hierarchiesatzebeweisen.

12.8 Many-One-Reduzierbarkeit, Vollstandigkeit

Seien L1 und L2 zwei formale Sprachen uber dem Alphabet 0, 1. Wir suchen nach einemBegriff, der uns die Aussage

”Die Sprache L1 ist algorithmisch nicht schwerer zu entscheiden als die Sprache L2.“

formalisiert.

Definition 12.23 Sei f : 0, 1∗ → 0, 1∗ eine vermoge eines TT berechenbare Funktion.Die Sprache L1 heißt langs der Funktion f auf die Sprache L2 reduzierbar, wenn fur alleWorter w ∈ 0, 1∗ die Aquivalenz

w ∈ L1 ⇐⇒ f(w) ∈ L2

erfullt ist.

Sei A2 ein Algorithmus, der die formale Sprache L2 entscheidet. Dann ist Algorithmus12.24 fur jedes Wort w ∈ 0, 1∗ ein Entscheidungsalgorithmus fur die Sprache L2. Verwen-det man diesen Algorithmus, so lost Definition 12.23 unser Formalisierungsproblem, wenndie Berechnungskomplexitat der Funktion f gegenuber der Komplexitat des AlgorithmusA2 nicht ins Gewicht fallt.

Algorithmus 12.24 (Allgemeiner Reduktionsalgorithmus)

Großschritt 1:Berechne f(w).

Großschritt 2:Entscheide mit Hilfe des Algorithmus A2, ob f(w) ∈ L2 ist.

227

Page 230: Skript Waack merged

Die Reduzierbarkeit mit Hilfe einer Funktion f nennt man many-one-Reduzierbarkeit :Ein Element w′ aus 0, 1∗ kann fur mehrere w — die Urbilder von w′ unter f — dazudienen, die Frage w ∈ L1? zu beantworten. Kann f als injektive Funktion gewahlt werden,so spricht man von einer one-one-Reduzierbarkeit.

Definition 12.25 Eine formale Sprache L1 ist auf eine formale Sprache reduzierbar inpolynomialer Zeit (alternative Bezeichnung: FP-reduzierbar), falls es eine Funktion f ∈ FPgibt, langs derer L1 auf L2 reduzierbar ist. (Bezeichnungen: L1 ≤pol L2 oder L1 ≤FP L2 .)

Definition 12.26 Eine formale Sprache L1 ist auf eine formale Sprache logspace-reduzierbar(alternative Bezeichnung: FL-reduzierbar), falls es eine Funktion f ∈ FL gibt, langs dererL1 auf L2 reduzierbar ist. (Bezeichnungen: L1 ≤log L2 oder L1 ≤FL L2 .)

Lemma 12.27 Die Logspace-Reduzierbarkeit impliziert die Polynomialzeit-Reduzierbarkeit.

Beweis. Die Aussage ist eine unmittelbare Folgerung aus Lemma 12.7.

Lemma 12.28 Sowohl die Logspace-Reduzierbarkeitsrelation als auch die Polynomialzeit-Reduzierbarkeitsrelation sind transitiv.

Beweis. Die Aussage ist eine unmittelbare Folgerung aus Lemma 12.8 bzw. Lemma 12.6.

Lemma 12.29 Ist L1 ≤FP L2, so gelten die folgenden Implikation.

L2 ∈ PSPACE =⇒ L1 ∈ PSPACE

L2 ∈ NP =⇒ L1 ∈ NP

L2 ∈ P =⇒ L1 ∈ P

Das heißt, diese Komplexitatsklassen sind unter der Relation ≤FP und damit auch unterder Relation ≤FL abgeschlossen.

Beweis. Die drei Aussagen haben analoge Beweise. Wir beschranken uns auf die Abge-schlossenheit der Klasse P. Dieser Beweis wiederum ist dem von Lemma 12.6 sehr ahnlich.

Sei M ein TT, der eine Funktion f ∈ FP in nk-beschrankter Zeit berechnet, langsderer sich die Sprache L1 auf die Sprache L2 reduziert laßt. Sei ferner M2 ein DTA, der dieSprache L2 in nℓ-beschrankter Zeit akzeptiert. Wir konstruieren einen DTA M1, der dieformale Sprache L1 akzeptiert.

Angesetzt auf eine Eingabe x simuliert M1 in einer ersten Phase Schritt-fur-Schritt M ,wobei er ein zusatzliches Arbeitsband als Hilfsausgabeband nutzt.

Anschließend simuliert M1 Schritt-fur-Schritt M2, wobei das zusatzliche Arbeitsbandnun als Hilfseingabeband dient.

Man uberlegt sich sofort, daß die Laufzeit von M auf jede Eingabe der Lange n, die zuL1 gehort, durch nk + nk·ℓ nach oben beschrankt ist.

228

Page 231: Skript Waack merged

Lemma 12.30 Ist L1 ≤FL L2, so gilt die Implikation

L2 ∈ NL =⇒ L1 ∈ NL.

Das heißt, die Komplexitatsklasse NL ist unter der Relation ≤FL abgeschlossen.

Beweis. Der Beweis verwendet den Trick aus dem Beweis von Lemma 12.8.Sei M ein TT, der eine Funktion f ∈ FL, langs derer sich die Sprache L1 auf die

Sprache L2 reduzieren laßt, mit O (log n)-beschranktem Speicher berechnet. Sei ferner M2

ein O (log n)-speicherbeschrankter NTA, der die Sprache L2 akzeptiert.Wir beschreiben einen NTA M1, der angesetzt auf eine Eingabe x den NTA M2 ange-

setzt auf f(x) Schritt-fur-Schritt simuliert. Dazu halt M auf einem zusatzlichen Arbeits-band einen Zahler fur den Index des nachsten Bits von f(x), der von M2 gelesen werdenmuß.

Simulation des Leseschritts von M2. M1 erzeugt auf einem zusatzlichen Arbeitsbandeine Arbeitskopie z von z und startet eine Simulation von M angesetzt auf x. Allerdingswird, sofern die simulierte Maschine M ein Bit ausgeben will, diese Ausgabe unterdruckt.Es wird lediglich der Zahler z dekrementiert. Ist der Zahlerstand gleich null, so ist das Bit,das bei M gerade zur Ausgabe anstunde, das gesuchte Bit von f(w).

Simulation der Bewegung des Lesekopfes von M2. Im wesentlichen wird der Zahlerz inkrementiert bzw. dekrementiert. Allerdings muß vor jeder Inkrementierung getestetwerden, ob f(x) uberhaupt ein solches Bit hat. Das geschieht in einer Weise, die zurSimulation des Leseschritts von M2 analog ist.

Die Simulation der Aktionen von M2 auf seinen Arbeitsbandern erfolgt direkt. Dafurhat M1 zusatzliche Arbeitsbander in gleicher Zahl.

Fur jedes x hat der Wert f(x) eine Lange, die durch ein Polynom in |x| beschranktist. Folglich benotigt die Darstellung des Zahlers z nur O (log |x|)-beschrankten Platz.Fur jedes x mit f(x) ∈ L2 gibt es eine akzeptierende Rechnung von M2 auf f(x), die mitO (log |f(x)|) = O (|x|) beschranktem Speicher auskommt. Die Simulation dieser Rechnungdurch M1 sichert, daß die Speicherschranke respektiert wird.

Definition 12.31 Sei ≤ eine transitive Reduzierbarkeitsrelation fur formale Sprachen undC eine Komplexitatsklasse formaler Sprachen, die bzgl. der Relation ≤ abgeschlossen ist.

1. Eine formale Sprache L heißt C-hart bzgl. der Reduzierbarkeitsrelation ≤, wenn furjedes L′ aus C die Relation L′ ≤ L gilt.

2. Eine formale Sprache L heißt C-vollstandig bzgl. der Reduzierbarkeitsrelation ≤,wenn L bzgl. ≤ C-hart ist und uberdies L zu C gehort.

Bei der Anwendung von Definition 12.31 muß man Vorsicht walten lassen. Ein vollstandi-ges Problem einer Komplexitatsklasse soll ein im intuitiven Sinne schwerstes Problem die-ser Klasse sein und somit Informationen uber die Komplexitatsklasse selbst liefern. Ist der

229

Page 232: Skript Waack merged

Reduktionsbegriff zu stark, so gelingt das nicht: Jede einelementige Sprache ist beispiels-weise L-vollstandig bzgl. Logspace-Reduktionen und P-vollstandig bzgl. Polynomialzeit-Reduktionen.

Im weiteren bezieht sich der Begriff der

– NP-Vollstandigkeit und PSPACE-Vollstandigkeit immer auf Polynomialzeit-Re-duktionen;

– NL-Vollstandigkeit immer auf Logspace-Reduktionen.

Beispiele.

• GAP1 ist L-vollstandig. (Naturlich ist diese Aussage nur fur eine schachere als dieLogspace-Reduktion sinnvoll.)

• GAP ist NL-vollstandig.

• Das Rucksack-Entscheidungsproblem KNAPSACK ist NP-vollstandig. Weitere Bei-spiele werden wir im Verlauf dieses Kapitels kennenlernen.

• QBF ist PSPACE-vollstandig.

Welche Bedeutung haben (naturliche und interessante) vollstandige Probleme von Kom-plexitatsklassen in der Theoretischen Informatik?

Einerseits bringt man durch die Ermittlung eines interessanten vollstandigen Problemsdie Information, die in der Klasse steckt, gewissermaßen auf den Punkt. Am Entscheidungs-problem GAP1 kann man z.B. sehr gut sehen, was eine logarithmisch speicherbeschrankteRechnung zu leisten vermag. Erst vollstandige Probleme machen Komplexitatsklassen be-sonders interessant.

Andererseits ist die Vollstandigkeit eines Problems fur eine als sehr reichhaltig ange-sehene Komplexitatsklasse Ausweis der Schwierigkeit des Problems. Spiel-Liebhaber zumBeispiel, die mit Sokoban Probleme haben, konnen sich damit trosten, daß dessen kanoni-sche Entscheidungsvariante PSPACE-vollstandig ist.

Bemerkung. Eine transitive Reduktionsrelation ≤ definiert vermoge

L ≡ L′ ⇐⇒ L ≤ L′ und L′ ≤ L

auf der Menge aller formalen Sprachen uber 0, 1 eine Aquivalenzrelation. Es folgt sofort,daß diese Aquivalenzrelation bzgl. der Reduktionsrelation ≤ eine Kongruenzrelation ist:Sind [L] und [L′] zwei Aquivalenzklassen bzgl. ≡ und ist L ≤ L′, so ist L1 ≤ L2 fur alleL1 ∈ [L] und alle L2 ∈ [L′].

Folglich laßt sich die Relation ≤ auf die Aquivalenzklassen bzgl. ≡ durch reprasentan-tenweise Definition ubertragen:

[L] ≤ [L′] ⇐⇒ L ≤ L′.

Es ist leicht einzusehen, daß auf den Aquivalenzklassen bzgl. ≡ die Relation ≤ eine Halb-ordnung ist. In diesem Zusammenhang heißen die Aquivalenzklassen auch Grade.

230

Page 233: Skript Waack merged

Die NP-vollstandigen und die PSPACE-vollstandigen Probleme beispielsweise bildenden Grad NP-C bzw. den Grad PSPACE-C bzgl. der Polynomialzeitaquivalenz ≡FP.Aus Satz 12.32 ergibt sich sofort, daß NP-C kleiner oder gleich PSPACE-C ist.

12.9 Das Verhaltnis von Determinismus zu Nichtde-

terminismus

Wir haben bereits im Abschnitt 12.1 gesagt, daß das Verhaltnis von Determinismus zuNichtdeterminismus zu den wichtigsten Fragen der Theoretischen Informatik gehort. Es istdie Frage danach, ob Raten unter bestimmten Bedingungen etwas nutzt.

Warum ist NPSPACE = PSPACE? Die polynomiale Speicherschranke ist so schwach,daß Algorithmen die nur ihr gehorchen, außerordentlich machtig sind: Alles was man sinn-voller Weise raten kann, kann man auch ausprobieren.

Eine duale Aussage gilt fur Komplexitatsklassen, die durch außerordentlich strengeRessourcenbeschrankungen definiert sind. In solchen Fallen kann man beweisen, daß Ratenetwas nutzt. Wir haben leider nicht die Zeit, darauf naher einzugehen.

Wir haben zwei noch offene sogenannte N-ND-Probleme kennengelernt:

Das L-NL-Problem. Ist die Inklusion L ⊆ NL echt?

Das P-NP-Problem. Ist die Inklusion P ⊆ NP echt?

In beiden Fallen vermutet man eine positive Antwort. Im Falle des P-NP-Problemsgeht man sogar davon aus. Nach Satz 12.32 konzentrieren wir uns auf das P-NP-Problem.

Satz 12.32 Es ist

L ⊆ NL ⊆ P ⊆ NP ⊆ PSPACE.

Beweis. Die einzige nichttriviale Inklusion ist NL ⊆ P. Zu ihrem Beweise genugt es,fur das NL-vollstandige Problem GAP einen Polynomialzeitalgorithmus anzugeben. EineTiefensuche leistet das.

Bemerkung. Aus Satz 12.22 weiß man, daß die Inklusion L ⊆ PSPACE echt ist. EineInklusion des Turmes der Komplexitatsklassen aus Satz 12.32 ist folglich ebenfalls echt,aber man weiß nicht welche.

12.10 Die NP-Vollstandigkeit von SAT

Sei V := x1, x2, . . . eine abzahlbare Menge Boolescher Variablen und seinen ∧, ∨ und ¬die Symbole fur die logischen Operationen Konjunktion, Disjunktion bzw. Negation. (EineVariable heißt Boolesch, wenn sie nur Werte aus 0, 1 annehmen kann.)

231

Page 234: Skript Waack merged

Definition 12.33 Die Menge der vollstandig geklammerten Booleschen Formeln in denVariablen V ist wie folgt rekursiv defininiert.

Anfang. Samtliche Variablen aus V und die Konstanten 0 und 1 sind vollstandig geklam-merte Boolesche Formeln.

Rekursion. Sind F , F1 und F2 vollstandig geklammerte Boolesche Formeln, so auch (¬F ),(F1 ∧ F2) und (F1 ∨ F2).

Eine Boolesche Formel F heißt Formel uber der Variablenmenge x1, x2, . . . , xn, wenn nurVariablen aus dieser Menge in der Darstellung von F vorkommen.

Statt (¬F ) schreibt man gerne F . Das gilt besonders fur den Fall, daß F lediglicheine Boolesche Variable oder eine Konstante ist. Fur die Negation einer Variablen x ist inbestimmten Zusammenhangen die Bezeichnung x0 ublich. Dann steht x1 fur die Variablex selbst. Das Operationssymbol fur die Konjunktion wird oft weggelassen.

Die Semantik, die jeder vollstandig geklammerten Booleschen Formel F eine BoolescheFunktion zuordnet, ist jedem gelaufig: Ist F = F (x1, x2, . . . , xn) eine Boolesche Formeluber x1, x2, . . . , xn, so liefert jede Belegung

β : x1, x2, . . . , xn → 0, 1

der in Rede stehenden Variablenmenge mit Booleschen Werten auf naturliche Weise einenWert b ∈ 0, 1 der Formel F auf diese Belegung. Wir schreiben dafur

F (β(x1), β(x2), . . . , β(xn)) = b

oder

β(F ) = b.

Auf diese Weise stellt F eine Boolesche Funktion

f : 0, 1n → 0, 1

dar. Haufig identifizieren wir die dargestellte Funktion mit der darstellenden Formel.Auf Grund der ublichen Bindungsregel (Negation vor Konjuktion vor Disjunktion) und

der Assoziativitat von Konjunktion und Disjunktion geht man von vollstandig geklammer-ten Booleschen Formeln gerne zu (unvollstandig geklammerten) Booleschen Formeln uber.So steht beispielsweise

x1 ∧ x2 ∨ x4 ∧ x9

fur

((x1 ∧ x2) ∨ ((¬x4) ∧ x9)).

232

Page 235: Skript Waack merged

Definition 12.34 Eine Boolesche Formel F uber x1, x2, . . . , xn heißt genau dann erfull-bar, wenn die dargestellte Funktion nicht identisch null ist. Eine der Belegung der Variablenx1, x2, . . . , xn, die zum Funktionswert 1 fuhrt, heißt erfullende Belegung der Formel F .

Wir wollen Boolesche Formeln zum Gegenstand von Rechnungen auf Turingmaschi-nen machen. Wir mussen deshalb die Menge F aller Booleschen Formeln in V uber demAlphabet 0, 1 codieren.

Erster Schritt. Zunachst codieren wir die Menge V wie folgt uber dem Alphabet 0, 1, x:

V −→ 0, 1, x

xi 7→ x bin(i).

Dadurch sind die Booleschen Formel bereits endlich reprasentiert:

F ⊂ 0, 1, x,∧,∨,¬, (, )∗.

Zweiter Schritt. Um zu einer Darstellung uber 0, 1 zu kommen, verwenden wir denfolgenden Blockcode.

0, 1, x,∧,∨,¬, (, ) −→ 0, 13

0 7→ 000

1 7→ 001

x 7→ 010

∧ 7→ 011

∨ 7→ 100

¬ 7→ 101

( 7→ 110

) 7→ 111.

Wir sind in besonderem Maße an Booleschen Formeln mit spezieller Syntax interessiert.

Definition 12.35 1. Boolesche Variablen und deren Negationen heißen Literale.

2. Ein Literal y widerspricht einem Literal z, wenn es eine Variable xi so gibt, daßy, z = xi,¬xi ist.

3. Eine Klausel ist eine Disjunktion von Literalen.

4. Ein Monom ist einen Konjunktion von Literalen.

5. Eine konjunktive Form ist eine Konjunktion von Klauseln, wobei keine Klausel dop-pelt auftritt.

233

Page 236: Skript Waack merged

6. Eine disjunktive Form ist eine Disjunktion von Monomen, wobei kein Monom doppeltauftritt.

7. Ist f(x1, x2, . . . , xn) eine Boolesche Funktion, so heißt eine f darstellende

– konjunktive Form, die eine Konjunktion von Klauseln aus

(xb1

1 ∨ xb22 ∨ . . . ∨ xbn

n

)| b1, b2, . . . , bn ∈ 0, 1

ist, konjunktive Normalform der Funktion f .

– disjunktive Form, die eine Disjunktion von Monomen aus

xb11 ∧ xb2

2 ∧ . . . ∧ xbn

n | b1, b2, . . . , bn ∈ 0, 1

ist, disjunktive Normalform der Funktion f .

Aus dem Grundkurs Informatik I/II ist der folgende Satz wohlbekannt. Er sichert, daßsich Boolesche Funktionen sowohl durch konjunktive als auch durch disjunktive Formendarstellen lassen.

Satz 12.36 Jede Boolesche Funktion hat eine eindeutig bestimmte konjunktive und eineeindeutig bestimmte disjunktive Normalform.

Definition 12.37 Die formale Sprache SAT ist die Menge aller erfullbaren konjunktivenFormen:

SAT := F |F ist erfullbare konjunktive Form.

Satz 12.38 Das Entscheidungsproblem SAT ist NP–vollstandig.

Beweis. Teil 1. Wir mussen zeigen, daß die Sprache SAT in NP liegt. Dazu geben wirden folgenden nichtdeterministischen Polynomialzeitalgorithmus an, der fur jede BoolescheFormel in konjunktiver Form F testet, ob sie erfullbar ist.

Großschritt 1. Teste, ob die Eingabe F eine konjunktive Form ist. (Das sich dieser Syntax-check in Polynomialzeit durchfuhren laßt, ist eine nicht allzu anspruchsvolle Ubungs-aufgabe.)

Großschritt 2. Rate eine erfullende(e1, e2, . . . , en)

der Booleschen Variablen, von denen F abhangt.

Großschritt 3. Verifiziere, obF (e1, e2, . . . , en) = 1

ist. (Man uberlegt sich sofort, daß die Auswertung einer Booleschen Formel in Poly-nomialzeit moglich ist.)

234

Page 237: Skript Waack merged

Teil 2. Sei L eine formale Sprache aus NP. Wir mussen L auf SAT in polynomialzeit-reduzieren. Dazu sei M ein ENTA, fur den gilt:

– L = L(M);

– Fur jede Eingabe w ∈ L gibt es eine akzeptierende Rechnung der Lange kleiner odergleich nk − 3.

Wir erinnern uns daran, daß jede Rechnung eines NTA syntaktisch gesehen beliebigverlangert werden kann, wobei es aus einer terminalen lokalen Situation kein Entrinnengibt. Folglich sind wir berechtigt, im weiteren nur Rechnungen der Lange nk−3 in Betrachtzu ziehen. In deren Verlauf konnen hochstens nk − 3 Speicherzellen mit einer Inschrift ver-sehen werden. Der beschriftete Teil des Bandes ist in seiner Lange durch nk−1 beschrankt,da die beiden linken Randbegrenzer von Anfang an vorhanden sind.

Wir definieren die Menge Γ als die disjunktive Vereinigung

Γ := Σ ∪ ⊲, B ∪Q,

wobei Σ ⊇ 0, 1 das Bandalphabet und Q die Zustandsmenge des ENTA M ist. Wirordnen jeder Rechnung CM (w) der Lange nk − 3 der Maschine M auf eine Eingabe w ∈0, 1n eine Tafel T := TCM (w)

⊲q0⊲ w1 w2 . . . wn B . . . . . .B...

...⊲⊲γi1 γi2 . . .qζi

γi,λi+1 γi,λi+2 . . . γi,λi+ρi. . .B

......

⊲⊲γnk−2,1γnk−2,2. . .qζnk

−2γnk−2,λ

nk−2

+1γnk−2,λnk

−2+2. . . γnk−2,λ

nk−2

+ρnk

−2. . .B

(12.22)

aus der Menge der Abbildungen T | T : 1, 2, . . . , nk − 2 × 1, 2, . . . , nk → Γ zu. JedeZeile von TCM (w) entspricht in kanonischer Weise einer Konfiguration der Maschine M aufdie Eingabe w wahrend der Rechnung CM(w).

Wir bemerken, daß weder der am weitesten links liegende Randbegrenzer”⊲“ noch

das am weitesten rechts liegende Blanksymbol”B“ einer beliebigen Zeile einer der in

Rede stehenden Tafeln T jemals vom Lese-Schreib-Kopf von M erreicht wird: Fur denRandbegrenzer ist das technisch ausgeschlossen. Zum Besuch des Blanksymbols reichtdie Zeit nicht.

Nun fuhren wir fur jede Eingabenlange n und jeden moglichen Eintrag

(i, j) ∈ 1, 2, . . . , nk − 2 × 1, 2, . . . , nk

unserer Tafeln eine Menge Boolescher Variablen

U (i,j)n := xi,j,γ | γ ∈ Γ

235

Page 238: Skript Waack merged

ein und definieren

Un :=nk−2⋃

i=1

nk⋃

j=1

U (i,j)n

Jede Tafel wird als Belegung der Variablen aus Un aufgefaßt. Dabei ist fur jedes (i, j) ∈1, 2, . . . , nk − 2 × 1, 2, . . . , nk und jedes γ ∈ Γ die Variable xi,j,γ genau dann gleich 1,wenn fur die zugehorige Tafel Tij = γ ist.

Naturlich gehort nicht zu jeder Belegung der Variablen aus Un eine Tafel. Wir be-schranken uns auf solche, fur die das der Fall ist und uberdies die erste Spalte ausschließlichaus Randbegrenzern ⊲, die letzte Spalte aus lauter Blanks B besteht. Diese Belegungengeben Anlaß zu den folgenden Bezeichnungen: Eine Belegung

β : Un → 0, 1

heißt zulassig, wenn fur jedes i ∈ 1, 2, . . . , nk − 2 und jedes j ∈ 1, 2, . . . , nk genau einγ ∈ Γ mit

β(xi,j,γ) = 1

existiert und fur alle i = 1, 2, . . . , nk − 2 gilt:

β(xi,1,⊲) = 1 β(xi,nk,B) = 1.

Ist β eine zulassige Belegung, so bezeichnet T (β) die zugehorige Tafel.

Wir reduzieren L auf SAT, indem wir einen nO(1)–zeitbeschrankten Algorithmus beschrei-ben, der fur jede Eingabe w ∈ 0, 1n eine konjunktive Form Φw uber den Variablen ausUn ausgibt, welche die folgenden Eigenschaften hat.

– Jede Belegung β der Variablenmenge Un, welche die konjunktive Form Φw erfullt,ist auch zulassig.

– Jede zulassige Belegung β der Variablenmenge Un erfullt die konjunktive Form Φw

genau dann, wenn die Tafel T (β) einer akzeptierenden Berechnung des ENTA Mauf die Eingabe w entspricht.

Die Zielformel Φw wird die folgende Gestalt haben:

Φw = Φadm ∧ Φinputw ∧ Φaccept ∧ Φcomp (12.23)

Die Teilformeln aus 12.23 werden in Zeit nO(1) konstruierbar und, sofern notig, in einekonjunktive Form uberfuhrbar sein. Ferner werden sie die folgenden Eigenschaften haben.

Zulassigkeit. Jede Belegung β der Variablenmenge Un erfullt Φadm genau dann, wenn βzulassig ist.

236

Page 239: Skript Waack merged

Eingabe. Jede zulassige Belegung β der Variablenmenge Un erfullt Φinputw genau dann, wenn

T(β)1 die initiale Konfiguration des ENTA M auf die Eingabe w ist.

Akzeptierung. Jede zulassige Belegung β der Variablenmenge Un erfullt Φaccept genau dann,wenn es ein j mit β(xnk−2,j,q+

) = 1 gibt.

Nachfolgereigenschaft. Jede zulassige Belegung β der Variablenmenge Un mit β(Φinput

w

)=

1 erfullt Φcomp genau dann, wenn fur sie die folgenden beiden Bedingungen gelten.

1. Fur jeden Zeilenindex i ∈ 2, 3, . . . , nk−2 reprasentiert T(β)i eine Konfiguration

von M auf eine Eingabe der Lange n.

2. Fur jeden Zeilenindex i ∈ 1, 2, . . . , nk − 3 ist daruber hinaus T(β)i+1 eine Nach-

folgerkonfiguration von T(β)i .

Effizienz. Die Formeln Φadm, Φinputw , Φaccept und Φcomp sind in Zeit nO(1) konstruierbar und

in eine konjunktive Form uberfuhrbar.

Zur Zulassigkeit. Die Formel

Φadm :=nk−2∧

i=1

nk−1∧

j=2

((∨

γ∈Γ

xijγ

)

∧∧

γ1 6=γ2

(xijγ1 ∨ xijγ2)

)

∧nk−2∧

i=1

(xi,1,⊲ ∧ xi,nk,B

)(12.24)

hat offensichtlich die geforderten Eigenschaften.

Zur Eingabe. Sei w = w1w2 . . . wn, wobei die wi die einzelnen Bits sind. Dann hat dieFormel

Φinput := x1,1,⊲ ∧ x1,2,q0 ∧ x1,3,⊲ ∧ x1,4,w1 ∧ x1,5,w2 ∧ . . . ∧ x1,n+3,wn∧

nk∧

j=n+4

x1,j,B (12.25)

die geforderte Eigenschaft.

Zur Akzeptierung. Offensichtlich ist Formel 12.26 das, was wir suchen:

Φaccept :=

nk−2∨

j=2

xnk−2,j,q+. (12.26)

Zur Nachfolgereigenschaft. Es genugt, die konjunktive Form Φcomp gemaß

Φcomp =

nk−3∧

i=1

Φcompi (12.27)

darzustellen, wobei die Formeln Φcompi die folgenden Eigenschaften haben.

237

Page 240: Skript Waack merged

– Φcompi ist eine konjunktive Form, die sich aus einer Zeichenkette der Lange n in

Polynomialzeit berechnen laßt.

– Φcompi hangt nur von den Variablen

xi,j,γ, xi+1,j,γ | j = 1, 2, . . . , nk, γ ∈ Γ

ab.

– Jede zulassige Belegung β der Variablen aus Un, fur welche die Zeile T(β)i eine Konfi-

guration von M auf eine Eingabe der Lange n darstellt, erfullt die konjunktive FormΦcomp

i genau dann, wenn die Zeile T(β)i+1 eine Nachfolgerkonfiguration der Zeile T

(β)i

reprasentiert.

Sei i ∈ 2, 3, . . . , nk−3 beliebig aber fest gewahlt. Wir konstruieren eine Formel Φcompi

mit den vorstehend genannten Eigenschaften.Wir konnen voraussetzen, daß β zulassig ist, und daß es sich bei Zeile T

(β)i um eine

Konfiguration handelt. Wir uberdecken das Zeilenpaar (i, i + 1) auf die folgende Weisemit 2× 3–Fenstern, wobei zwei benachbarte Fenster genau eine Spalte gemeinsam haben.(Folglich wird die mittlere Spalte jedes solchen Fensters ausschließlich von diesem Fensteruberdeckt.)

1. Wir legen um den einzigen Eintrag von Zeile i, der gleich einem Zustand q ∈ Q ist,auf die folgende Weise das zentrale Fenster :

b q a∗ ∗ ∗

(12.28)

Das ist stets moglich, da der Lese-Schreibkopf niemals auf dem am weitesten linksliegenden Randbegrenzer steht.

2. Ausgehend von dem zentralen Fenster wird die Uberdeckung nach links und nachrechts solange ausgedehnt, bis daß die Paare von Eintragen

T(β)i,2

T(β)i+1,2

bzw.T

(β)

i,nk−1

T(β)

i+1,nk−1

uberdeckt sind. (Die Uberdeckung der Paare

T(β)i,1

T(β)i+1,1

undT

(β)

i,nk

T(β)

i+1,nk

ist fakultativ. Da zulassige Belegungen die erste und die letzte Spalte der zugehorigenTafel fixieren, konnen wir auf deren Uberdeckung verzichten.) Diese Fenster wollenwir peripher nennen.

238

Page 241: Skript Waack merged

Die vorstehend beschriebene Uberdeckung nennen wir die ausgezeichnete Uberdeckung desZeilenpaars (i, i + 1). Man sieht sofort ein, daß sie stets existiert und eindeutig bestimmt

ist, sofern die Zeile T(β)i, einer Konfiguration entspricht.

Jedes 2× 3–Fenster einer Uberdeckung des Zeilenpaares (i, i + 1) ist durch den Indexseiner mittleren Spalte eindeutig bestimmt. Die Folge f dieser Indizes fur eine ausgezeich-nete Uberdeckung hangt von der Anzahl der Spalten nk und der Position ιQ des Zustandesin der i-ten Zeile ab. Es gilt:

f =

f(0,0) := (2, 4, . . . , nk − 2) falls ιQ gerade und nk gerade ist;

f(1,0) := (3, 5, . . . , nk − 1) falls ιQ ungerade und nk gerade ist;

f(0,1) := (2, 4, . . . , nk − 1) falls ιQ gerade und nk ungerade ist;

f(1,1) := (3, 5, . . . , nk − 2) falls ιQ ungerade und nk ungerade ist.

(12.29)

Sei β eine zulassige Belegung derart, daß T(β)i, einer Konfiguration entspricht. Wir wol-

len an den Fenstern der ausgezeichneten Uberdeckung der Zeilen i und i + 1 eineindeutigerkennen, ob Zeile T

(β)i+1, einer Nachfolgerkonfiguration von Zeile T

(β)i, entspricht. Da die

Uberfuhrungsrelation δM unseres ENTA M ihre Wirkung ausschließlich im zentralen Fen-ster entfaltet, sind die folgenden beiden Bedingungen dafur notwendig und hinreichend:

1. Es gibt ein Element aus δM , das die obere Zeile des zentralen Fensters in dessenuntere Zeile uberfuhrt. Wichtig ist dabei, daß die untere Zeile des zentralen Fenstersdurch die obere Zeile und das entsprechende Element aus δM eindeutig bestimmt ist.

2. Der obere und der untere Eintrag der mittleren Spalte ist fur alle peripheren Fen-ster gleich. Daruber hinaus enthalt die obere Zeile eines peripheren Fensters keinenZustand.

Darstellung zentraler Fenster durch Boolesche Formeln. Wir mußten fur jeden Daten-satz

ς = (q, a, q′, a′, ρ)

aus δM und jede (dann mittlere) Spalte j = 2, 3, . . . , nk−1 eine Fensterfunktion definieren.Wir tun das exemplarisch fur die Datensatze des Typs

ςL = (q, a, q′, a′, L).

Die zu definierende Funktion Φ(ςL)ij ist auf den zu dem Fenster

Ti,j−1 Ti,j Ti,j+1

Ti+1,j−1 Ti+1,j Ti+1,j+1(12.30)

gehorigen Variablen aus Un definiert. Sie muß die folgende Eigenschaft haben:

239

Page 242: Skript Waack merged

Eine zulassige Belegung β erfullt Φ(ςL)ij genau dann, wenn T

(β)i,j = q und T

(β)i,j+1 = a und

T(β)i+1,j−1 = q′ und T

(β)i+1,j+1 = a′ und T

(β)i,j−1 = T

(β)i+1,j .

Dies leistet die folgende Formel.

Φ(ςL)ij = xi,j,q ∧ xi,j+1,a ∧ xi+1,j−1,q′ ∧ xi+1,j+1,a′ ∧

γ∈Γ

(xi,j−1,γ ⊕ xi+1,j,γ) (12.31)

Naturlich gilt fur alle ς 6= ς ′, daß die zugehorigen Fensterfunktionen disjunkt sind:

Φ(ς)ij ∧ Φ

(ς′)ij = 0. (12.32)

Die Gesamtfunktion fur dieses Fenster als zentralem Fenster ist

Φcentij =

ς∈δM

Φ(ς)ij , (12.33)

wobei es sich dabei wegen Gleichung 12.32 um eine disjunkte Vereinigung handelt.

Darstellung peripherer Fenster durch Boolesche Formeln. Wir suchen nach einer Funk-tion Φ

(peripher)ij , die wiederum auf den Variablen definiert ist, die zu dem Fenster 12.30

gehoren. Ihre definierende Eigenschaft ist:

Eine zulassige Belegung β erfullt Φperipherij genau dann, wenn T

(β)i,j = T

(β)i+1,j ist und

T(β)i,j−1, T

(β)i,j , T

(β)i,j+1 6∈ Q gilt.

Die Formel

Φperipherij =

q∈Qk=j−1,j,j+1

xi,k,q ∧∧

γ∈Γ\Q

(xi,j,γ ⊕ xi+1,j,γ) (12.34)

leistet das Verlangte.

Wir beobachten, daß die Funktionen Φcentij und Φperipher

ij disjunkt sind:

Φcentij ∧ Φperipher

ij = 0 (12.35)

Da grundsatzlich jedes Fenster sowohl zentral als auch peripher sein kann, definierenwir:

Φcompij := Φcent

ij ∨ Φperipherij . (12.36)

Aus den Gleichungen 12.32 und 12.35 folgt: Jede zulassige Belegung β der Variablen aus Un,fur welche die Zeile T

(β)i eine Konfiguration von M auf eine Eingabe der Lange n darstellt,

erfullt die Formel Φcompij genau dann, wenn folgendes gilt: Das 2 × 3–Fenster mit dem

mittleren Spaltenindex j ist entweder ein zentrales Fenster, das genau ein Transformationς ∈ δM widerspiegelt, oder es ist ein peripheres Fenster.

240

Page 243: Skript Waack merged

Nun mussen die Φcompij (j = 2, 3, . . . , nk − 1) nur noch zu der Funktion Φcomp

i zusam-mengesetzt werden. Wir greifen auf das zuruck, was wir im Vorfeld von Gleichung 12.29gesagt haben.

Φcompi :=

(∧

j∈f(0,0)Φcomp

ij

)

∨(∧

j∈f(1,0)Φcomp

ij

)

falls nk gerade ist;(∧

j∈f(0,1)Φcomp

ij

)

∨(∧

j∈f(1,1)Φcomp

ij

)

falls nk ungerade ist.(12.37)

Warum erfullt jede zulassige Belegung β der Variablen aus Un, fur welche die Zeile T(β)i

eine Konfiguration von M auf eine Eingabe der Lange n darstellt, die durch Gleichung 12.37definierte Formel Φcomp

i genau dann, wenn die Zeile T(β)i+1 eine Nachfolgerkonfiguration der

Zeile T(β)i reprasentiert?

Ist T(β)i+1 eine Nachfolgerkonfiguration der Zeile T

(β)i , und ist f die ausgezeichnete Uber-

deckung (siehe Gleichung 12.29), so ist die Teilformel∧

j∈fΦcomp

ij erfullt.

Ist andererseits Φcompi erfullt, so muß es eine erfullte Teilformel

j∈f Φcompij geben. Die

Folge f reprasentiert eine ausgezeichnete Uberdeckung, deren samtliche FensterformelnΦcomp

ij erfullt (j ∈ f) sind. Da nach Voraussetzung die Zeile T(β)i eine Konfiguration von

M auf eine Eingabe der Lange n darstellt, sichert dies (siehe Bemerkung im Anschluß an

Gleichung 12.36), daß T(β)i+1 eine Nachfolgerkonfiguration von T

(β)i darstellt.

Warum laßt sich die in Gleichung 12.37 definierte Formel Φcompi in Zeit nO(1) in eine

konjunktive Form transformieren?

Jede der Formeln Φcompij hangt nur von O (1) vielen Variablen ab und kann folglich

in Zeit O (1) in konjunktive Normalform gebracht werden. Folglich kann jede der Teilfor-meln

j∈f Φcompij in Zeit nO(1) in eine konjunktive Form gebracht werden. Schließlich lassen

sich Formeln von der Art(∧

j∈f′ Φcompij

)

∨(∧

j∈f′′ Φcompij

)

durch einfache Anwendung des

Distributivgesetzes in Zeit nO(1) in eine konjunktive Form uberfuhren.

Zur Effizienz. Aus den angegebenen Konstruktionen fur die Formeln Φadm, Φinputw , Φaccept

und Φcomp ergibt sich unmittelbar, daß sie in Zeit nO(1) aufgestellt werden konnen. DieTransformation der Φcomp

i in konjuktive Formen haben wir soeben besprochen.

12.11 Einschrankungen und Varianten von SAT

Nach Definition 12.35 ist klar, daß sich jede konjunktive Form

F =

r∧

i=1

Kr (12.38)

241

Page 244: Skript Waack merged

in den Variablen x1, x2, . . . , xn sich umkehrbar eindeutig als Menge ihrer Klauseln1 dar-stellen laßt:

F = Ki | i = 1, 2, . . . , r. (12.39)

Das folgende Lemma ist eine einfache, aber sehr nutzliche Charakterisierung fur dieErfullbarkeit der konjunktiven Form F aus Gleichung 12.39.

Lemma 12.39 Die konjunktive Form F aus Gleichung 12.39 ist genau dann erfullbar,wenn es eine Funktion

α : F = Ki | i = 1, 2, . . . , r → x1, x2, . . . , xn, x1, x2, . . . , xn

derart gibt, daß

– fur jedes i = 1, 2, . . . , r das Literal α(Ki) ein Literal der Klausel Ki ist;

– fur alle i 6= j die Literale α(Ki) und α(Kj) einander nicht widersprechen: α(Ki) 6=

α(Kj). (Wir nennen eine solche Funktion α auch eine widerspruchsfreie Auswahl-funktion.)

Beweis. Ist F erfullbar, so gibt es einen Booleschen Vektor b ∈ 0, 1n, der F erfullt.Das heißt insbeondere fur jede der Klauseln Ki, daß es ein Literal y aus Ki geben muß,das durch b erfullt wird. Sei y ein solches Literal fur Ki. Wir definieren α(Ki) := y.

Die so ausgewahlten Literale konnen einander nicht widersprechen, da sie alle durchden Vektor b erfullt werden.

Sei α eine Auswahlfunktion. Wir definieren wie folgt fur F einen erfullenden Vektorb = (b1, b2, . . . , bn). Fur jedes i = 1, 2, . . . , r gibt α(Ki) Anlaß, eine Komponente von bfestzulegen: Ist α(Ki) = x

ej

j , so setzen wir bj := ej . Komponenten von b, die auf dieseWeise nicht erreicht werden, legen wir beliebig fest.

Naturlich kann es passieren, daß einer Komponente von b mehrfach ein Wert zugewiesenwird. Das ist genau dann der Fall, wenn es ein i und ein j derart gibt, daß den Literalenα(Ki) und α(Kj) dieselbe Variable zugrunde liegt. Wegen der Widerspruchsfreiheit derAuswahlfunktion α sind dann die Literale α(Ki) und α(Kj) und damit die zugewiesenenWerte gleich.

Man erkennt unschwer, daß ein Boolescher Vektor b, der auf die vorstehend beschrie-bene Weise entstanden ist, die konjunktive Form F erfullt: Ist α(Ki) = x

ej

j , so sorgt dieKomponente bj fur die Erfullung der Klausel Ki.

Definition 12.40 Die konjunktive Form F aus Gleichung 12.39 heißt genau dann (exakte)k-CF, wenn fur jedes i = 1, 2, . . . , r gilt: Die Klausel Ki besteht aus (genau) k paarweiseverschiedenen Literalen, die einander nicht widersprechen.

1Aus technischen Grunden — siehe Beweis von Satz 12.46 — ist eine Klausel nicht eindeutig durch diein ihr vorkommenden Literale bestimmt. Es kann z.B. sein, daß K1 = K2 = (x ∨ y ∨ z) ist.

242

Page 245: Skript Waack merged

Definition 12.41 Die formale Sprache kSAT ist fur k ≥ 2 die Menge aller erfullbarenk-CF:

kSAT := F |F ist erfullbare k-CF.

kSATexakt := F |F ist erfullbare exakte k-CF.

Die formale Sprache

3SAT2,3 ⊂ 3SAT

besteht aus allen erfullbaren 3-CF F , fur die uberdies gilt: Jede Variable kommt in Fhochstens dreimal, jedes Literal hochstens zweimal vor.

Satz 12.42 Das Problem 3SATexakt und damit das Problem 3SAT ist NP-vollstandig.

Beweis. Ein NP-Vollstandigkeitsbeweis besteht, wie wir aus dem Beweis des Satzes 12.38wissen, aus zwei Teilen. Man muß zunachst zeigen, daß das in Rede stehende Problem inNP liegt. Fur 3SAT geht das in der gleichen Weise wie im Beweis von Satz 12.38 dargestellt.

Nun mussen wir jedes Problem aus NP auf 3SATexakt reduzieren. Das geschieht, indemwir einen Polynomialzeit-Algorithmus angeben, der SAT auf 3SATexakt reduziert:

Eingabe: eine konjunktive Form F gemaß Gleichung 12.39.

Ausgabe: eine exakte 3-CF gemaß Definition 12.40, die genau dann erfullbar ist, wenn dieEingabeform F erfullbar ist.

Sei F im folgenden die aktuelle konjunktive Form.

Großschritt 1.

– Streiche aus jeder Klausel mehrfach vorkommende Literale bis auf einen Reprasen-tanten.

– Streiche jede Klausel, in der eine Variable und deren Negation vorkommt.

Bemerkung. Warum kann man Klauseln, die einen Term”x ∨ x“ enthalten, streichen? Sie

sind stets erfullt.

Großschritt 2. Hier geht es darum, Klauseln der Lange eins zu entfernen. Die Grundideeist einfach: Solche Klausel konnen nur erfullt werden, indem man das Literal eins setzt. Dader Wert fur die Boolesche Variable, die y zugrunde liegt, nun festgelegt ist, muß dieserWert in alle anderen Klauseln eingesetzt werden. Fur jede Klausel K ′ ∈ F , die von dieserEinsetzung betroffen ist, sind zwei Falle moglich.

Entweder die Klausel K ′ ist dadurch erfullt. Dann kann sie gestrichen werden. Ist Fnach dieser Streichung leer, war die Eingabeform erfullbar, und wir geben eine erfullbareexakte 3-CF aus.

Oder das ist nicht der Fall. Dann kommt y in K ′ vor, und es muß ein anderes Literalherhalten, um K ′ zu erfullen: Das Literal y wird aus K ′ entfernt. Ist K ′ nun leer, so isteine Erfullung von K ′ nicht mehr moglich. Die Eingabe-Form war folglich unerfullbar. Wirreagieren darauf, indem wir eine unerfullbare exakte 3-CF ausgeben:

243

Page 246: Skript Waack merged

Solange F eine Klausel K = y (y Literal) enthalt, fuhre aus.Setze y ← 1Entferne K aus F .Falls F = ∅, so fuhre aus.

Gib eine erfullbare exakte 3-CF aus und breche ab:return (x1 ∨ x2 ∨ x3).

Fur alle K ′ ∈ F fuhre aus.Falls y in K ′ vorkommt, so fuhre aus.

Entferne K ′ aus F .Bemerkung. K ′ ist dann erfullt.

Falls F = ∅, so return (x1 ∨ x2 ∨ x3).Falls y in K ′ vorkommt, so fuhre aus.

Entferne y aus K.Ist K ′ nun leer, so fuhre aus.

Gib eine nichterfullbare exakte 3-CF aus und breche ab:return

e1,e2,e3∈0,1 xe11 ∨ xe3

2 ∨ xe33 .

Großschritt 3. Nun mussen Klauseln der Lange 2 ersetzt werden.

Fur jede Klausel K ∈ F fuhre aus:Ist K = (y1 ∨ y2) (y1, y2 Literale), so ersetze K durch die Klauseln

(y1 ∨ y2 ∨ zK) und (y1 ∨ y2 ∨ zK).

Bemerkung. Die Variable zK ist eine neue Variable, die nur an dieser Stelle vorkommt.Der Sinn dieser Konstruktion besteht darin, daß eine Auswahlfunktion α fur die Neuformwenigstens eines der Altliterale y1 und y2 auswahlen muß. Dadurch ist die Altform genaudann erfullbar, wenn die Neuform erfullbar ist.

Großschritt 4. Schließlich werden Klauseln der Lange ≥ 4 ersetzt.

Fur jedes (y1 ∨ y2 ∨ . . . ∨ yk) ∈ F (k ≥ 4, yi fur i = 1, 2, . . . k Literale) fuhre aus:Ersetze (y1 ∨ y2 ∨ . . . ∨ yk) durch die folgenden Klauseln:

(y1 ∨ y2 ∨ zK,1)(zK,1 ∨ y3 ∨ zK,2). . .(zK,i ∨ yi+2 ∨ zK,i+1). . .(zK,k−3 ∨ yk−1 ∨ yk).

Bemerkung. Die Variablen zK,1,zK,2, . . ., zK,k−3 sind neu. Fur sie laßt sich das wiederholen,was wir am Ende von Großschritt 3 uber die Variable zK gesagt haben.

Man kann das Problem 3SAT weiter einschranken, ohne die Qualitat der NP-Vollstandig-keit zu verlieren.

244

Page 247: Skript Waack merged

Satz 12.43 Das Problem 3SAT2,3 ist NP-vollstandig.

Beweisskizze. Offenbar liegt 3SAT2,3 in NP. Folglich genugt es, das Problem 3SAT auf3SAT2,3 zu reduzieren.

Sei F eine Instanz von 3SAT. Fur jede Variable x von F , die in F mehr als einmalvorkommt, fuhren wir folgendes durch.

1. Kommt die Variable x in F k-mal vor, so ersetzten wir jedes Vorkommen durch eineneue Variable. Statt der Variablen x kommen in F nun die Variablen x1, x2, . . ., xk

vor.

2. Wir erzwingen, daß unsere modifizierte Form nur dann erfullbar ist, wenn die Va-riablen x1, x2, . . ., xk mit dem gleichen Wert belegt werden, indem wir sie mit der2-CF

(x1 ∨ x2) ∧ (x2 ∨ x3) ∧ . . . ∧ (xk ∨ x1)

verunden, die zu der Formel

(x1 → x2) ∧ (x2 → x3) ∧ . . . ∧ (xk → x1)

aquivalent ist. (Die Boolesche Funktion x → y, die Implikation, ist genau dann 0,wenn x = 1 und y = 0 ist.) Diese ist offenbar genau dann erfullt, wenn x1 = x2 =. . . = xk ist.

Was ist mit dem Problem 2SAT? Wie der folgende Satz zeigt, wird die Erfullbarkeitkonjunktiver Formen einfacher, wenn man sich auf Klauseln der Lange zwei beschrankt.

Satz 12.44 Das Problem 2SAT ist NL-vollstandig.

Die Beweisidee von Satz 12.44 sei hier kurz skizziert. Zunachst wissen wir, daß dieDisjunktion A∨B zweier Aussagen A und B logisch zu der Implikation A→ B aquivalentist. Diese Tatsache regt uns zu der folgenden Konstruktion an.

Ist F eine 2-CF uber x1, x2, . . . , xm, so ersetzen wir zunachst jede Klausel von F , dienur aus einem Literal y besteht, durch y ∨ y. Nun ordnen wir dem so modifizierten F denfolgenden gerichteten Graphen G(F ) zu. Die Knotenmenge von G(F ) ist

x1, x2, . . . , xm,¬x1,¬x2, . . . ,¬xm, .

Zwei Knoten y1 und y2 sind genau dann durch eine Kante y1 → y2 verbunden, wenn y1∨y2

eine Klausel von F ist.Man uberlegt sich leicht, daß die 2-CF F genau dann nicht erfullbar ist, wenn es eine

Variable xi (i = 1, 2, . . . , n) derart gibt, daß es in F (G) sowohl einen gerichteten Weg vonxi nach ¬xi als auch einen gerichteten Weg von ¬xi nach xi gibt.

245

Page 248: Skript Waack merged

Auf dieser Grundlage kann man sich leicht uberlegen, daß 2SAT in NL liegt. Die NL-Vollstandigkeit beweist man, indem man die große Ahnlichkeit des oben beschriebenen We-geproblems in F (G) mit dem in Abschnitt 12.2 betrachteten Graph-Accessibility-ProblemGAP ausnutzt.

Man kann sich auch die Frage stellen, wieviele Klauseln einer k-CF maximal gleichzeitigerfullbar sind. Das zugehorige Entscheidungsproblem ist MAXkSAT.

Problem 7 (Entscheidungsproblem MAXkSAT)

Eingabe: eine k-CF F = Ki | i = 1, 2, . . . , r in x1, x2, . . . , xn gemaß Definition 12.40und eine naturliche Zahl c.

Ausgabe: Akzeptiere genau dann, wenn es einen Booleschen Vektor (β1, β2, . . . , βn) ∈0, 1n gibt, der mindestens c Klauseln aus Ki | i = 1, 2, . . . , r erfullt.

Man ist nicht verwundert, daß der folgende Satz gilt.

Satz 12.45 Das Problem MAX3SAT ist NP-vollstandig.

Beweis. Einerseits ist klar, daß MAX3SAT in NP liegt. Man muß ja nur die entspre-chende Belegung der Variablen raten. Andererseits ist die Funktion

F 7→ (F, |F |)

offenbar eine FP-Reduktion von 3SAT auf MAX3SAT.

Es ist erstaunlich, daß hier der Ubergang zu Klauseln mit nur zwei Literalen unschadlichist, wenn es um den Erhalt der NP-Vollstandigkeit geht.

Satz 12.46 Das Problem MAX2SAT ist NP-vollstandig.

Beweis. Da MAX2SAT offenbar in NP liegt, genugt es, 3SATexakt auf MAX2SAT zureduzieren. Dazu sei F eine 3-CF.

1. Sei K ∈ F eine Klausel von F mit K = (x ∨ y ∨ z), wobei x, y und z Literale sind.Seien schließlich v = vw und w = wK neue Variablen. Wir definieren

FK(v, w, x, y, z) := (v ∨ w) ∧ (v ∨ x) ∧ (v ∨ y) ∧ (v ∨ z)︸ ︷︷ ︸

=:Φ1

(v ∨ w) ∧ (v ∨ x) ∧ (v ∨ y) ∧ (v ∨ z)︸ ︷︷ ︸

=:Φ2

(x ∨ y) ∧ (x ∨ z) ∧ (y ∨ z)︸ ︷︷ ︸

=:Φ3

(x ∨ w) ∧ (y ∨ w) ∧ (z ∨ w)︸ ︷︷ ︸

=:Φ4

. (12.40)

246

Page 249: Skript Waack merged

2. Wir beobachten, daß die durch Gleichung 12.40 in Beweisschritt 1 definierte konjunk-tive Form FK(v, w, x, y, z) symmetrisch in x, y und z ist.

3. Wir beweisen, daß K = (x ∨ y ∨ z) genau dann erfullt ist, wenn die Anzahl dererfullten Klauseln von FK großer oder gleich 11 ist.

Ist v = 1, so sind die drei Klauseln aus Φ1 erfullt, andernfalls sind es alle Klauselnaus Φ2. Im ubrigen sind diese beiden Falle symmetrisch. Wir konnen im weitereno.B.d.A. voraussetzen, daß v = 1 ist. Die vier Klauseln aus Φ1 sind also stets erfullt.

Wir unterscheiden nun danach, ob ein, zwei oder alle drei Literale der Klausel K =(x∨y∨z) erfullt sind. Wegen Beweisschritt 2 konnen wir uns o.B.d.A. auf die folgendeFallunterscheidung beschranken.

Fall 1: x = 1 und y = z = 0. Offenbar sind alle drei Klauseln aus Φ3 erfullt.Zusammen mit den vier erfullten Klauseln aus Φ1 haben wir einen Sockeln von 7erfullten Klauseln.

Wahlen wir w = 0, so konnen wir alle drei Klauseln aus Φ4 aber nur eine Klausel ausΦ2 erfullen. Andernfalls ware es nur eine Klausel aus Φ4, dafur aber zwei Klauselnaus Φ2. Fur w = 1 sind folglich 11 Klauseln erfullt.

Fall 2: x = y = 1 und z = 0. Offenbar sind zwei Klauseln aus Φ3 erfullt. Zusammenmit den vier Klauseln aus Φ1 haben wir einen Grundstock von 6 erfullten Klauseln.

Fur w = 0 kommen zwei Klauseln aus Φ2 und drei Klauseln aus Φ4 hinzu. Fur w = 1sind es drei Klauseln aus Φ2, aber nur zwei Klauseln aus Φ4, die erfullt sind. Folglichsind sowohl fur w = 0 als auch fur w = 1 genau 11 Klauseln erfullt.

Fall 3: x = y = z = 1. Hier ist keine Klausel aus Φ3, aber unabhangig von der Wahlvon w alle drei Klauseln Φ4 aus erfullt. Im Fall w = 1 sind daruber hinaus alle vierKlauseln aus Φ2 erfullt.

4. Man uberlegt sich leicht in einer zu Beweisschritt 3 analogen Weise, daß (x ∨ y ∨ z)genau dann nicht erfullt ist, wenn die Anzahl der erfullten Klauseln von FK kleineroder gleich 10 ist. (Hier ist der Fall w = 0 am gunstigsten.)

5. Offenbar gilt nun: Die 3-CF F ist genau dann erfullbar, wenn fur die 2-Form∧

K∈F FK

mindestens 11 · |F | Klauseln gleichzeitig erfullt werden konnen.

247

Page 250: Skript Waack merged

Literaturverzeichnis

[Pap94] C. H. Papadimitriou. Computational Complexity. Addison–Wesley, 1994.

[Rei99] K. R. Reischuk. Komplexitatstheorie. Leitfaden der Informatik. Teubner Verlag,1999.

248

Page 251: Skript Waack merged

Kapitel 13

Einige wichtige NP–vollstandigeProbleme

Es folgen einige wichtige NP-vollstandige Probleme. Wer mehr wissen will, der studiere dieentsprechenden Kapitel aus [Pap94].

13.1 Aufteilungsprobleme fur Mengen und Zahlen

Definition 13.1 Seien H , B und G disjunkte endliche Mengen gleicher Machtigkeit q,und sei P ⊆ H × B × G eine dreistellige Relation uber diesen Mengen.

Eine Teilrelation M ⊆ P mit

M = (hi, bi, gi) | i = 1, 2, . . . , q

mit

H = h1, h2, . . . , hq B = b1, b2, . . . , bq G = h1, h2, . . . , hq

heißt dreidimensionales Matching fur D = (H, B, G, P ).Ein Tripel m = (h, b, g) uberdeckt seine Komponenten h, b und g.

Problem 8 (Dreidimensionales Matching 3DM)

Eingabe: ein 4-Tupel D = (H, B, G, P ) mit den Eigenschaften aus Definition 13.1.

Ausgabe: Akzeptiere genau dann, wenn die Relation P ein dreidimensionales Matchingenthalt.

Man kann sich das Entscheidungsproblem 3DM wie folgt veranschaulichen. Eine gleicheAnzahl von Jungen (B) und Madchen (G) wollen Lebensgemeinschaften grunden. Dazustehen Hauser (H) in entsprechender Anzahl zur Verfugung. Gegeben ist ferner eine Menge

249

Page 252: Skript Waack merged

P von Praferenztripeln: Ist (h, b, g) ∈ P , so glauben das Madchen g und der Junge b indem Haus h miteinander auskommen zu konnen.

Jedes Madchen, jeder Junge und jedes Haus sollten von mehreren Praferenztripelnuberdeckt werden, denn ansonsten ware das Problem algorithmisch uninteressant.

Die Frage ist, ob die Jungen und Madchen in den zur Verfugung stehenden Hausern sozueinander finden konnen, daß sie dort gemaß P miteinander auskommen.

Den Beweis des folgenden Satzes fuhren wir in Anlehnung an [Pap94].

Satz 13.2 Das Entscheidungsproblem 3DM ist NP-vollstandig.

Beweis. Man uberzeugt sich in der ublichen Weise davon, daß 3DM ∈ NP ist.Um zu zeigen, daß 3DM NP-vollstandig ist, reduzieren wir 3SATexakt auf 3DM. Wir

brauchen einen Polynomialzeit-Algorithmus, der angesetzt auf eine exakte 3-CF

F = K1, K2, . . . , Kr mit

Kj = aj ∨ bj ∨ cj (j = 1, 2, . . . , r)

uber der Variablenmenge

VF = x1, x2, . . . , xn

eine Instanz

DF = (HF , BF , GF , PF )

von 3DM derart berechnet, daß PF genau dann ein dreidimensionales Matching M enthalt,wenn die Formel F erfullbar ist.

Die Instanz DF hat

HF :=r⋃

j=1

x(j)1 , x

(j)2 , . . . , x(j)

n , x(j)1 , x

(j)2 , . . . , x(j)

n ︸ ︷︷ ︸

=:H(Kj)

als Hausermenge: Jede Klausel Kj (j = 1, 2, . . . , r) bekommt ihren eigenen vollstandigen

Satz H(Kj) von Literalen und mutiert zu Kj, indem die Literale uber VF durch die ent-sprechenden Literale aus H(Kj) ersetzt werden. (Ist beispielsweise K7 = x1 ∨ x2 ∨ x5, so

ist K7 = x(7)1 ∨ x

(7)2 ∨ x

(7)5 .)

Die Menge der Praferenztripel MF besteht aus drei Teilen.

Der Klauselteil von F besteht fur jedes j = 1, 2, . . . , r aus der Menge von Praferenztri-peln

P (Kj) ⊆ x(j)1 , x

(j)2 , . . . , x(j)

n , x(j)1 , x

(j)2 , . . . , x(j)

n × βj × γj,

250

Page 253: Skript Waack merged

die wie folgt definiert ist:

(z(j), βj, γj) ∈ P (Kj) ⇐⇒ Das Literal z kommt in Kj vor.

Der Klauselteil PK insgesamt besteht aus der Vereinigung der P (Kj) fur j = 1, 2, . . . , r.Fur j = 1, 2, . . . , r kommen die Paare (βj, γj) nur im Klauselteil vor.

Ist M ′ eine Uberdeckung der Paare (βj, γj) | j = 1, 2, . . . , r mit |M ′| = r, so definiertM ′ auf die folgende Weise eine Auswahlfunktion:

α : K1, K2, . . . , Kr → aj , bj , cj | j = 1, 2, . . . , r

α(Kj) = z : ⇐⇒(z(j), βj, γj

)∈ M ′.

Ist umgekeht α eine Auswahlfunktion, so ist die zugehorige Menge M ′ ⊂ PK

M ′ :=(z(j), βj , γj) |α(Kj) = z

eine Uberdeckung der Paare (βj , γj) | j = 1, 2, . . . , r mit |M ′| = r.Wir mussen in der Konstruktion von DF nun so fortfahren, daß folgendes gesichert ist:

1. Ist M ⊆ PF ein dreidimensionales Matching und ist M ′ := M ∩ PK , so ist die zuM ′ gehorige Auswahlfunktion α widerspruchsfrei.

2. Ist umgekehrt α eine widerspruchsfreie Auswahlfunktion, so laßt sich die zugehori-ge Uberdeckung M ′ der Paare (βj, γj) | j = 1, 2, . . . , r mit |M ′| = r zu einemdreidimensionalen Matching auffullen.

Der nun folgende Variablenteil hat die Aufgabe, die Eigenschaften aus der vorstehendenBox sicherzustellen.

Der Variablenteil. Wir fuhren fur jede Variable xi ∈ VF neue Mengen

B(xi) := b(1)i , b

(2)i , . . . , b

(r)i

G(xi) := g(1)i , g

(2)i , . . . , g

(r)i

von r = #Klauseln Jungen und Madchen ein und konstruieren ein P (xi) mit

P (xi) ⊆ x(j)i , x

(j)i | j = 1, 2, . . . , r × B(xi) × G(xi)

so, daß fur jedes j = 1, 2, . . . , r und alle µ und ν gilt:

(x(j)i , b

(µ)i , g

(ν)i ) ∈ P (xi) ⇐⇒ µ = j und ν = j.

(x(j)i , b

(µ)i , g

(ν)i ) ∈ P (xi) ⇐⇒ µ ≡ (j + 1) (mod r) und ν = j.

Fur den Fall r = 4 ist die Relation P (xi) in Abbildung 13.1 graphisch dargestellt: DieElemente von P (xi) sind genau durch die Ecken der außeren (grunen) Dreiecke definiert.

251

Page 254: Skript Waack merged

x(1)i

x(2)i

x(2)i

x(3)i

x(3)i

x(4)i

x(1)i

b(1)i

b(2)i

g(1)i

g(2)i

g(3)i

b(3)i

g(4)i

b(4)i

x(4)i

Abbildung 13.1: Der Teil der 3DM-Instanz fur die Variable xi einer 3-CF mit vier Klauseln

Die Elemente aus B(xi) und G(xi) konnen ausschließlich von Tripeln aus P (xi) uber-deckt werden.

Die folgende Beobachtung, die man sich sehr schon anhand von Abbildung 13.1 ver-deutlichen kann, ist von zentraler Bedeutung. Fur jedes i = 1, 2, . . . , n gibt es genau zweiMoglichkeiten, die Mengen B(xi) und G(xi) zu uberdecken. Entweder geschieht das durchdie Tripel

(x(1)i , b

(1)i , g

(1)i ) (x

(2)i , b

(2)i , g

(2)i ) . . . (x

(r)i , b

(r)i , g

(r)i ) (13.1)

oder durch die Tripel

(x(1)i , b

(2)i , g

(1)i ) (x

(2)i , b

(3)i , g

(2)i ) . . . (x

(r)i , b

(1)i , g

(r)i ) (13.2)

Der Auffullteil dient der Losung des folgendes Problems. Es gibt bisher zuwenige Jungenund Madchen, um alle 2nr Hauser besetzen zu konnen:

∣∣∣∣∣β1, β2, . . . , βr ∪

n⋃

i=1

B(xi)

∣∣∣∣∣= nr + r

∣∣∣∣∣γ1, γ2, . . . , γr ∪

n⋃

i=1

G(xi)

∣∣∣∣∣= nr + r

252

Page 255: Skript Waack merged

Deshalb mussen die folgenden Auffullmengen konstruiert werden:

B := β1, β2, . . . βnr−r G := γ1, γ2, . . . γnr−r.

Diese Auffullmengen konnen nur durch die folgenden Praferenztripel uberdeckt werden:

P := (x(j)i , βk, γk), (x

(j)i , βk, γk) | i = 1, 2, . . . , n, j = 1, 2, . . . , r k = 1, 2, . . . , nr − r

Nun beweisen wir die Korrektheit der Reduktion.

1. Ein dreidimensionales Matching aus PF muß fur jedes i = 1, 2, . . . , n die MengenB(xi) und G(xi) uberdecken. Diese jungen Damen und Herren wohnen, wie oben

dargestellt, entweder alle in einem”Haus“ mit Dach (in einem der

”Hauser“ x

(j)i fur

j = 1, 2 . . . , r) oder alle in einem”Haus“ ohne Dach (in einem der

”Hausern“ x

(j)i

fur j = 1, 2 . . . , r). Die durch die Uberdeckung der Paare (βj , γj) (j = 1, 2, . . . , r) ausdem Klauselteil definierte Auswahlfunktion α ist folglich widerspruchsfrei.

2. Ist F erfullbar, und ist α eine widerspruchsfreie Auswahlfunktion, so fullen wir diezu α gehorige Uberdeckung M ′ der Paare (βj, γj) | j = 1, 2, . . . , r mit |M ′| = r wiefolgt zu einem dreidimensionalen Matching M auf:

(a) Ist α(Kj) = xi, so wahlt man fur die Mengen B(xi) und G(xi) die Uberdeckung(13.2).

(b) Ist α(Kj) = xi, so wahlt man fur die Mengen B(xi) und G(xi) die Uberdeckung(13.1).

(c) Gibt es fur ein xi keine Klausel K mit α(K) ∈ xi, xi, so ist die Uberdeckungder Mengen B(xi) und G(xi) nicht festgelegt.

(d) Alle bisher nicht uberdeckten Elemente aus HF werden durch den Auffullteiluberdeckt.

Problem 9 (Das Partitionsproblem PARTITION fur Folgen naturlicher Zahlen)

Eingabe: ein Paar (A, s) bestehend aus

– einer endlichen Indexmenge A und

– einer Funktion s : A → N.

Ausgabe: Akzeptiere genau dann, wenn es eine Teilmenge A′ ⊆ A derart gibt, daß∑

a∈A′

s(a) =∑

a6∈A′

s(a).

253

Page 256: Skript Waack merged

Wir nennen eine Teilmenge A′, sofern sie existiert, partitionierende Teilmenge von A.

Wir bemerken, daß fur die Existenz einer partionierenden Teilmenge notwendig ist, daßdie Zahl

a6∈A s(a) gerade ist.

Satz 13.3 Das Entscheidungsproblem PARTITION ist NP-vollstandig.

Beweis. Wir reduzieren 3DM auf PARTITION. Sei (H, B, G, M) mit

H := h0, h1, . . . , hq−1

B := b0, b1, . . . , bq−1

G := g0, g1, . . . , gq−1

und P = m1, m2, . . . , mk.Wir arithmetrisieren Elemente m aus P durch Zahlen der Lange 3q uber den Ziffern

0, 1, . . . , k. Das Ziffernmuster einer solchen Zahl ist in (13.3) dargestellt.

(q − 1)-te . . . λ-te . . . 0-te︸ ︷︷ ︸

Ziffer des H-Teils

(q − 1)-te . . . µ-te . . . 0-te︸ ︷︷ ︸

Ziffer des B-Teils

(q − 1)-te . . . ν-te . . . 0-te︸ ︷︷ ︸

Ziffer des G-Teils

(13.3)

Ist m = (hλ, bµ, gν) ∈ M , so ist

Ziffernindex 3q − 1 . . . λ + 2q . . . 2q 2q − 1 . . . µ + q . . . q q − 1 . . . ν . . . 0Ziffernwert 0 . . . 1 . . . 0 0 . . . 1 . . . 0 0 . . . 1 . . . 0

(13.4)

das Ziffernmuster der Arithmetrisierung s(m) gemaß (13.3). Der Wert dieser Arithmetri-sierung ist

s(m) := (k + 1)λ+2q + (k + 1)µ+q + (k + 1)ν . (13.5)

Eine Teilmenge M ⊆ P wird durch

s(M) :=∑

m∈M

s(m) (13.6)

arithmetrisiert. Jetzt erkennen wir den Sinn dessen, die Menge 0, 1, . . . , k als Ziffern-menge zu verwenden: Bei der Berechnung von s(M) gemaß (13.6) gibt es in keiner der 3qSpalten einen Ubertrag. Insbesondere ist M genau dann ein dreidimensionales Matching,wenn

β := s(M) =

3q−1∑

i=0

(k + 1)i =(k + 1)3q − 1

k(13.7)

254

Page 257: Skript Waack merged

ist. Wir schlußfolgern, daß falls

s(P ) < β (13.8)

ist, die Eingabe P kein dreidimensionales Matching enthalt.Fur den Fall

”s(P ) ≥ β“ definieren wir

A := P ∪ a1, a2, (13.9)

wobei a1 und a2 zwei neue Elemente sind, und

s : A −→ N

m ∈ P 7→ s(m) (13.10)

a1 7→ 2s(P ) − β (13.11)

a2 7→ s(P ) + β. (13.12)

Wir beobachten, daß

s(A) = 4s(P ) (13.13)

ist.Wir zeigen: Ist s(P ) = s(P ) ≥ β, so hat die Eingabe P genau dann ein dreidiemsionales

Matching M ⊆ P , wenn die Indexmenge A eine partitionierende Teilmenge A′ enthalt.(⇒) Sei M ⊆ P das dreidimensionale Matching. Wir setzen

A′ := M ∪ a1

und erhalten

s(A′) = 2s(P ) − β + β = 2s(P ).

Wegen (13.13) ist A′ partitionierende Teilmenge.(⇐) Sei A′ ⊂ A eine partitionierende Teilmenge. Dann ist naturlich auch A \ A′ parti-

tionierend. Wegen

s(a1) + s(a2) = 3s(P ),

konnen nicht sowohl a1 als auch a2 in einer partitionierenden Teilmenge sein. Wir nehmeno.B.d.A.

a1 ∈ A′

an. Dann gilt fur

M := A′ \ a1

wegen (13.11)

s(M) = β,

woraus folgt, daß M ein dreidimensionales Matching ist.Wir fassen die soeben konstruierte Reduktion zusammen.

255

Page 258: Skript Waack merged

Großschritt 1.Ist Ungleichung 13.8 erfullt, so gib eine unlosbare Instanz von PARTITION aus.

Großschritt 2.Berechne die Instanz (A, s) gemaß (13.5), (13.9), (13.10), (13.11) und (13.12)

und gib sie aus.

Satz 13.4 Das Entscheidungsproblem KNAPSACK ist NP-vollstandig.

Beweis. Wir reduzieren PARTITION auf KNAPSACK. Sei (A, s) eine Instanz vonPARTITION, wobei wir o.B.d.A. annehmen wollen, daß A = 1, 2, . . . , n ist.

Großschritt 1.Ist

∑ni=1 s(n) ungerade, so gib eine unlosbare Instanz von KNAPSACK aus.

Großschritt 2.Berechne die Instanz

I(A, s) :=(w1 = c1 = s(1), . . . , wn = cn = s(n), W = C = 1

2·∑n

i=1 s(n))

und gib sie aus.

Die Korrektheit des vorstehenden Reduktionsalgorithmus ergibt sich aus den folgendenbeiden Bemerkungen.

Ist∑n

i=1 s(n) ungerade, so kann es keine partitionierende Indexmenge geben.Im Falle, daß

∑ni=1 s(n) gerade ist, hat I(A, s) genau dann eine Losung, wenn A eine

partitionierende Indexmenge hat.

13.2 Probleme aus der Graphentheorie

Definition 13.5 Sei G = (V, E) ein ungerichteter Graph. Eine Teilmenge V ′ der Knoten-menge V heißt

– Clique, wenn der durch V ′ in G induzierte Teilgraph der vollstandige Teilgraph ist.

– unabhangige Menge (IS), wenn der durch V ′ in G induzierte Teilgraph keine Kantenenthalt.

– Vertex Cover (VC), wenn jede Kante e aus E zu einem Knoten aus V ′ inzidiert.

Ist G = (V, E) ein ungerichteter Graph, so heißt G = (V, E) der zu G komplementareGraph. Es ist

(u, v) ∈ E : ⇐⇒ (u, v) 6∈ E.

Die drei Begriffe aus Definition 13.5 sind eng miteinander verwandt.

256

Page 259: Skript Waack merged

Lemma 13.6 Sei G = (V, E) ein ungerichteter Graph, und sei V ′ eine Teilmenge der

Knotenmenge V .

Dann gilt. Die Menge V ′ ist genau dann Clique in G, wenn V ′ im komplementaren

Graphen G eine unabhangige Menge ist.

Beweis. Es ist

V ′ ist Clique in G ⇐⇒ ∀u∀v(u, v ⊆ V ′, u 6= v ⇒ u, v ∈ E

)

⇐⇒ ∀u∀v(u, v ⊆ V ′, u 6= v ⇒ u, v 6∈ E

)(Definition von E)

⇐⇒ V ′ ist IS in G.

Lemma 13.7 Sei G = (V, E) ein ungerichteter Graph, und sei V ′ eine Teilmenge der

Knotenmenge V .

Die Menge V ′ ist genau dann eine Clique in G, wenn V \V ′ im komplementaren Graphen

G ein Vertex Cover ist.

Beweis. Es ist

V ′ ist Clique in G ⇐⇒ ∀u∀v(u, v ⊆ V ′, u 6= v ⇒ u, v ∈ E

)

⇐⇒ ∀u∀v(u, v ∈ E ⇒ u, v ∩ (V \ V ′) 6= ∅

)(Kontraposition)

⇐⇒ V \ V ′ ist VC von G.

Problem 10 (Entscheidungsproblem CLIQUE)

Eingabe: ein Graph G = (V, E) und ein Schwellenwert c ∈ N mit c ≤ |V |.

Ausgabe: Akzeptiere genau dann, wenn G eine Clique V ′ mit |V ′| ≥ c hat.

Problem 11 (Entscheidungsproblem IS)

Eingabe: ein Graph G = (V, E) und ein Schwellenwert c ∈ N mit c ≤ |V |.

Ausgabe: Akzeptiere genau dann, wenn G eine IS V ′ mit |V ′| ≥ c hat.

Problem 12 (Entscheidungsproblem VC)

Eingabe: ein Graph G = (V, E) und ein Schwellenwert c ∈ N mit c ≤ |V |.

257

Page 260: Skript Waack merged

Ausgabe: Akzeptiere genau dann, wenn G ein VC V ′ mit |V ′| ≤ c hat.

Satz 13.8 Das Entscheidungsproblem CLIQUE ist NP-vollstandig.

Beweis. Die Zugehorigkeit von CLIQUE zur Klasse NP ist klar.Wir reduzieren 3SATexakt auf CLIQUE. Sei F = K1, K2, . . . , Kr eine exakte 3-CF,

wobei fur j = 1, 2, . . . , r die Klausel Kj = aj ∨ bj ∨ cj ist.Wir konstruieren in Polynomialzeit einen Graphen

GF := (VF , EF )

wie folgt:

VF := (Kj, aj), (Kj, bj), (Kj, cj) | j = 1, 2, . . . , r

EF ∋ (K, d), (K ′, d′) ⇐⇒ K 6= K ′ und d′ 6= d

Man uberlegt sich leicht, daß

– GF nur Cliquen der Machtigkeit kleiner oder gleich r haben kann;

– jede widerspruchsfreie Auswahlfunktion α zu einen r-Clique (K, α(K)) |K ∈ Ffuhrt;

– jede r-Clique als Graph einer widerspruchsfreien Auswahlfunktion abgesehen werdenkann.

Folglich ist die Abbildung

F = K1, K2, . . . , Kr 7→ (GF , r)

eine Polynomialzeit-Reduktion von 3SATexakt auf CLIQUE.

Korollar 13.9 Das Entscheidungsproblem IS ist NP-vollstandig.

Beweis. Die Zugehorigkeit von IS zur Klasse NP ist klar.Gemaß Lemma 13.6 ist die Abbildung

(G, c) 7→ (G, c)

eine Polynomialzeit-Reduktion von CLIQUE auf IS.

Korollar 13.10 Das Entscheidungsproblem VC ist NP-vollstandig.

258

Page 261: Skript Waack merged

Beweis. Die Zugehorigkeit von VC zur Klasse NP ist klar.Gemaß Lemma 13.7 ist die Abbildung

(G, c) 7→ (G, |V | − c)

eine Polynomialzeit-Reduktion von CLIQUE auf VC.

Definition 13.11 Sei G = (V, E) ein ungerichteter Graph. Ein Kreis C in G heißt Hamil-tonsch (HC), wenn er jeden Knoten aus V genau einmal enthalt.

Man uberlegt sich leicht Beispiele fur Graphen, die einen HC haben, und fur Graphen,die keinen HC haben.

Problem 13 (Entscheidungsproblem HC)

Eingabe: ein Graph G = (V, E).

Ausgabe: Akzeptiere genau dann, wenn G einen HC hat.

Satz 13.12 Das Entscheidungsproblem HC ist NP-vollstandig.

Beweis. Siehe [CLRS01].

Die NP-Vollstandigkeit des folgenden Rundreiseproblems ist der Grund dafur, warumTransportoptimierung schwierig ist.

Problem 14 (Entscheidungsproblem TSP)

Eingabe: eine Abbildung

γ : 1, 2, . . . , n2 → N

mit

γ(i, i) = 0 (i = 1, 2, . . . , n)

und eine Schwelle c ∈ N .

Ausgabe: Akzeptiere, falls es eine Permutation π der Menge der”Stadte“ 1, 2, . . . , n

gibt, die fur eine Rundreise steht, fur deren Kosten gilt:

γ(π) := γ(π(n), π(1)) +

n−1∑

i=1

γ(π(i), π(i + 1)) ≤ c.

259

Page 262: Skript Waack merged

Satz 13.13 Das Rundreiseproblem TSP ist NP-vollstandig.

Beweis. Offenbar ist TSP in NP.Fur jeden Graphen mit n Knoten kann man o.B.d.A. annehmen, daß seine Knotenmenge

gleich 1, 2, . . . , n ist.Man sieht sofort ein, daß die Abbildung

G = (1, 2, . . . , n, E) 7→ (γG, 0)

mit

γG : 1, 2, . . . , n2 → N,

wobei fur i 6= j

γG(i, j) :=

0 falls (i, j) ∈ E;

1 falls (i, j) 6∈ E

ist, eine Polynomialzeit-Reduktion von HC auf TSP ist.

260

Page 263: Skript Waack merged

Literaturverzeichnis

[CLRS01] T. H. Cormen, C. E. Leiserson, R. L. Rivest, and C. Stein. Introduction to

Algorithms. MIT Press, 2001.

[Pap94] C. H. Papadimitriou. Computational Complexity. Addison–Wesley, 1994.

261