Algorithmen und Datenstrukturen

Werbung
Algorithmen und Datenstrukturen
28. April 2014
Inhaltsverzeichnis
1
2
3
Online-Algorithmen
1.1 Grundbegriffe . . . . . . . . . . . . . . . . . . . . . . . .
1.1.1 Einführungs-Beispiel: Ski-Rental Problem . . . .
1.2 Amortisierte Analyse . . . . . . . . . . . . . . . . . . . .
1.2.1 Amortisierte Analyse eines Binärzählers . . . . . .
1.3 List-Accessing . . . . . . . . . . . . . . . . . . . . . . .
1.3.1 Der Algorithmus Move-To-Front . . . . . . . . . .
1.3.2 Deterministische untere Schranke . . . . . . . . .
1.4 Paging-Probleme . . . . . . . . . . . . . . . . . . . . . .
1.4.1 Deterministische Paging-Algorithmen . . . . . . .
1.4.2 Randomisierte Paging-Algorithmen . . . . . . . .
1.5 Weiterführende Literatur . . . . . . . . . . . . . . . . . .
1.6 Grundlagen der Wahrscheinlichkeitsrechnung - Erinnerung
Suchbäume
2.1 Splay-Bäume . . . . . . . . . . . . . . . . . . .
2.1.1 Operationen auf Splay-Bäume . . . . . .
2.1.2 Analyse der SPLAY-Operation . . . . . .
2.1.3 Statische Optimalität von Splay-Bäumen
2.2 Randomisierte Suchbäume . . . . . . . . . . . .
2.2.1 Der randomisierte Quicksort Algorithmus
2.2.2 Randomisierte Suchbäume . . . . . . . .
2.3 Weiterführende Literatur . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
3
4
5
7
7
10
10
12
14
14
19
23
24
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
28
28
29
32
36
38
38
41
44
Datenmanagement in Netzwerken
3.1 Definition des File-Allocation-Problems (FAP) . . . .
3.2 FAP auf Bäumen . . . . . . . . . . . . . . . . . . . .
3.3 Deterministische untere Schranke für FAP . . . . . . .
3.4 FAP auf allgemeinen Graphen . . . . . . . . . . . . .
3.4.1 Deterministische Approximation von Metriken
3.4.2 Probabilistische Approximation von Metriken .
3.4.3 Randomisierter Online-Algorithmus . . . . . .
3.5 Weiterführende Literatur . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
46
47
47
51
52
52
55
58
59
1
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
4
Lastbalancierung
4.1 Identische Maschinen . . .
4.2 Eingeschränkte Maschinen
4.3 Verwandte Maschinen . . .
4.4 Weiterführende Literatur .
.
.
.
.
.
.
.
.
.
.
.
.
Literatur
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
60
60
61
63
65
66
2
Kapitel 1
Online-Algorithmen
Die klassische Entwicklung und Analyse von Algorithmen geht davon aus, dass die
zur Lösung eines Problems benötigten Daten zu Beginn der Berechnungen vollständig
vorliegen. In vielen Anwendungen ist diese Annahme jedoch unrealistisch: Algorithmische Probleme, die in der Praxis auftreten, sind oftmals online. D.h. relevante Daten
treffen erst nach und nach ein und müssen vom Algorithmus auch seriell verarbeitet werden (d.h. dass er üblicherweise die Daten nicht horten“ kann und nach jeder
”
neuen Information eine Entscheidung treffen muss, die er später nicht mehr kostenlos
zurücknehmen kann.
Ein Online-Algorithmus muss die Daten trotzdem zu einer Ausgabe verarbeiten.
Im Gegensatz zu einem Offline-Algorithmus, der zu Beginn seiner Berechnungen die
vollständige Sequenz der Daten bekommt, kennt er keine zukünftigen Daten. Er kann
also nicht vorhersehen, welche Entscheidungen die günstigsten Auswirkungen auf
spätere Berechnungsschritte haben werden. Trotzdem sollte der Online-Algorithmus
auch ohne dieses Wissen versuchen, seine Entscheidungen so zu treffen, dass sie ihn
in der Zukunft nicht behindern.
Für die Bewertung von Algorithmen sind weiterhin Kriterien wie benötigte Laufzeit und Speicherplatz von Bedeutung, aber auch die Güte der Lösung. Dabei sind
oft Analyseverfahren, die für Offline-Algorithmen angewendet werden, nicht einfach
übertragbar.
In diesem Kapitel werden also Grundbegriffe zu Online-Algorithmen, einige Beispielprobleme und -algorithmen und die Analyseverfahren, mit denen Laufzeit, Speicherplatz und Güte eines Online-Algorithmus beurteilt werden können, vorgestellt.
3
1.1
Grundbegriffe
Bei Online-Problemen handelt es sich um eine spezielle Art von Optimierungsproblemen. Im Allgemeinen sagen wir, dass ein Optimierungsproblem1 aus einer Menge
von Eingaben I, möglichen Ausgaben O und einer Kostenfunktion C : I × O → R besteht. Für jede Eingabe i ∈ I gibt es eine Menge von zulässigen Ausgaben (Lösungen)
F(i) ∈ O. Mit jeder Lösung o ∈ F(i) sind Kosten C(i, o) assoziiert, die die Kosten für
Ausgabe o bei Eingabe i darstellen.
Ein Algorithmus ALG berechnet nun bei Eingabe i ∈ I eine Lösung o ∈ F(i). Die
Kosten von ALG sind dann ALG(i) = C(i, o). Ein optimaler Algorithmus OPT berechnet dementsprechend für jede Eingabe i ∈ I eine Lösung mit geringsten Kosten und hat
damit selbst die Kosten:
OPT(i) = min C(i, o) .
o∈F(i)
Mit Hilfe dieser Beschreibung der Kosten können wir nun definieren, wie man die
Güte eines Online-Algorithmus bewertet. Zur Erinnerung: Der Online-Algorithmus
arbeitet auf einer Sequenz von Eingabedaten und kann sich wegen fehlender Kenntnis
der zukünftigen Daten nicht immer optimal verhalten. Wir beschreiben dann seine
Güte im direkten Vergleich zu den Kosten eines optimalen Algorithmus:
Definition 1.1 Ein Online-Algorithmus ALG ist c-kompetitiv, wenn für jede Eingabesequenz σ gilt
ALG(σ) ≤ c · OPT(σ) + α ,
wobei α eine von σ unabhängig Konstante ist. Wenn α = 0, ist ALG streng ckompetitiv.
Der kompetitive Faktor oder Kompetitiv-Faktor eines Online-Algorithmus ALG bezeichnet das Infimum über alle Werte c mit der Eigenschaft, dass ALG c-kompetitiv
ist.
Um die Kosten eines Online-Algorithmus zu analysieren, verwendet man häufig
eine der folgenden Methoden: Einerseits die amortisierte Analyse, bei der statt der
Maximal-Kosten in jedem Schritt die Auswirkungen vorangegangener Schritte auf
dieses Maximum berücksichtigt werden, und andererseits ein Gegenspieler oder Adversary (manchmal auch grausamer Gegenspieler). Dieser Gegenspieler hat das Ziel,
maximale Kosten für den Algorithmus zu verursachen und erzeugt in Kenntnis seiner
Vorgehensweise eine möglichst schlechte Sequenz. Eine solche möglichst schlechte
Seuqenz für einen Algorithmus erreicht den Kompetitiv-Faktor des Algorithmus.
1
wir betrachten hier o.b.d.A. nur Minimierungsprobleme
4
1.1.1
Einführungs-Beispiel: Ski-Rental Problem
Wir möchten zum ersten Mal in unserem Leben Ski fahren. Als Anfänger haben wir
keine Ausrüstung und müssen uns jeden Tag entscheiden: Sollen wir die Ausrüstung
für diesen Tag für 50 Euro ausleihen oder sollen wir sie komplett für 800 Euro kaufen?
Würden wir genau 16 Tage Ski fahren, hätten wir die selben Ausgaben fürs Leihen
oder Kaufen. Leider können wir nicht gut voraus planen: Das Skigebiet steht uns prinzipiell den gesamten Winter über zur Verfügung, aber wir könnten aus verschiedenen
Gründen verhindert sein; beispielsweise durch schlechtes Wetter.
Wir wollen einen Online-Algorithmus finden, der an jedem Tag mit gutem Wetter
entscheidet, ob wir die Ski leihen oder kaufen. Das Wetter der nächsten Tage ist nie
bekannt, eine Entscheidung kann nur basierend auf der Vergangenheit und Gegenwart
getroffen werden. Man kann sich hier einen Wettergott als Gegenspieler vorstellen,
der als mögliche Eingaben eine Folge von Tagen mit schlechtem oder gutem Wetter
produziert. Seine Strategie, eine möglichst teure Situation zu konstruieren, könnte sein:
Er sorgt solange für gutes Wetter, wie wir die Ausrüstung leihen und ab dem Kauf für
schlechtes Wetter, sodass wir die Ski nicht mehr nutzen. Der Verlust bezogen auf die
Entscheidung an diesem Tag sind also immer 800-50=750. Uns interessiert aber der
gesamte Verlauf.
Unser Online-Algorithmus produziert zu einer Eingabe dieser Tage also eine Ausgabe: Die Entscheidungen, zu leihen oder zu kaufen. Die Kosten dieser Entscheidungsfolge sind das investierte Geld, nach der Kostenfunktion: C(i, o) = Leihtage ·
50 + Kau f entscheidung · 800.
Was ist eine gute Strategie für unseren Algorithmus? Zu früh“ zu kaufen bedeutet,
”
dass wir schlimmstenfalls am ersten Tag 800 Euro ausgeben, danach nur noch schlechtes Wetter folgt und wir 750 Euro mehr ausgegeben haben, als für die optimale Lösung
(die Ski zu leihen) nötig gewesen wären. Zu spät“ zu kaufen bedeutet, dass wir die
”
Leihgebühr all der frühen Tage zusätzlich zum Kaufpreis der Ski zahlen.
Unser Algorithmus entscheidet folgendermaßen: Die ersten 15 Mal werden die Ski
geliehen, am 16. Tag bei gutem Wetter gekauft.
Natürlich kann der Gegenspieler-Wettergott damit eine schlimmstmögliche Situation für uns konstruieren und nach dem 16. Tag für Regen sorgen. Wie sieht also der
Kompetitiv-Faktor des Algorithmus aus?
• Fall 1: Wir fahren weniger als 15 mal Ski, d.h. k < 16 bzw. 50k < 800
Optimal: Es ist am besten, die Ski nur zu leihen zu Kosten von k · 50 Euro.
Online: Der Online-Algorithmus zeigt das gleiche Verhalten wie der optimale
Algorithmus, er hat minimale/optimale Kosten von k · 50 Euro.
• Fall 2: Wir fahren mindestens 16 mal Ski, d.h. k ≥ 16 bzw. 50k ≥ 800
Optimal: Man sollte Ski kaufen zu Kosten von 800 Euro.
Online: Der Online-Algorithmus entscheidet, 15 mal zu leihen und dann zu kaufen, er hat also in etwa doppelte Kosten von k · 50 + 800 = 1550 Euro. Genauer
5
50
gesagt hat der Algorithmus die (1 + (1 − 800
))-fachen Kosten des optimalen Algorithmus. Beachte, dass sich die Kosten für den Online-Algorithmus und unseren Algorithmus nach dem 16. Tag nicht mehr erhöhen.
Leihen
))-fache Kosten
Der Algorithmus verursacht also schlimmstenfalls (1 + (1 − Kaufen
der optimalen Lösung:
ALG(σ) ≤ (2 −
Leihen
) · OPT(σ) ,
Kaufen
Leihen
und hat somit einen Kompetitiv-Faktor von (2 − Kaufen
).
6
1.2
Amortisierte Analyse
Die Analyse von Online-Algorithmen ist wie erwähnt nicht immer mit den Methoden
möglich, die man von der Analyse von Offline-Algorithmen kennt. In vielen Fällen
hängen die Kosten eines Schritts davon ab, welche Situation vorher erzeugt wurde.
Statt einfach die überhaupt schlechteste Situation für alle Schritte anzunehmen, kann
man oft bessere Beschränkungen der Laufzeit finden, in dem man zeigt, dass diese Situation nur beschränkt häufig auftreten kann. Man betrachtet also die maximal
möglichen Kosten eines Schritts unter Berücksichtigung vorangegangener Schritte.
Die amortisierte Analyse ist eine ursprünglich für dynamische Datenstrukturen entwickelte Analysemethode, die sich auch gut auf viele Online-Algorithmen anwenden
lässt. Sie berechnet die durchschnittlichen Kosten einer Worst-Case-Eingabe“, wobei
”
diese Worst-Case-Eingabe sorgfältig konstruiert werden muss.
Zunächst gewährt man dem Algorithmus ein gewisses Guthaben, von dem er mit
jeder einzelnen Operation die Kosten dieser Operation verbraucht. Wenn in einer Operation weniger als der ihr zugeordnete Anteil des Guthabens verbraucht wird, kann das
gesparte Guthaben in einem späteren, teureren Schritt verbraucht werden.
Mithilfe der amortisierten Analyse kann man die durchschnittlichen Kosten einer
Sequenz σ1 , . . . , σn von Anfragen mit Kosten c1 , . . . , cn analysieren. Dabei gilt:
Worst-Case-Kosten von σ = max ci
i
Gesamtkosten von σ =
∑ ci
i
Amortisierte Kosten von σ =
∑ ci/n
i
Als amortisierte Kosten (von Operationen auf) der Datenstruktur bezeichnet man dann
das Maximum der amortisierten Kosten von σ über alle Folgen σ: maxσ (∑i ci /n) .2
1.2.1
Amortisierte Analyse eines Binärzählers
Wir werden nun amortisierte Analyse anhand des Beispiels eines k-Bit-Binärzählers
kennenlernen. Der k-Bit-Binärzähler besteht aus k Bits, die zu Beginn alle auf 0 stehen.
Die einzige mögliche Operation ist das Erhöhen des Zählers um 1 (bis k Bits auf 1
stehen). Die Anzeige ändert sich, in dem man von links nach rechts einzelne Bits von
1 auf 0 flippt, bis man zum ersten mal ein Bit von 0 auf 1 flippt. Die Kosten der
Operation sind durch die Zahl der Flips definiert.
Offensichtlich gilt, dass die Kosten für das Erhöhen des Zählers im Worst-Case k
sind. Dieser Wert gilt jedoch nur für den Fall, dass der Zähler bis jetzt auf 2k−1 − 1 beziehungsweise (01...1) stand. Was sind also die amortisierten Kosten für das Erhöhen
des Zählers?
2 Weitergehende Informationen zur amortisierten Analyse von Datenstrukturen findet man z.B. in Introduction To Algorithms Herausgeber Thomas H Cormen Mitwirkende Leiserson, C.E. and Rivest, R.L.
and Stein, C. - auch abzurufen unter http://books.google.de/books?id=NLngYyWFl_YC
7
Theorem 1.2 Die amortisierten Kosten für das Erhöhen eines Zählers sind O(1).
Es gibt für die amortisierte Analyse drei übliche Blickwinkel. Sie werden als die des
Bankers, des Physikers und des Ingenieurs bezeichnet3 .
Sichtweise des Bankers
Wir beginnen mit der Sichtweise, die die Idee des Guthabens am direktesten aufgreift.
Für jede Operation stehen zunächst cb Euro zur Verfügung. Von diesen cb Euro müssen
zunächst die Kosten der Operation bezahlt werden, wobei eventuell übrig gebliebenes
Geld gespart werden kann. Sind die Kosten für eine Operation größer als cb, so müssen
sie mit Geld vom Konto bezahlt werden.
Beobachtung 1.3 Hat ein System immer einen nicht-negativen Kontostand, dann ist cb
eine obere Schranke für die amortisierten Kosten des Systems, weil in keinem Schritt
mehr als durchschnittlich cb Euro verbraucht wurden.
Um nun unser Beispiel des Binärzählers zu analysieren, setzen wir cb = 2. Wir werden für jedes Bit einen eigenen Kontostand einführen und induktiv zeigen, dass der
Kontostand nicht-negativ bleibt.
Es soll folgende Invariante gelten: Der Kontostand eines Bits ist 1, wenn der Wert
des Bits 1 ist und 0 sonst.
Zu Beginn stehen alle Bits auf 0. Für die erste Operation stehen cb = 2 Euro zur
Verfügung. In der ersten Operation wird nur das erste Bit von 0 auf 1 geflippt. Für
die erste Operation haben wir einen Euro für das Flippen gezahlt und den übrigen Euro auf das Konto des kleinsten Bits überwiesen, das jetzt 1 Euro enthält. Also stimmt
unsere Behauptung für die erste Operation.
Wir nehmen an, dass unsere Behauptung für die ersten m Operationen stimmt. In Operation m + 1 werden nun die kleinsten j Bits des Zählers geflippt, von denen zuvor die
kleinsten j − 1 auf 1 standen und das j-te Bit auf 0 (entsprechend sieht also auch der
Kontostand der Bits aus). Wir zahlen das Flippen der j − 1 Bits von den Konten dieser
Bits und das Flippen des j-ten Bit von unseren 2 Euro für die Operation. Den übrigen
Euro zahlen wir auf das Konto von Bit j ein.
Unsere Invariante gilt also auch nach Operation m + 1 und damit per Induktion für
alle Schritte.
Sichtweise des Physikers
Hier wird das Guthaben durch überschüssige Energie als Potential des gesamten Systems gespeichert. Dieses Potential wird benutzt, um für Operationen zu bezahlen,
3
Andere Namen für die Methoden sind die Account-/Konto-, Potentialfunktions- und Aggregatmethode.
8
die mehr Energie kosten, als sie bringen. Das Potential zum Zeitpunkt i wird mit Φi
bezeichnet. Sei
cb ≥ ci + Φi − Φi−1 .
Damit gilt für m Schritte:
m
m
m
m · cb = ∑ cb ≥ ∑ (ci + Φi − Φi−1 ) = ∑ ci + Φn − Φ0 .
i=1
i=1
i=1
Beobachtung 1.4 Wenn Φm ≥ Φ0 ist, dann ist cb eine obere Schranke für die amortisierten Kosten.
Wir wenden nun die Potentialmethode auf unser Binärzähler Problem an. Sei Φi
die Anzahl Bits, die zum Zeitpunkt i auf 1 gesetzt sind. Es gilt Φm ≥ 0 = Φ0 . Wir
betrachten die m-te Operation. Sei j die Position des Bits, das auf 1 geflippt wird (und
alle Bits an Positionen kleiner j werden auf 0 geflippt). Dann gilt
Φm − Φm−1 = 1 − ( j − 1) = 2 − j .
Also sind die amortisierten Kosten höchstens
cm + Φm − Φm−1 = j + (2 − j) = 2 .
Sichtweise des Ingenieurs
Bei dieser Methode versucht man, die tatsächlichen Gesamtkosten für das Problem zu
berechnen, und teilt diese dann durch n, um die amortisierten Kosten einer Operation
zu erhalten. So erhält man wirklich einen Durchschnittswert, statt die Kosten einzelner
Operationen zu untersuchen. Diese Art der Berechnung ist sehr direkt und exakt, meist
deswegen aber auch schwierig oder im Ergebnis nicht handhabbar. Für den Binärzähler
stellen wir fest, dass das kleinste Bit b0 jedes Mal geflippt wird. Das zweitkleinste Bit
b1 wird jedes zweite Mal geflippt. Das Bit bi wird jedes 2i -te Mal geflippt. Für m
Operationen ergeben sich amortisierten Kosten
cb =
blog mc m
b 2i c
∑i=0
m
9
<2 .
1.3
List-Accessing
Als erstes werden wir uns mit dem List-Accessing-Problem beschäftigen. Dabei nehmen wir an, dass ` Datensätze in einer einfach verketteten Liste abgespeichert sind. Zu
jedem Datensatz gibt es einen Schlüssel. Datensätze könnten z.B. Kundendaten sein
und der Schlüssel ist der Kundenname oder eine ID-Nummer. Verkettete Listen sind
eine bekannte Implementierung des abstrakten Datentyps Wörterbuch. Die Implementierung durch verkettete Listen ist sehr einfach und wird daher häufig für Wörterbücher
moderater Größe genutzt.
Um auf einen bestimmten Datensatz zuzugreifen, wird die Liste von vorne bis hinten
durchlaufen bis man auf den gesuchten Datensatz trifft oder am Ende der Liste weiß,
dass er nicht vorhanden ist. Wir nehmen an, dass wir für eine solche Such-Operation x
Schritte benötigen, wobei x die Position des Datensatzes in der Liste ist. Das Löschen
des x-ten Datensatzes in der Liste kostet auch x Schritte. Das Einfügen eines Datensatzes kostet ` + 1 Schritte, wobei ` die Länge der Liste vor Einfügen des Datensatzes
ist4 .
Es handelt sich um ein Online-Problem, wenn nach einem Zugriff oder dem Einfügen
bzw. Löschen eines Datensatzes in der Liste erlaubt ist, die Liste neu zu sortieren. Wir
messen die Kosten zur Reorganisation der Liste in Transpositionen (Vertauschungen
benachbarter Elemente): Jede Transposition kostet einen Zeitschritt. Es gibt jedoch
eine Sonderregel: Einen Datensatz, auf den gerade zugegriffen wurde, dürfen wir kostenlos näher zum Listenanfang verschieben. Die Idee ist hier, dass wir bei der vorangegangenen Suche nach diesem Datensatz Zeiger zu den bisher besuchten Positionen
aufrecht erhalten können.
Beim List-Accessing-Problem ist also ein Online-Algorithmus gesucht, der die Liste
nach jedem Zugriff geschickt so reorganisiert, dass die Gesamtzugriffszeit minimiert
wird.
1.3.1
Der Algorithmus Move-To-Front
Der deterministische Algorithmus Move-To-Front (MTF) ist sehr einfach: Nach jedem
Zugriff auf einen Datensatz oder dem Einfügen eines Datensatzes bewegen wir diesen
an die erste Position der Liste, ohne die relative Ordnung der anderen Elemente zu
verändern. Wir werden nun zeigen, dass MTF einen Kompetitiv-Faktor von 2 erreicht.
Theorem 1.5 MTF ist 2-kompetitiv.
Beweis. Wir müssen zeigen, dass für jede beliebige Sequenz von Operationen σ =
σ1 · · · σn (aus Zugriff, Einfügen und Löschen) MTF höchstens doppelt so viele Schritte benötigt wie ein optimaler Offline-Algorithmus OPT. Wir stehen nun vor einem
4
Eine andere Variante des Problems ist das statische List-Accessing-Problem. Dabei sind nur Zugriffsoperationen erlaubt
10
Problem: Im Gegensatz zum Ski-Rental Problem kennen wir keine einfache Beschreibung einer optimalen Offline-Strategie. Wie können wir dann dennoch eine Aussage
über den Kompetitiv-Faktor machen?
Wir werden die Potentialfunktionsmethode verwenden und eine Potentialfunktion
Φi benutzen. Φi gibt die Zahl der Inversionen der Liste von MTF bezüglich der Liste
von OPT nach der i-ten Operation σi an. Eine Inversion ist ein geordnetes Paar von
Datensätzen hx, yi, wobei x in der Liste von MTF vor y steht, aber nach y in der Liste
von OPT. Wir bezeichnen mit con
i die Kosten von MTF für die i-te Operation und mit
off
ci die entsprechenden Kosten von OPT. Wir wollen zeigen, dass für die amortisierten
Kosten von MTF für die i-te Operation gilt:
off
ai = con
i + Φi − Φi−1 ≤ 2 · ci
womit die amortisierten Kosten in einem Schritt von MTF das Doppelte der Kosten des
optimalen Algorithmus im selben Schritt nicht überschreiten, also MTF 2-kompetitiv
ist.
Dafür zerlegen wir die Kosten von OPT bei der Bearbeitung der i-ten Operation
in die Suchkosten S, die Zahl der kostenpflichtigen Transpositionen P und die Zahl
der kostenlosen Transpositionen F dieser Anfrage. Wir wollen nun zeigen, dass die
amortisierten Kosten für die i-te Operation höchstens (2S − 1) + P − F betragen.
Wir betrachten zunächst die Such- bzw. Zugriffsoperation, indem wir zuerst die Kosten analysieren, die MTF verursacht, und danach die, die OPT verursacht.
Ausgangssituation: Sei x der Datensatz, auf den zugegriffen werden soll. Sei j die
Position von x in der Liste von OPT und k die Position in der Liste von MTF. Weiterhin
sei v die Anzahl der Datensätze, die in der Liste von MTF vor x stehen, aber in der Liste
von OPT hinter x stehen.
Dann gibt es k − 1 − v Datensätze, die in beiden Listen vor x liegen. Außerdem gilt
k − 1 − v ≤ j − 1, da x an Position j in der Liste von OPT steht. Also gilt k − v ≤ j.
Veränderung in MTF: Bewegt MTF nun x an die erste Position der Liste, so erzeugt
er k − 1 − v neue Inversionen bezüglich der Liste von OPT, da so viele Datensätze in
beiden Listen vor x standen. Desweiteren eliminiert diese Aktion auch v Inversionen
bezüglich der Liste von OPT, weil diese v Elemente in der Liste von OPT schon hinter
x standen. Also ist der Beitrag durch die Veränderung in MTF zu den amortisierten
Kosten
k
|{z}
Kosten der Suche
+ (k − 1 − v) −
| {z }
neue Inversionen
v
|{z}
= 2(k − v) − 1 ≤ 2 j − 1 = 2S − 1 .
aufgelöste Inversionen
Veränderung in OPT: Die reine Suche von OPT beeinflusst die Potentialfunktion
und damit die amortisierten Kosten nicht. Danach müssen die Transpositionen betrachtet werden: Da x in MTF zu Beginn der Liste steht, verringert jede kostenlose Trans11
position von OPT, die x nach vorn rückt, das Potential um 1, jede andere und damit
bezahlte Transposition von OPT erhöht das Potenzial höchstens um 1.
Daraus folgt für die amortisierten Kosten durch die Veränderungen in MTF und
OPT:
ai ≤ (2S − 1) + P − F ≤ 2(S + P) = 2 · coff
.
i
Da Φn ≥ 0 und Φ0 = 0 ist (die Listen von MTF und OPT sind zu Beginn identisch)
ergibt sich insgesamt für die Kosten von MTF
n
n
n
off
MTF(σ) = ∑ con
i = ∑ ai + Φ0 − Φn ≤ 2 ∑ ci = 2 · OPT(σ) .
i=1
i=1
i=1
Um das selbe Ergebnis für das Einfügen eines Datensatzes oder den Zugriff auf nicht
vorhandene Datensätze zu zeigen, können wir die gleichen Argumente verwenden und
müssen lediglich j = ` + 1 setzen, wobei ` die Länge der Listen bezeichnet.
Der Fall, dass ein Datensatz gelöscht wird ist noch einfacher, da hier keine neuen
Inversionen erzeugt werden und der Beitrag von MTF zu den amortisierten Kosten
k − v ≤ j = s ≤ 2s − 1 ist.
1.3.2
Deterministische untere Schranke
Wir werden eine untere Schranke für deterministische Online-Algorithmen für das statische List-Accessing-Problem kennenlernen. Da dies ein Spezialfall des dynamischen
Modells ist, gilt die Schranke natürlich auch für den allgemeineren Fall.
Theorem 1.6 Jeder deterministische Online-Algorithmus für das statische List2
, wobei `
Accessing-Problem hat einen Kompetitiv-Faktor von mindestens 2 − `+1
die Anzahl der Datensätze in der Liste bezeichnet.
Beweis. Sei eine Liste der Länge ` gegeben. Wir werden nun einen der erwähnten
Gegenspieler einsetzen, der die Vorgehensweise des Algorithmus kennt und eine Anfragesequenz konstruiert, die die höchstmögliche Laufzeit erzeugt.
Die Strategie des Gegenspielers ist in diesem Fall wieder recht einfach: Er fragt immer den Datensatz an, der am Ende der Liste steht, womit er die Kosten der Suche des
Online-Algorithmus maximiert. Für eine Anfragesequenz der Länge n sind dementsprechend die Gesamtkosten des Online-Algorithmus ` · n.
Wir wollen die Leistung des Online-Algorithmus mit der eines besseren OfflineAlgorithmus vergleichen. Statt einen konkreten Algorithmus zu finden und zu beschreiben, werden wir eine Menge von Offline-Algorithmen definieren und berechnen,
wieviel Zeit diese im Durchschnitt brauchen, um die Anfragesequenz zu bearbeiten.
Danach benutzen wir, dass es mindestens einen Offline-Algorithmus geben muss, der
mindestens gut ist wie der Durchschnitt.
12
Wir betrachten alle `! möglichen Permutationen der Liste. Nun ordnen wir leder der
`! Listen einen Offline-Algorithmen zu, der genau diese verwendet und die Reihenfolge der Elemente nicht mehr ändert. Das heißt, die Kosten für einen jeden solchen Offline Algorithmus bestehen aus den Kosten für die initiale Anordnung und den Kosten
für das Beantworten der n Anfragen. Die Kosten für die Umordnung sind O(`2 ) (Bubblesort), also eine Konstante bezüglich der Anfragelänge, da ` nicht von n abhängt.
Nun berechnen wir die durchschnittlichen Zugriffskosten eines dieser `! OfflineAlgorithmen. Dazu berechnen wir die Gesamtkosten aller Algorithmen und teilen sie
durch die Zahl der Algorithmen.
Um die Gesamtkosten zu berechnen, machen wir folgende Beobachtung: Ein Zugriff
auf ein Element x verursacht in jedem Offline-Algorithmen Kosten von i; wobei i die
Position ist, an der x in der jeweiligen Liste steht. Der Zugriff auf x verursacht Kosten
in Höhe von 1 in jeder der Listen, in denen x an erster Stelle steht. Es gibt (l − 1)!
solcher Offline-Algorithmen. Ebenso gibt es jeweils (l-1)! Algorithmen, in denen x an
den übrigen l − 1 Positionen angeordnet ist.
Daher gilt, dass die Gesamtkosten für eine Anfrage von x in allen `! OfflineAlgorithmen genau
`
∑ i · (` − 1)! = (` − 1)! ·
i=1
` · (` + 1) (` + 1)!
=
2
2
sind.
Damit sind die Gesamtkosten für n Anfragen
n·
(` + 1)!
+ `! · O(`2 )Sortieren
2
und wir erhalten Durchschnittskosten von
1
n(` + 1) + O(`2 ) .
2
Daher gibt es auch mindestens einen Offline-Algorithmus, der höchstens diese Kosten
hat, und mit dem wir den Online-Algorithmus vergleichen können.
Für n → ∞ strebt das Verhältnis zwischen Online-Kosten (` · n) und Offline-Kosten
2`
gegen (`+1)
.
13
1.4
Paging-Probleme
Beim Paging-Problem (oder zu deutsch Seitenwechsel-Problem) haben wir einen
Rechner mit einer gewissen Kapazität schnellen Speichers (im folgenden vor allem
Cache, aber auch RAM etc.) und einem großen, langsamen Sekundärspeicher (der
Festplatte). Die Speicherkapazität wird in der Zahl der Seiten k angegeben, die der
Cache halten kann.
Prozessor
...
schneller Speicher der Größe k
langsamer Speicher (ausreichend groß)
Wird eine Seite angefragt, muss sie im schnellen Speicher zur Verfügung stehen. Ist
sie keine der vorhandenen Seiten, muss sie aus dem langsamen Speicher geholt werden
und verdrängt aus einem vollen Cache (mit k anderen Seiten) eine ungenutzte. Dieses
Anfragen einer nicht vorhandenen Seite bedeutet also einen Seitenfehler.
Ein Algorithmus, der das Paging-Problem lösen soll, hat die Aufgabe, zu entscheiden, welche der vorhandenen Seiten er verdrängt, wenn eine Seite angefragt wird,
die er nicht im Cache zur Verfügung hat. Ein Online-Algorithmus weiß dabei wieder nichts über die noch kommenden Seitenanfragen. Er kennt nur die Seiten, die er
im Cache hat, und die zurückliegenden Anfragen. Ein Offline-Algorithmus hingegen
kennt die gesamte Sequenz und kann deswegen so planen, dass er auch die Zukunft
berücksichtigt.
1.4.1
Deterministische Paging-Algorithmen
Wir werden uns zunächst einige deterministische (Online-)Paging-Algorithmen und
Ersetzungsstrategien ansehen und auch einen optimalen Offline-Algorithmus kennenlernen, der im Gegensatz zu anderen optimalen Lösungen leicht zu beschreiben ist.
Für die Analyse der Algorithmen und zur Bestimmung einer unteren Schranke für den
Kompetitiv-Faktor deterministischer Paging-Algorithmen werden wir einen besonderen Kniff zur Analyse kennen lernen.
Ersetzungsstrategien
Alle deterministischen Ersetzungsstrategien wählen nach einer bestimmten Regel die
Seite aus, die sie aus dem Cache entfernen, sobald ein Seitenfehler auftritt.
14
Beispiel Wir betrachten in diesem Kapitel in allen Beispielen jeweils das Verhalten der Ersetzungsstrategien bei einer Größte des schnellen Speichers von k = 3 für
die Sequenz σ = a, a, b, c, c, c, d, c, a, a, a, b zum Zeitpunkt der siebten Anfrage. Es befinden sich also gerade die Seiten a, b und c im schnellen Speicher und der PagingAlgorithmus muss entscheiden, welche der drei er durch d ersetzt.
a
a
c
b
c
c
c
d
a
a
a
c
b
a
b
• Least-Recently-Used (LRU) verdrängt diejenige Seite, deren letzter Zugriff am
längsten zurückliegt.
5
a
a
b
c
c
c
1
c
d
a
a
a
b
c
b
4
Ersetze a
d
• Least-Frequently-Used (LFU) verdrängt diejenige Seite, die am seltensten angefragt wurde, seit sie im schnellen Speicher ist.
a
2
a
b
1
c
c
c
c
d
ersetze b
3
a
a
a
b
c
d
a
• First-In-First-Out (FIFO) verdrängt diejenige Seite, die sich am längsten im
schnellen Speicher befindet.
c
c
b
a
b
→
d
• Last-In-First-Out (LIFO) verdrängt diejenige Seite, die als letztes in den schnellen Speicher geladen wurde.
c
d
b
a
b
a
→
Ein Online-Algorithmus wird als kompetitiv bezeichnet, falls er gegenüber eines optimalen Algorithmus OPT einen Kompetitiv-Faktor hat, der nicht von der Länge der
Eingabesequenz abhängt.
15
Theorem 1.7 LIFO ist nicht kompetitiv.
Beweis. Sei ` eine positive ganze Zahl. Wir betrachten die Sequenz
σ = p1 , . . . , pk , (pk+1 , pk )` .
LIFO macht bei jeder Anfrage nach den ersten k Anfragen einen Seitenfehler. OPT
hingegen behält einfach die Seiten pk und pk+1 im schnellen Speicher und macht gar
keinen Seitenfehler mehr. Da man ` beliebig groß wählen kann, ist LIFO nicht kompetitiv.
Theorem 1.8 LFU ist nicht kompetitiv.
Beweis. Sei ` eine positive ganze Zahl. Wir betrachten die Sequenz
σ = p`1 , . . . , p`k−1 , (pk , pk+1 )`−1 .
LFU macht bei jeder Anfrage nach den ersten (k − 1) · ` Anfragen einen Seitenfehler.
OPT hingegen macht nur einen einzigen Seitenfehler. Da man ` beliebig groß wählen
kann, ist LFU nicht kompetitiv.
Ein optimaler Offline-Algorithmus: LFD
Der optimale Offline-Algorithmus für das Paging-Problem lässt sich insbesondere im
Gegensatz zur optimalen Lösung für das List-Accessing-Problem einfach beschreiben.
• Longest-Forward-Distance (LFD) verdrängt diejenige Seite, deren nächster Zugriff am weitesten in der Zukunft liegt.
1
a
a
b
c
c
c
d
Ersetze b
2
c
a
a
5
a
b
c
d
a
Theorem 1.9 LFD ist ein optimaler Offline Algorithmus für das Paging Problem.
Beweis. Wir zeigen, dass jeder beliebige und damit auch jeder optimale OfflineAlgorithmus OPT in LFD umgeformt werden kann, ohne dass zusätzliche Kosten
entstehen. Dies zeigen wir durch den Vergleich des Verhaltens der Algorithmen auf
eine Anfrage i aus einer Anfragesequenz σ.
Lemma 1.10 Sei ALG ein beliebiger Paging-Algorithmus und sei σ eine Anfragesequenz. Dann gibt es einen Offline-Algorithmus ALGi mit den folgenden Eigenschaften:
• ALGi verhält sich bei den ersten i − 1 Anfragen genauso wie ALG, beide Algorithmen haben also nach i − 1 Anfragen den gleichen Speicherinhalt.
16
• ALGi verhält sich bei der i-ten Anfrage wie LFD.
• ALGi (σ) ≤ ALG(σ).
Wenn wir zeigen können, dass sich solch ein Algorithmus ALGi für jeden Schritt i
konstruieren lässt, ist das Lemma bewiesen und damit auch das Theorem 1.9.
Beweis. Nach der i + 1ten Anfrage habe ALG die Seiten X ∪ {o} und ALGi die Seiten
X ∪ {n} im Speicher, wobei X eine Menge von k − 1 Seiten ist.
Wenn kein Seitenfehler auftritt oder beide die gleiche Seite aus dem Speicher ersetzen, ist also o = n, so folgt das Lemma mit ALG = ALGi .
Wir betrachten die Situation, dass die i-te Anfrage einen Seitenfehler verursacht hat
und o 6= n ist. Jetzt ergeben sich fünf mögliche Situationen:
#
Anfrage
ALG
ALGi
Konsequenz
1
6= n und 6= o
ersetzt o
ersetzt n
Speicherinhalt gleich → X
2
6= n und 6= o
ersetzt 6= o
ersetzt wie ALG
Weiterhin k − 1 identische Seiten
3
n
ersetzt o
kein Fehler
Speicherinhalt gleich → X
4
n
ersetzt 6= o
kein Fehler
Weiterhin k− identische Seiten
5
o
kein Fehler
ersetzt n
Speicherinhalt gleich
Nach den Situationen 1 und 3 haben beide Algorithmen den gleichen Speicherinhalt erzeugt und verhalten sich identisch. In beiden Fällen hat ALGi höchstens so viele
Fehler gemacht wie ALG und die Bedingungen des Lemmas sind erfüllt.
Nach den Situationen 2 und 4 haben beide Algorithmen im Speicher k − 1 identische
Seiten und die nächsten Anfragen lassen sich analog beschreiben (obwohl sich der
Speicherinhalt von ALG und ALGi jetzt in zwei anderen Seiten als den ursprünglichen,
n und o, unterscheidet). In beiden Fällen hat ALGi höchstens so viele Fehler gemacht
wie ALG.
Die einzige Situation, in der ALGi also einen Seitenfehler hat, ALG aber nicht, ist
Situation 5. ALGi hat aber n statt o nach der LFD-Regel in den schnellen Speicher geladen: Dementsprechend muss die nächste Anfrage nach o zu diesem Zeitpunkt weiter
in der Zukunft gelegen haben, als die nächste Anfrage nach n.
o
k
...
n
>k
Seitenfehler für ALGi
17
...
o
Also muss Situation 4 vor Situation 5 aufgetreten sein, und in dieser hat ALG einen
Seitenfehler gehabt. Dementsprechend gilt auch hier, dass ALGi höchstens so viele
Seitenfehler gemacht hat, wie ALG.
Damit erfüllt ALGi alle im Lemma geforderten Eigenschaften..
Aus Lemma 1.10 folgt mit ALG = OPT sofort auch Theorem 1.9.
Markierungsalgorithmen
Sei σ eine Anfragesequenz. Wir teilen σ wie folgt in k-Phasen auf: Phase 0 ist die
leere Sequenz zu Beginn von σ. Phase i > 0 ist die maximale Sequenz, die direkt auf
Phase i − 1 folgt, und in der auf höchstens k verschiedenen Seiten zugegriffen wird.
Wir erinnern uns, dass k die Größe des schnellen Speichers bezeichnet.
Beispiel Für die bereits betrachtete Sequenz σ = a, a, b, c, c, c, d, c, a, a, a, b, sähe die
Unterteilung in k-Phasen für k = 3 so aus:
σ = a, a, b, c, c, c, |d, c, a, a, a, |b
Ein Marking-Algorithmus assoziiert mit jeder Seite im schnellen Speicher ein Bit,
das angibt, ob die jeweilige Seite markiert oder unmarkiert ist. Zu Beginn einer kPhase werden alle Markierungen gelöscht. Während einer k-Phase wird eine Seite
markiert, wenn auf sie zugegriffen wird. Ein Marking-Algorithmus ist nun dadurch gekennzeichnet, dass er niemals markierte Seiten aus dem schnellen Speicher verdrängt,
sondern aus den unmarkierten Seiten wählt. Auf eine Seite, die neu in den schnellen
Speicher geladen wurde, wurde gerade zugegriffen; sie ist also markiert.
Theorem 1.11 Jeder Marking-Algorithmus ALG ist k-kompetitiv.
Beweis. Wir zeigen zunächst, dass ALG höchstens k Seitenfehler pro Phase macht.
Dies folgt sofort, da jede Seite nach ihrem ersten Zugriff markiert ist und somit nicht
mehr aus dem schnellen Speicher entfernt wird. Also kann ALG höchstens einen Fehler pro unterschiedlicher Seite in einer Phase machen.
σ = a, a, b, c, c, c, |d, c, a, a, a, |b
Nun zeigen wir, dass OPT pro Phase (bis auf die letzte) mindestens einen Seitenfehler macht. Sei q die erste Anfrage in Phase i. Wir betrachten die Sequenz, die mit
der zweiten Anfrage von Phase i beginnt und bis einschließlich zur ersten Anfrage der
Phase i + 1 reicht. Zu Anfang dieser Sequenz hat OPT die Seite q und k − 1 andere
Seiten im schnellen Speicher. In dieser Sequenz gibt es Zugriffe auf k verschiedenen
Seiten, die alle ungleich q sind. Also hat OPT mindestens einen Seitenfehler pro Phase
(bis auf die letzte Phase).
Also folgt
ALG(σ) ≤ k · (OPT(σ) + 1) = k · OPT(σ) + k .
18
Wir betrachten die Kompetivität von LRU, indem wir zeigen:
Theorem 1.12 LRU ist ein Marking-Algorithmus.
Beweis. Widerspruchsannahme: LRU ist kein Marking-Algorithmus. Dann verdrängt
LRU während einer Phase eine markierte Seite x.
Wir betrachten den ersten Zugriff auf x in dieser Phase. Hier wird x markiert und ist
zu diesem Zeitpunkt natürlich die Seite, auf die als letztes zugegriffen wurde. Wenn
LRU x verdrängt, ist x die Seite im schnellen Speicher, deren Zugriff am längsten
zurück liegt. Es wurden also in der Zwischenzeit alle k −1 anderen Seiten im schnellen
Speicher angefragt.
Damit ist die Anfrage, wegen der x verdrängt wird, aber die nach einer k + 1-ten
Seite und eine neue Phase muss begonnen haben, so dass x nicht mehr markiert ist.
Also ist LRU ein Marking-Algorithmus, weil er nie eine markierte Seite entfernt.
Korollar 1.13 LRU ist k-kompetitiv.
Eine untere Schranke für deterministische Paging-Algorithmen
Die folgende untere Schranke zeigt, dass Marking-Algorithmen optimal sind.
Theorem 1.14 Jeder deterministische Paging-Algorithmus ALG hat einen KompetitivFaktor von mindestens k.
Beweis. Wir nehmen an, dass es k + 1 verschiedene Seiten gibt. Wir konstruieren eine
Anfragesequenz σ der Länge n so, dass gilt: ALG(σ) ≥ k · OPT(σ). Dafür benutzen
wir wieder den Gegenspieler: Die ersten k Anfragen gehen auf verschiedene Seiten.
Danach fordert der Gegenspieler immer genau die Seite an, die nicht im schnellen
Speicher von ALG ist. Bei einer darauffolgenden Sequenz σ der Länge n hat ALG
somit genau n Seitenfehler.
Der optimale Offline-Algorithmus LFD verdrängt bei einer Anfrage die Seite p nur
dann, wenn alle übrigen k Seiten vorher wieder angefragt werden. Schlimmstenfalls
macht LFD damit also nur einen Fehler je k Anfragen, also: LFD(σ) ≤ nk .
Damit gilt
n
ALG(σ) = n = k ·
≥ k · OPT(σ) .
k
1.4.2
Randomisierte Paging-Algorithmen
Wie sieht der Kompetitiv-Faktor eines randomisierten Algorithmus aus? Wir werden
hier den so genannten blinden Gegenspieler (englisch auch oblivious adversary) kennenlernen, der nicht weniger als sein sehender Counterpart versucht, grausam zu sein.
Sei ALG ein randomisierter Online-Algorithmus. Der blinde Gegenspieler wählt in
19
Kenntnis des Algorithmus (und seiner Wahrscheinlichkeitsverteilung) eine Eingabesequenz σ aus. Er sieht jedoch nicht den Ausgang der Zufallsexperimente des Algorithmus und kann daher nicht genau diese, sondern nur ein wahrscheinliches Ergebnis
vorwegnehmen und eine Anfragesequenz σ möglichst negativ gestalten (daher blinder
Gegenspieler). Wir sagen, dass ALG c-kompetitiv ist, wenn für jede Eingabesequenz
σ gilt
E [ALG(σ)] ≤ c · OPT(σ) + α ,
wobei α eine Konstante ist, die nicht von σ abhängt. Genau wie im deterministischen
Fall bezeichnet der Kompetitiv-Faktor eines randomisierten Online-Algorithmus ALG
das Infimum über alle Werte c mit der Eigenschaft, dass ALG c-kompetitiv ist.
Ein randomisierter Marking-Algorithmus
Der randomisierte Marking-Algorithmus Mark assoziieren mit jeder Seite im schnellen
Speicher ein Bit, das angibt, ob die jeweilige Seite markiert oder unmarkiert ist. Zu
Beginn einer k-Phase werden alle Markierungen gelöscht. Während einer k-Phase wird
eine Seite markiert, wenn auf sie zugegriffen wird. Bei einem Seitenfehler verdrängt
Mark eine uniform zufällig ausgewählte unmarkierte Seite aus dem schnellen Speicher.
Auch der randomisierte Marking-Algorithmus Mark ist dadurch gekennzeichnet, dass
er niemals markierte Seiten aus dem schnellen Speicher verdrängt.
Wir wollen nun zeigen, dass Mark 2Hk -kompetitiv ist, dabei bezeichnet Hk die k-te
harmonische Zahl, d.h.
k
1
Hk = ∑ .
i=1 i
Für die k-te harmonische Zahl gilt
ln k ≤ Hk ≤ ln k + 1 .
Theorem 1.15 Mark ist 2Hk -kompetitiv.
Beweis. Sei σ eine Anfragesequenz. Wir betrachten die Partitionierung von σ in kPhasen. Eine Seite, die direkt zu Beginn einer Phase im schnellen Speicher vorhanden
ist, wird als alt bezeichnet. Jede nicht-alte Seite, die in einer Phase angefragt wird,
wird als neu bezeichnet. Beachte, dass wiederholte Anfragen auf alte oder neue Seiten
die Kosten von Mark nicht erhöhen, da jede Seite, die während einer Phase angefragt
wird, bis zum Ende der Phase im schnellen Speicher gehalten wird.
j–te Anfrage
p1 . . . pmi pmi+1 . . . pk
| {z } | {z }
Phase i
mi neue
k−mi alte
20
Sei mi die Anzahl neuer Seiten, die in Phase i angefragt werden. Innerhalb einer Phase ist es am schlechtesten für Mark, wenn zunächst alle neuen Seiten angefragt werden,
weil so diese ersten mi Anfragen nach neuen Seiten auf jeden Fall mi Seitenfehler verursachen. Wir untersuchen nun die erwartete Anzahl von Seitenfehlern bezüglich der
k − mi Anfragen nach alten Seiten.
Wir betrachten die erste Anfrage nach der j-ten alten Seite p in Phase i. Zu diesem
Zeitpunkt sind noch k − mi − ( j − 1) unmarkierte alte Seiten im schnellen Speicher und
es gibt insgesamt noch k − ( j − 1) unmarkierte alte Seiten (von denen einige im langsamen Speicher sind). Bei einem Seitenfehler verdrängt Mark eine uniform zufällig
ausgewählte unmarkierte Seite aus dem schnellen Speicher. Daher gilt, dass zum Zeitpunkt dieser Anfrage jede unmarkierte alte Seite mit derselben Wahrscheinlichkeit im
schnellen Speicher vorhanden ist. Also gilt
Pr [p ist im schnellen Speicher] =
k − mi − ( j − 1)
.
k − ( j − 1)
Dann folgt
Pr [p ist nicht im schnellen Speicher] = 1 −
mi
k − mi − ( j − 1)
=
.
k − ( j − 1)
k− j+1
Damit gilt für die erwartete Anzahl von Seitenfehlern in Phase i
k−mi
mi +
∑
j=1
mi
= mi + mi · (Hk − Hmi )
k− j+1
= mi · (Hk − Hmi + 1)
≤ mi · Hk .
Wir müssen nun noch eine untere Schranke für die Kosten eines optimalen OfflineAlgorithmus OPT finden. In den Phase i − 1 und i zusammen werden mindestens k +
mi verschiedene Seiten angefragt, d.h. OPT macht mindestens mi Seitenfehler. In der
ersten Phase macht OPT mindestens m1 Seitenfehler. Dann können wir ∑i gerade mi und
∑i ungerade mi als untere Schranke für die Kosten von OPT benutzen. Eine der beiden
Summen ist mindestens 12 ∑i mi . Also sind die Kosten von OPT mindestens 12 ∑i mi . Da
die erwarteten Kosten von Mark höchstens Hk ∑i mi sind, folgt der Satz sofort.
Eine untere Schranke für randomisierte Paging-Algorithmen
Die folgende untere Schranke zeigt, dass Mark asymptotisch optimal ist.
Theorem 1.16 Jeder randomisierte Paging-Algorithmus ALG hat einen KompetitivFaktor von mindestens Hk .
21
Beobachtung 1.17 Ein randomisierter Algorithmus kann auch verstanden werden als
Zufallsverteilung auf einer Menge deterministischer Algorithmen. Jeder deterministische Algorithmus entspricht einem der möglichen Ergebnisse des Zufallsexperiments
im randomisierten Algorithmus.
Beobachtung 1.18 Wenn alle deterministischen Algorithmen zu einer Eingabesequenz σ den Kompetitiv-Faktor c haben, ist c auch untere Schranke für den randomisierten Algorithmus.
Diese Feststellung werden wir hier nicht beweisen. Anschaulich kann man sich klar
machen, dass der randomisierte Algorithmus genau dann die beste Leistung für eine
Eingabesequenz bringen kann, wenn er zufällig den besten deterministischen Algorithmus wählt. Eine niedrigere als dessen Kompetitivität kann der randomisierte Algorithmus also nicht haben.
Für den Beweis konstruieren wir die eine Anforderungsfolge, die für jeden deterministischen Algorithmus erwartet schlecht ist. Dann betrachten wir, welche Kompetitivität ein beliebiger deterministischer Algorithmus darauf erreicht und können eine
untere Schranke für den randomisierten Algorithmus ableiten.
Beweis.
Anforderungsfolge Für einen Cache der Größe k wird die Anforderungsfolge aus
k + 1 Elementen folgendermaßen konstruiert: Das erste Element σ1 wird zufällig
gewählt, danach wird die nächste Anfrage σi+1 zufällig gleichverteilt aus den k Elementen 6= σi gewählt.
k-Phasen Auch diese Folge lässt sich in k-Phasen5 einteilen, deren erwartete Länge
uns hier interessiert.
Man kann sich die k + 1 möglichen Elemente als Knoten eines vollständigen Graphen
vorstellen. Zu jedem Zeitpunkt befindet man sich im Graphen auf dem Knoten, der zur
i-ten Anfrage gehört. Im nächsten Schritt kann man jede der k Kanten zum nächsten
Knoten und damit zur i + 1-ten Anfrage nutzen.
5
Zur Erinnerung: Eine k-Phase beinhaltet alle Anfragen nach k verschiedenen Elementen und endet
mit der letzten Anfrage bevor das k + 1te Element angefragt wird.
22
Der erwarteten Länge einer k-Phase entspricht also die erwartete Zahl von Schritten,
im vollverbundenen Graphen mit k + 1 Knoten bei einem RandomWalk von einem
beliebigen Startknoten aus alle k + 1 Knoten einmal zu erreichen. Diese erwartete Zahl
von Schritten ist kHk 6 .
OPT Der optimale Offline-Algorithmus (LFD) macht, wie wir bereits wissen, genau einen Fehler pro k-Phase und zwar genau beim ersten Element einer k-Phase. Er
entfernt dabei jeweils das erste Element der nächsten Phase aus dem Cache.
Online-Algorithmus Ein beliebiger deterministischer Online-Algorithmus hat zu
jedem Zeitpunkt genau eines der k + 1 Elemente nicht im Cache. Die Wahrscheinlichkeit, dass genau dieses aus den möglichen k Elementen gewählt wird, ist in jedem
Schritt 1k .
In jeder Phase der erwarteten Länge k · Hk macht der deterministische OnlineAlgorithmus also erwartet 1k · k · Hk = Hk Fehler.
Damit macht OPT in jeder Phase genau einen, der deterministische Online-Algorithmus
erwartet Hk Fehler und wir erkennen die untere Schranke für randomisierte OnlineAlgorithmen.
1.5
Weiterführende Literatur
- Introduction To Algorithms (auch für die übrigen Kapitel) - [CLRS09]
- Online Computation and Competitive Analysis - [BEY98]
6
Beweis in der Übung
23
1.6
Grundlagen der Wahrscheinlichkeitsrechnung Erinnerung
Wahrscheinlichkeitsraum
Ein diskreter Wahrscheinlichkeitsraum ist eine endliche Menge Ω = {ω1 , . . . , ωn } von
Elementarereignissen ωi .
Eine Wahrscheinlichkeitsverteilung gibt die Wahrscheinlichkeit Pr [ωi ] = pi an. Dabei muss gelten, dass die Summe der Wahrscheinlichkeiten über alle Elementarereignisse 1 ist, d.h.
∑ Pr [ωi] = 1 ,
ωi ∈Ω
und die Wahrscheinlichkeiten dürfen nicht negativ sein, also
Pr [ωi ] ≥ 0 .
Beispiel 1.19 Sei Ω =
ˆ Würfelergebnis zweier unterscheidbarer Würfel. Dann ist
Ω = {(1, 1), (1, 2), (1, 3, ), (1, 4), (1, 5), (1, 6), (2, 1), (2, 2), . . . , (2, 6), . . . , (6, 6)} .
Da jeder Wurf gleichwahrscheinlich ist, gilt für jedes Elementarereignis a ∈ Ω,
Pr [a] = 1/36 .
Ereignis
Eine Menge W ⊆ Ω heißt Ereignis. Die Wahrscheinlichkeit eines Ereignisses W ist
Pr [W ] =
∑
Pr [ω] .
ω∈W
Beispiel 1.20 Im Beispiel zweier Würfel kann man das Ereignis W = Pasch definieren,
also W = {(1, 1), . . . , (6, 6)}. Für diese Ereignis ergibt sich
Pr [W ] = 6 · 1/36 = 1/6 .
Zufallsvariable
Eine Zufallsvariable ist eine Funktion
X :Ω→R .
Offensichtlich bezeichnet der Begriff Zufallsvariable nicht einfach eine Variable im
klassischen Sinne. Viel mehr ist der Wert X vom Ausgang eines Zufallsexperimentes
abhängig und in diesem Sinne eine Variable.
24
Beispiel 1.21 Im Beispiel Wurf zweier Würfel bezeichnet
X((a, b)) = a + b
die Zufallsvariable für die Summe der beiden Würfel.
Man schreibt auch abkürzend
Pr [X < k]
für
Pr [ω ∈ Ω|X(ω) < k] .
Analog benutzt man auch Pr [X = k] und Pr [X > k].
Erwartungwert
Der Erwartungswert einer Zufallsvariable gibt den durchschnittlichen Wert an, den
eine Zufallsvariable annimmt. Der Erwartungswert E [X] einer Zufallsvariable X ist
definiert als
E [X] = ∑ k · Pr [X = k] .
k∈X(Ω)
Beispiel 1.22 Wir betrachten noch einmal das Werfen von zwei Würfeln und die Zufallsvariable X für die Summe der beiden Würfel. Wir bekommen:
E [X] = 2 · 1/36 + 3 · 1/18 + 4 · 1/12 + · · · + 12 · 1/36 = 7 .
Linearität des Erwartungswertes
Die Linearität des Erwartungswertes ist eine der wichtigsten Eigenschaften, die wir
bei der Analyse randomisierter Algorithmen ausnutzen. Seien X1 , . . . , Xn Zufallsvariablen auf Ω. Dann gilt
"
#
n
n
∑ Xi = ∑ E [Xi] ,
E
i=1
wobei
n
∑ Xi
i=1
i=1
!
n
(ω) = ∑ Xi (ω)
i=1
bezeichnet. Linearität des Erwartungswertes bedeutet also, dass der Erwartungswert
einer zusammengesetzten“ Zufallsvariable bestimmt werden kann, indem man sie als
”
Summe einfacherer“ Zufallsvariablen schreibt und für diese einfachen Zufallsvaria”
blen ihren Erwartungswert bestimmt. Die Summe des Erwartungswertes der einfachen
Zufallsvariablen ist dann der Erwartungswert der zusammengesetzten Zufallsvariable.
25
Varianz
Die Varianz einer Zufallsvariable ist ein Maß für ihre Streuung. Die Varianz ist definiert als
V [X] = E (X − E [X])2 .
Es folgt
V [X] = E (X − E [X])2
h
i
= E X 2 − 2X · E [X] + E [X]2
= E X 2 − 2E [X · E [X]] + E [X]2
= E X 2 − 2E [X] · E [X] + E [X]2
= E X 2 − E [X]2 .
Zwei Zufallsvariable X und Y heißen paarweise unabhängig, wenn gilt
Pr [X = x|Y = y] = Pr [X = x] für alle x, y ∈ R .
Beispiel 1.23 Bezeichnet die Zufallsvariable X das Ergebnis eines Würfelwurfs mit
einem Würfel und Y das Ergebnis eines Würfelwurfs mit einem anderen Würfel, so
sind X und Y paarweise unabhängig. Keine Unabhängigkeit ist gegeben, wenn X das
Ergebnis von Würfel 1 ist und Y die Summe beider Würfel ist.
Ohne Beweis halten wir folgendes fest.
Lemma 1.24 Sind X1 , . . . , Xn paarweise unabhängig, so gilt
"
#
n
V
n
∑ Xi = ∑ V [Xi] .
i=1
i=1
Hilfreiche Ungleichungen
Lemma 1.25 (Markov-Ungleichung) Sei X eine nicht negative Zufallsvariable, dann
gilt für k > 0
Pr [X ≥ k] ≤ E [X] /k .
26
Beweis.
Pr [X ≥ k] =
∑ Pr [X = x]
x≥k
=
1
· ∑ k · Pr [X = x]
k x≥k
≤
1
· ∑ x · Pr [X = x]
k x≥k
≤
1
· ∑ x · Pr [X = x]
k x≥0
=
E [X]
k
Lemma 1.26 (Chebyshev-Ungleichung) Sei X eine Zufallsvariable, dann gilt für k >
0
V [X]
Pr [|X − E [X] | ≥ k] ≤ 2 .
k
Beweis. Mit Hilfe der Markov-Ungleichung folgt
Pr [|X − E [X] | ≥ k] = Pr (X − E [X])2 ≥ k2
E (X − E [X])2
≤
k2
V [X]
=
.
k2
27
Kapitel 2
Suchbäume
Wir haben bereits die einfache Datenstruktur Verkettete Liste“ für ein Wörterbuch
”
kennengelernt. Wie bereits bei ihrer Einführung erwähnt ist diese Implementierung
sehr einfach und wird deswegen vor allem für kleinere Wörterbücher verwendet. Wenn
man größere Datenmengen verwalten möchte, ist sie aber zu ineffizient. Deswegen
betrachten wir nun Suchbäume, die etwas komplexer und damit auch schwieriger zu
analysieren sind. Es ist noch keine (nichttriviale) Kompetitive-Analyse bekannt.
2.1
Splay-Bäume
Wir werden uns zunächst mit sogenannten SPLAY-Bäumen beschäftigen. Diese haben
die Eigenschaft, für eine beliebige Anfragesequenz σ asymptotisch genauso gut zu
sein wie ein optimaler statischer Suchbaum für σ. Ein optimaler statischer Suchbaum
ist ein Suchbaum, der die Zugriffshäufigkeit auf die einzelnen Elemente berücksichtigt
und in dem die am häufigsten aufgerufenen Elemente nah der Wurzel stehen. SPLAYy
x
→
x
A
C
y
A
B
B
C
Abbildung 2.1: Beispiel für eine Rotation am Knoten x bei dem der Knoten B verschoben
wird.
Bäume benutzen die SPLAY1 -Operation, mit deren Hilfe ein Element des Suchbaumes
an die Wurzel rotiert wird. Dabei sorgen die Rotationen dafür, dass der Suchbaum auf
lange Sicht balanciert wird.
1
zu engl. splay - spreizen, ausbreiten
28
Die Kosten einer Operation entspricht der Anzahl der Vergleiche, die notwendig
sind, um das entsprechende Element im Suchbaum zu finden, oder um festzustellen,
dass es nicht im Suchbaum vorhanden ist. Die Kosten für die Reorganisation des Suchbaumes werden in der Anzahl der dafür notwendigen Rotationen gemessen. Es gibt
jedoch eine Sonderregel: Ein Element, auf das gerade zugegriffen wurde, darf umsonst aufwärts rotiert werden. Die Idee dabei ist, dass bei der Suche nach dem entsprechenden Element Zeiger zu den bisher besuchten Positionen aufrecht erhalten werden
können.
2.1.1
Operationen auf Splay-Bäume
Auf SPLAY-Bäumen stehen einige Operationen zur Verfügung, die größtenteils auf
der SPLAY-Operation basieren. Daher wird diese zuerst vorgestellt:
SPLAY(x): Bei einer SPLAY(x)-Operation wird zunächst das Element x im Baum
gesucht. Ist das Element x nicht im Baum vorhanden, so wird der Vorgänger oder
Nachfolger von x mit x identifiziert. Dann wird das gefundene Element mit Hilfe
von Rotationen an die Wurzel des Baumes bewegt. Dabei unterscheiden wir je nach
Baumstruktur zwischen drei Fällen.
1. Ist x ein Kind der Wurzel des Suchbaumes, so wird es mit Hilfe einer Rotation
um die Wurzel höher bewegt.
y
x
→
x
A
C
y
A
B
B
C
Abbildung 2.2: Rotation um y, die x zur Wurzel macht
2. Ist x kein Kind der Wurzel, wird x solange rotiert, bis es Kind der Wurzel oder
Wurzel ist. Dazu betrachtet man auch den Elternknoten von x:
• Ist x linkes Kind eines linken Kindes (oder rechtes Kind eines rechten
Kindes), wird x mit Hilfe von zwei Rechts-Rotationen (oder zwei LinksRotationen) erst um den Groß-Elterknoten, dann um den Elterknoten nach
oben rotiert.
• Ist x linkes Kind eines rechten Kindes (oder rechtes Kind eines linken Kindes), wird x ebenfalls mit Hilfe von zwei Rotationen, erst rechts dann links
(oder erst links, dann rechts).
29
y
z
x
→
y
x
A
→
x
D
C
A
z
B
C
y
A
D
z
B
B
C
D
Abbildung 2.3: Rechts-Rechts-Rotation, da x linkes Kind des linken Kinds y war
z
z
x
→
y
A
x
B
→
x
A
D
y
B
C
C
y
z
A
B
C
D
D
Abbildung 2.4: Rechts-Links-Rotation, da x rechtes Kind des linken Kinds y war
Die anderen auf der SPLAY-Operation beruhenden Operationen sind:
• ACCESS(x): Dies ist die Suchoperation nach dem Element x. Diese Operation
wird durch SPLAY(x) und Ausgabe der Wurzel realisiert.
• INSERT(x): Beim Einfügen eines Elements wird zunächst eine SPLAY(x)Operation durchgeführt, die den Vorgänger oder Nachfolger von x an die Wurzel
rotiert. Ist nun die Wurzel r der Nachfolger von x, so wird x Wurzel des neuen
Suchbaumes. Der linke Teilbaum von r wird zum linken Nachfolger von x und r
wird rechter Nachfolger von x. Ist die Wurzel r der Vorgänger von x, so erfolgt
das Einfügen analog.
• SPLIT(x): Auch bei der SPLIT Operation wird zunächst ein SPLAY(x) durchgeführt. Danach sind alle Elemente im linken Unterbaum der Wurzel kleiner als
x und alle Elemente im rechten Unterbaum größer. Je nachdem, ob die Wurzel kleiner (oder gleich) oder größer als x ist, bleibt sie Wurzel des linken bzw.
rechten Teilbaums.
• DELETE(x): Um ein Element x aus dem Splay-Baum zu löschen wird dieses zunächst mit der SPLAY(x)-Operation an die Wurzel geholt. Dann wird es
gelöscht und die beiden dabei entstehenden Bäume werden mit Hilfe von der
JOIN-Operation wieder zusammengefügt.
30
7
3
→
9
3
7
1
9
1
Abbildung 2.5: ACCESS(5): Erfolglose Suche nach 5. Der zuletzt besuchte Knoten 3 wird an
die Wurzel rotiert und ausgegeben.
7
3
5
→
→
9
3
1
1
7
3
7
9
1
9
Abbildung 2.6: INSERT(5): Dazu wird zunächst 3, der Vorgänger von 5, an die Wurzel rotiert. Nun wird 5 Wurzel des neuen Suchbaumes. Der rechte Teilbaum von 3 wird zum rechten
Nachfolger von 5 und 3 wird der linke Nachfolger von 5.
9
6
6
→
9
3
11
7
3
9
6
→
7
5
1
7
3
11
11
5
1
5
1
Abbildung 2.7: SPLIT(6): Zunächst wird die 6 an die Wurzel rotiert, dann wird der Baum
aufgespalten.
9
6
6
1
→
9
3
11
7
3
9
3
→
1
5
7
1
5
7
11
11
5
Abbildung 2.8: DELETE(6): Zunächst wird 6 an die Wurzel rotiert, dann gelöscht. Die beiden
Bäume werden wie oben durch JOINT verknüpft.
31
• JOIN(T1 , T2 ): Die JOIN Operation vereinigt zwei Bäume T1 und T2 unter der
Voraussetzung, dass die Elemente in T1 alle kleiner sind als die Elemente in
T2 . Bei einem JOIN wird zunächst ein SPLAY(∞) in Baum T1 durchgeführt.
Damit wird das größte Element aus Baum T1 an die Wurzel rotiert und der rechte
Teilbaum unter der Wurzel ist leer. Dort wird nun Baum T2 angehängt.
9
3
1
5
9
5
→
+
7
5
→
+
7
3
11
11
3
1 7
1
9
11
Abbildung 2.9: JOIN(T1 , T2 ): Zunächst wird 5 an die Wurzel von T1 rotiert, dann werden die
beiden Bäume verknüpft.
Wir können also jede Operation mit Hilfe zweier SPLAY-Operationen und eines konstanten Zusatzaufwandes durchführen. Daher interessiert uns für die Analyse in erster
Linie die SPLAY-Operation.
2.1.2
Analyse der SPLAY-Operation
Wir wollen nun die amortisierten Kosten von SPLAY(x) analysieren. Dazu führen wir
eine Potentialfunktion Φ eines Splay-Baumes T ein. Wir nehmen an, dass jeder Knoten x ein positives Gewicht w(x) besitzt (zunächst setzen wir uniform w(x) = 1; später
werden wir jedoch auch andere Gewichte betrachten). Dann können wir das Gewicht
eines Teilbaumes definieren, wobei wir einen Teilbaum mit seiner Wurzel identifizieren:
W (x) =
w(y) .
∑
Knoten y im Teilbaum von x
Den Rang r(x) von x definieren wir als:
r(x) = log2 W (x) .
Letztendlich können wir dann das Potential eines Splay-Baumes T definieren:
Φ(T ) =
∑
r(x) .
Knoten x in T
Betrachten wir nun eine Sequenz σ = σ1 · · · σm von Operationen. Die amortisierten
Kosten ai von Operation σi sind die tatsächlichen Kosten ci von σi plus die Potentialveränderung, die durch σi verursacht worden ist. Im vorherigen Kapitel haben wir
32
schon gesehen, dass dann die tatsächlichen Kosten der Sequenz σ höchstens die amortisierten Kosten von σ plus das Anfangspotential der Datenstruktur sind, d.h.:
m
m
∑ ci ≤ ∑ ai + Φ(T ) ,
i=1
i=1
wobei T der initiale Suchbaum ist. Als erstes wollen wir nun die amortisierten Kosten
einer SPLAY-Operation analysieren.
Lemma 2.1 Die amortisierten Kosten von SPLAY(x) betragen höchstens 1 + 3(r(t) −
r(x)), wobei t die Wurzel des Baumes vor der Operation ist.
Beweis. Wir teilen die SPLAY-Operation in eine Sequenz von Schritten auf. Dabei
ist jeder Schritt gerade einer der drei oben beschriebenen Fälle, die bei einer SPLAYOperation auftreten können bis x die Wurzel des Baums ist. Wir betrachten nun per
Fallunterscheidung die amortisierten Kosten eines Schrittes. Dabei bezeichnet r(y) den
Rang von einem Knoten y vor dem Schritt und r0 (y) den Rang von y nach dem Schritt.
Die amortisierten Kosten setzen sich immer aus der Zahl der Rotationen und der
Veränderung des Potentials Φ(T I zusammen.
y
x
→
x
A
C
y
A
B
B
C
Abbildung 2.10: Fall 1
Behauptung 2.2 Im Fall 1 betragen die amortisierten Kosten höchstens 1 + 3(r0 (x) −
r(x)).
Beweis. Weil eine Rotation benötigt wird, betragen die amortisierten Kosten, da
r0 (x) = r(y) ist (denn x rückt an die Position von y):
1 + r0 (x) − r(x) + r0 (y) − r(y) = 1 + r0 (y) − r(x) .
Weil r0 (y) ≤ r0 (x) ist (y ist jetzt Kind von x), folgt
1 + r0 (y) − r(x) ≤ 1 + r0 (x) − r(x) .
Da r0 (x) ≥ r(x) ist (x ist im Baum hochrotiert), folgt dann
1 + r0 (x) − r(x) ≤ 1 + 3(r0 (x) − r(x)) .
33
y
z
x
→
y
x
A
→
x
D
C
A
z
B
C
y
A
D
B
z
B
C
D
Abbildung 2.11: Fall 2
Behauptung 2.3 Im Fall 2 betragen die amortisierten Kosten höchstens 3(r0 (x) −
r(x)).
Beweis. Weil zwei Rotationen benötigt werden, betragen die amortisierten Kosten da
r0 (x) = r(z) ist
2 + r0 (x) − r(x) + r0 (y) − r(y) + r0 (z) − r(z) = 2 + r0 (y) + r0 (z) − r(x) − r(y) .
Weil r0 (x) ≥ r0 (y) und −r(x) ≥ −r(y) ist, folgt
2 + r0 (y) + r0 (z) − r(x) − r(y) ≤ 2 + r0 (x) + r0 (z) − 2r(x) .
Wir nutzen nun, dass
r0 (z) + r(x) − 2r0 (x) ≤ −2
ist. Damit folgt, dass gilt
2 + r0 (x) + r0 (z) − 2r(x) ≤ 3(r0 (x) − r(x)) .
Wir müssen noch zeigen, dass r0 (z) + r(x) − 2r0 (x) ≤ −2. Dazu setzen wir r0 (z) =
log2 W 0 (z) und r0 (x) = log2 W 0 (x) ein und erhalten
r0 (z) + r(x) − 2r0 (x) = log2 W 0 (z) + log2 W (x) − 2 log2 W 0 (x)
0 W (x)
W (z)
+ log2
.
= log2
W 0 (x)
W 0 (x)
Es gilt
log2
W 0 (z)
W (x)
+ log2
≤ −2 ,
W 0 (x)
W 0 (x)
da W 0 (z) + W (x) ≤ W 0 (x) ist und 0 ≤ a, b ≤ 1 und a + b ≤ 1. Also nimmt der Term
log a + log b sein Maximum für a = b = 1/2 an.
34
z
z
x
→
→
y
A
x
B
x
A
D
y
B
C
y
z
C
A
B
C
D
D
Abbildung 2.12: Fall 3
Behauptung 2.4 Im Fall 3 betragen die amortisierten Kosten höchstens 3(r0 (x) −
r(x)).
Beweis. Weil zwei Rotationen benötigt werden, betragen die amortisierten Kosten da
r0 (x) = r(z) und −r(x) ≥ −r(y) ist
2 + r0 (x) + r0 (y) + r0 (z) − r(x) − r(y) − r(z) ≤ 2 + r0 (y) + r0 (z) − 2r(x) .
Wir zeigen nun, dass
r0 (z) + r0 (y) − 2r0 (x) ≤ −2
ist. Damit folgt dann, dass, da r0 (x) ≥ r(x) ist, gilt
2 + r0 (y) + r0 (z) − 2r(x) ≤ 2(r0 (x) − r(x)) ≤ 3(r0 (x) − r(x)) .
Wir setzen nun r0 (z) = log2 W 0 (z), r0 (y) = log2 W 0 (y) und r0 (x) = log2 W 0 (x) ein und
erhalten
r0 (z) + r0 (y) − 2r0 (x) = log2 W 0 (z) + log2 W 0 (y) − 2 log2 W 0 (x)
0 0 W (y)
W (z)
+ log2
.
= log2
0
W (x)
W 0 (x)
Es gilt
0 W 0 (z)
W (y)
log2
+ log2
≤ −2 ,
0
W (x)
W 0 (x)
da links ein Term der Form log a + log b steht, mit 0 ≤ a, b ≤ 1 und a + b ≤ 1, da
W 0 (z) + W 0 (y) ≤ W 0 (x) ist, und dieser Term log a + log b nimmt sein Maximum für
a = b = 1/2 an.
Nun beobachten wir noch, dass Fall 1 bei einer SPLAY-Operation nur ein einziges
mal auftritt. Dann folgt mit Hilfe der Teleskopsummenregel2 dass die amortisierten
einer SPLAY(x)-Operation höchstens 1 + 3(r(t) − r(x)) betragen, wobei t die Wurzel
des Baumes vor der Operation ist.
2 Eine
Summe von Differenzen, bei der je zwei benachbarte Glieder sich aufheben sodass nur das
erste und letzte Element übrig bleiben.
35
Wir können nun folgenden Satz zeigen.
Theorem 2.5 Eine Sequenz σ = σ1 · · · σm von Operationen wird auf einem SplayBaum, der dabei maximal Größe n erreicht, in Zeit O((m + n) log n) abgearbeitet.
Beweis. Sei T der Suchbaum vor der ersten Operation. Wir wissen, dass T höchstens
n Knoten hat. Wir setzen für jeden Knoten x sein Gewicht w(x) = 1. Damit folgt,
dass Φ(T ) = O(n log n) ist. Nach Lemma 2.1 gilt, dass die amortisierten Kosten einer
SPLAY-Operation höchstens O(1 + r(t)) = O(log n) betragen, wobei t die Wurzel des
Baumes vor der Operation ist. Da die amortisierten Kosten plus Anfangspotential eine
obere Schranke für die tatsächlichen Kosten sind, folgt der Satz.
2.1.3
Statische Optimalität von Splay-Bäumen
Wir werden nun zeigen, dass Splay-Bäume asymptotisch so gut sind, wie ein beliebiger
statischer Suchbaum (der Suchbaum wird während der Anfragen nicht verändert). Wir
können also auch den statischen Suchbaum nehmen, der optimal für eine feste Folge
von Anfragen ist, und dieser optimale statische Suchbaum wäre asymptotisch nicht
besser als ein Splay-Baum.
Theorem 2.6 Sei S eine Menge von n Elementen und σ eine Sequenz von Zugriffsoperationen auf Elemente aus S. Des weiteren sei TS ein beliebiger statischer Suchbaum
für die Elemente aus S und ` die Anzahl Vergleiche, die benötigt werden, um σ auf TS
abzuarbeiten. Dann wird σ auf einem Splay-Baum in Zeit O(` + n2 ) abgearbeitet.
Beweis. Sei T ein beliebiger Splay-Baum für S und t die Wurzel von T . Sei d die Tiefe
von TS und d(x) die Länge des Pfades von der Wurzel von TS zu x. Wir verwenden nun
für jeden Knoten x aus T die Gewichtsfunktion
w(x) = 3d−d(x) .
Wir zeigen zunächst folgende Behauptung.
Behauptung 2.7 W (t) ≤ 3d+1 .
Beweis. Man kann beobachten, dass das Gewicht der Wurzel t maximal für einen
vollständigen Binärbaum B ist. Damit ergibt sich
d
W (t) =
∑ w(x) = ∑ 3
x∈S
x∈S
d−d(x)
i
1
2
≤ 3d
= 3d+1 .
=3 ∑
3
1
−
2/3
i=0
d
i
≤ ∑ 2 ·3
d−i
i=0
36
d
Aus Lemma 2.1 folgt dann, dass für die amortisierten Kosten von SPLAY(x) gilt
W (t)
3d+1
O(1 + r(t) − r(x)) = O 1 + log2
= O 1 + log2 d−d(x) = O(1 + d(x)) .
W (x)
3
Für das Potential Φ(T ) gilt
Φ(T ) =
∑ r(x) = ∑ log2 W (x) ≤ ∑ log2 3d+1 = ∑ O(d) = O(n · d) = O(n2)
x∈S
x∈S
x∈S
.
x∈S
Da die amortisierten Kosten plus Anfangspotential eine obere Schranke für die
tatsächlichen Kosten sind, folgt der Satz.
37
2.2
Randomisierte Suchbäume
Anhand des randomisierten Quicksort-Algorithmus werden wir uns genauer mit der
Analyse randomisierter Algorithmen beschäftigen. Wir benutzen insbesondere die Linearität des Erwartunswertes3 .
Wir werden die erwartete Laufzeit des randomisirten Quicksort-Algorithmus und die
erwartete Zugriffszeit auf ein Element in randomisierten Suchbäumen analyisieren.
2.2.1
Der randomisierte Quicksort Algorithmus
Im deterministischen Quicksort Algorithmus wird das Element, an dem die jeweils
zu sortierende Menge gespalten wird, nach bestimmten Regeln ausgewählt. Oft wird
beispielsweise einfach das erste Element der (Teil)Menge gewählt. Der randomisierte
Quicksort-Algorithmus unterscheidet sich von der deterministischen Variante durch
die zufällige Wahl des Pivotelements.
R AND QS(S)
1. Wähle y ∈ S zufällig und gleichverteilt
2. S1 = {x ∈ S|x < y}; S2 = {x ∈ S|x > y}
3. if S1 6= 0/ then R AND QS(S1 )
4. Augabe y
5. if S2 6= 0/ then R AND QS(S2 )
Die Wahl des Pivot-Elements y entscheidet nicht darüber, ob der Algorithmus die
korrekte Reihenfolge der Elemente herstellt. Sie beeinflusst aber die Zahl der notwendigen Vergleiche und damit die Laufzeit des Algorithmus.
Ein Worst Case und seine Wahrscheinlichkeit
Wir betrachten den Fall, dass der Quicksort-Algorithmus stets das kleinste Element
einer Menge als Pivot-Element wählt. In diesem Fall wird auf jeder Rekursionsstufe
jedes verbleibende Element mit dem Pivot-Element verglichen, sodass eine maximale
3
Zur Einnerung an die mathematischen Grundlagen siehe auch im Anhang von Kapitel 1
38
Laufzeit zu Stande kommt. Für n Elemente ist die Zahl der Vergleiche:
n−1
∑i=
i=1
n · (n − 1)
= Θ(n2 ) .
2
Die Wahrscheinlichkeit dafür, dass dieser Fall beim randomisierten Quicksort Algorithmus eintritt, beträgt allerdings nur
n
1
∏i
=
i=1
1
.
n!
Damit benötigt die Sortierung in diesem Fall quadratische Zeit. Wird stets der Median
einer Menge gewählt, ist die Laufzeit hingegen nur O(n log n).
Die erwartete Laufzeit des randomisierten Quicksort Algorithmus
Bei einer solchen Spannbreite der Möglichkeiten interessiert uns natürlich, welche
erwartete Laufzeit der randomisierte Quicksort letztendlich erreicht.
Es genügt dazu, festzustellen, wie viele Vergleiche RandQS vornehmen muss. Zwei
Elemente werden höchstens einmal miteinander verglichen, nämlich dann, wenn eins
der beiden Pivot-Element einer Teilmenge ist, die beide enthält. Nach diesem Vergleich
wird das Pivot-Element nicht mehr betrachtet und dementsprechend auch nicht mehr
mit dem zweiten Element verglichen.
Die (Indikator-)Zufallsvariable Xi j bezeichne, ob die Elemente si und s j miteinander
verglichen werden (Xi, j = 1) oder nicht (Xi, j = 0). Die Zahl der Vergleiche läst sich
also beschreiben als:
n−1
n
∑ ∑
Xi, j
i=1 j=i+1
Die erwartete Zahl der Vergleiche und damit die Laufzeit ist dann wegen der Linearität des Erwartungswertes
"
#
n−1 n
n−1 n
E ∑ ∑ Xi, j = ∑ ∑ E Xi, j .
i=1 j=i+1
i=1 j=i+1
Als nächstes definieren wir
pi, j = Pr Xi, j = 1 ,
womit für den Erwartungswert gilt: E Xi, j = 1 · pi, j + 0 · (1 − pi, j ) = pi, j .
Wir wollen also die Wahrscheinlichkeit dafür bestimmen, dass zwei Elemente si und
s j (1 ≤ i < j ≤ n) miteinander verglichen werden.
Lemma 2.8 Die Wahrscheinlichkeit, dass zwei Elemente si und s j (1 ≤ i < j ≤ n)
2
.
miteinander verglichen werden, ist gleich j−i+1
39
Beweis. Sei s∗ das Element, das als erstes als Pivot-Element aus der Menge Si, j =
si , ..., s j , für die gilt s1 ≤ s2 ≤ . . . ≤ sn , gewählt wird.
• Fall 1 s∗ ∈ {si , s j }. Wenn s∗ = si ist, dann werden alle Elemente aus Si, j mit si
verglichen, insbesondere auch s j . Der Fall s∗ = s j ist analog.
• Fall 2 s∗ ∈
/ {si , s j }. Dann werden si und s j mit s∗ verglichen, wobei si als kleinstes Element der Menge Si , j in S1 und s j als größtes Element in S2 einsortiert
wird. Sie werden nun im weiteren Verlauf des Algorithmus nicht miteinander
verglichen.
Nun wissen wir, dass zwei Elemente si und s j nur genau dann miteinander verglichen werden, wenn eines der beiden Elemente als erstes aus Si, j als Pivot-Element
ausgewählt wird.
Da die Pivot-Elemente jeweils zufällig gewählt werden, beträgt die Wahrscheinlichkeit dafür, dass eins der beiden Elemente si und s j aus den j − i + 1 Elementen gewählt
1
.
wird |S1i, j | = j−i+1
2
. Dies brauchen wir nur noch einzusetzen, um die erwartete
Damit folgt: pi, j = j−i+1
Anzahl Vergleiche im randomisierten Quicksort Algorithmus zu bestimmen.
"
#
n−1 n
n−1 n
n−1 n
n−1 n
2
E ∑ ∑ Xi, j = ∑ ∑ E Xi, j = ∑ ∑ pi, j = ∑ ∑
i=1 j=i+1
i=1 j=i+1
i=1 j=i+1
i=1 j=i+1 j − i + 1
Summe berechnen mit Hilfe einiger Indexttransformationen:
n−1 n−i+1
=
∑ ∑
i=1 j=2
n n−i+2
=
∑ ∑
i=2 j=1
n
=
2
j
2
j
i
2
i=2 j=2 j
∑∑
n
= 2 ∑ (Hi − 1)
i=1
Dabei ist Hi = ∑ik=1 1k die i-te harmonische Zahl. Aus ln i ≤ Hi ≤ ln i + 1 folgt
Theorem 2.9 Die erwartete Anzahl von Vergleichen in einer Ausführung des randomisierten Quicksort Algorithmus auf einer n-elementigen Eingabe ist
n
2 ∑ (Hi − 1) = Θ(n log n) .
i=1
Bemerkung 2.10 Jeder vergleichsbasierte Sortieralgorithmus benötigt Ω(n log n)
Laufzeit.
40
2.2.2
Randomisierte Suchbäume
In diesem Kapitel lernen wir randomisierte Suchbäume kennen. Wir werden feststellen, dass sie eine besonders niedrige erwartete Laufzeit für das Suchen, Einfügen und
Löschen von Elementen aufweisen.
Dazu werden wir uns zunächst mit zufällig aufgebauten Suchbäumen beschäftigen
und dann randomisierte Suchbäume untersuchen.
Definition 2.11 Ein Suchbaum ist ein (binärer) Baum, der die Suchbaumeigenschaft
erfüllt, d.h. für den gilt:
Für jeden Knoten v mit Schlüssel s(v) gilt: Jeder Knoten im linken Teilbaum hat einen
Schlüssel ≤ s(v) und jeder Knoten im rechten Teilbaum hat einen Schlüssel > s(v).
Zufällig aufgebaute Suchbäume
Wir wollen zufällig aufgebaute Suchbäume betrachten, bei denen eine Menge S von
Elementen in zufälliger Reihenfolge eingefügt wird. Uns interessiert, wie viele Schritte
dann zum Zugriff auf ein Element nötig sind, also die erwartete Tiefe eines zufällig
aufgebauten Baums. Die Zahl der zum Zugriff nötigen Schritte entspricht der Anzahl
der Vorgänger des gesuchten Elements.
O.B.d.A. sei si das i-kleinste Element der Eingabe s1 , . . . , sn . Außerdem sei π eine
zufällig und gleichverteilt gewählte Permutation von {1, . . . , n}. Die einzelnen Elemente werden in der durch π vorgegebenen Reihenfolge in den Baum eingefügt.
Nun können wir die erwartete Zugriffszeit auf ein festes Element si bestimmen. Dazu
sei Di die Zufallsvariable für die Länge des Weges von si bis zur Wurzel von T , also
die Anzahl der Vorgänger von Knoten si im Baum T .
Wir definieren eine Indikatorzufallsvariable Xi, j für das Ereignis Knoten s j ist
”
Vorgänger von Knoten si in T“. Damit ist also Xi, j = 1, wenn Knoten s j Vorgänger von
Knoten si in T ist und 0 sonst. Dann gilt
Di =
∑
Xi, j
1≤ j≤n
und
"
E [Di ] = E
#
∑
1≤ j≤n
=
∑
Xi, j =
∑
E Xi, j =
1≤ j≤n
∑
Pr Xi, j = 1
1≤ j≤n
Pr s j ist Vorgänger von si
1≤ j≤n
Wir zeigen nun:
Theorem 2.12 Wenn eine Menge S = {s1 , . . . , sn } von n Elementen in zufälliger Reihenfolge in einen anfangs leeren binären Suchbaum eingefügt wird, dann ist die erwartete Tiefe eines festen Knotens s` = E [D` ] ≤ 1 + 2 ln n.
41
Dazu definieren wir einen Treap zum Suchbaum S:
Definition 2.13 Sei {s1 , . . . , sn } eine Menge mit sk < s` für k < `. Jedes Element aus S
hat eine Priorität prio(s` ).
Ein Treap (Tree + Heap) für S ist ein binärer Baum T , für den gilt:
• T ist ein Suchbaum bzgl. S.
• T ist ein Heap bzgl. der Prioritäten, d.h. für jeden Knoten außer der Wurzel ist
die Priorität seiner Vorgänger kleiner als die eigene.
Als nächstes entwickeln wir ein Lemma, dass den Zusammenhang zwischen Prioritäten und Baumstruktur in einem Treap charakterisiert:
Lemma 2.14 Sei S = {s1 , . . . , sn } eine Menge von Elementen mit sk < s` für k < ` und
Prioritäten prio(s` ) und Si, j = {si , . . . , s j } bezeichne eine Teilmenge von S.
Dann ist in Treap T für S das Element s j genau dann Vorgänger von si , wenn gilt:
min prio(si ), prio(si+1 ), . . . , prio(s j ) falls i < j
prio(s j ) =
min prio(s j ), prio(s j+1 ), . . . , prio(si ) falls i > j
Damit ist s j genau dann Vorgänger von si , wenn s j die kleinste Priorität aller Elemente
aus Si, j hat.
Beweis. Beweis in der Übung.
In einem Treap, dessen Prioritäten durch zufällige Permutationen gegeben sind, gilt:
Lemma 2.15 Sei π zufällig und gleichverteilt gewählt aus der Gruppe Σn der Permutationen von n Elementen und sei prio(s` ) = π(`). Dann gilt:
Pr s j ist Vorgänger von si =
1
.
| j − i| + 1
Beweis. Da π zufällig und gleichverteilt aus Σn gewählt wird, nimmt π(`) jeden Wert
aus {1, . . . , n} mit derselben Wahrscheinlichkeit an. Damit ist die Wahrscheinlichkeit,
dass für festes i die Priorität π(i) die kleinste Priorität der Elemente aus Si, j ist, genau
1
1
|Si, j | = | j−i|+1 .
Damit gilt für Theorem 2.12:
42
Beweis. :
∑
E Xi, j =
1≤ j≤n
1≤ j≤n
∑
Pr s j ist Vorgänger von si
E [Di ] =
=
∑
Pr Xi, j = 1
1≤ j≤n
1
1 1
1
1
+···+ +1+ + +···+
i
2
2 3
n−i+1
= Hi + Hn+1−i − 1
≤ 1 + 2 ln n
=
Randomisierte Suchbäume
Bisher haben wir gesehen, dass jedes Element in einem Suchbaum erwartete Tiefe
O(log n) hat, wenn die Elemente in zufälliger Reihenfolge in den Suchbaum eingefügt
worden sind. Wir wollen diese Eigenschaft ausnutzen und effiziente Suchbäume konstruieren, die für beliebige Einfügereihenfolgen eine erwartete Tiefe in O(log n) garantieren. Diese Suchbäume bezeichnen wir dann auch als randomisierte Suchbäume,
weil die Elemente so angeordnet sein sollen, als ob sie in zufälliger Reihenfolge einfügt
worden wären.
Idee Wir würfeln für jedes Element beim Einfügen eine zufällige Priorität aus dem
Intervall [0, 1]. Der Baum wird so aufgebaut, als wären die Elemente in der Reihenfolge
dieser zugeordneten Prioritäten eingefügt worden.
Definition 2.16 Ein randomisierter Suchbaum für {s1 , . . . , sn } ist ein Treap, bei dem
für jedes si die Priorität zufällig und gleichverteilt aus [0, 1] gewählt wurde.
Wir können nun ähnlich wie bei zufällig aufgebauten Suchbäumen folgendes Lemma
zeigen:
Lemma 2.17 Sei S = {s1 , . . . , sn } eine Menge von Elementen und prio(s1 ), . . . , prio(sn )
seien unabhängige und gleichverteile Zufallsvariablen aus [0, 1]. Dann gilt
Pr prio(s j ) = min prio(Si, j ) =
1
.
| j − i| + 1
Beweis. Die Wahrscheinlichkeit, dass zwei Prioritäten identisch sind, ist 0. Da jede
Priorität zufällig, gleichverteilt und unabhängig aus derselben Menge gewählt wurde,
ist damit aus Symmetriegründen jedes Element mit derselben Wahrscheinlichkeit das
Element mit der kleinsten Priorität. Daher ist die Wahrscheinlichkeit, das ein Element
das kleinste einer k-elementigen Menge ist, genau 1k und das Lemma folgt.
43
Es folgt
Theorem 2.18 Sei S = {s1 , . . . , sn } eine Menge von Elementen, die in einem randomisierten Suchbaum gespeichert sind. Dann ist die erwartete Tiefe des Knotens für
si
Hi + Hn+1−i − 1 ≤ 1 + 2 ln n .
Einfügen in randomisierten Suchbäumen
Wir müssen nun natürlich noch zeigen, dass man effizient Elemente in einen randomisierten Suchbaum einfügen kann.
Dabei funktioniert das Einfügen wie in einem normalen Suchbaum. Wir merken uns
zusätzlich beim Einfügen den Suchpfad (dies geschieht implizit durch Rekursion) und
stellen nach dem Einfügen durch Rotationen entlang des Suchpfads die Heapeigenschaft bzgl. der Prioritäten wieder her.
Theorem 2.19 Löschen kann ebenfalls in O(log n) erwarteter Zeit implementiert werden.
Beweis. Übung.
Theorem 2.20 In einem randomisierten Suchbaum für n Elemente können die Operationen Suchen, Einfügen und Löschen in O(log n) erwarteter Zeit durchgeführt werden.
2.3
Weiterführende Literatur
- The Design and Analysis of Algorithms - [Koz92]
44
1
2
F
A
F
1
7
K
C
8
H
3
10
J
A
M
1
7
K
C
4
8
H
10
J
12
I
3
3
M
4
M
4
12
2
4
F
A
F
1
7
K
C
8
H
3
10
I
A
M
7
K
C
4
1
8
H
2
J
12
I
2
I
2
10
J
3
12
5
F
A
1
7
C
8
H
10
J
K
3
12
M
4
Abbildung 2.13: Ein Treap, in dem die Elemente mit den Schlüsseln A,C, F, H, J, K, M geordnet nach dem Alphabet eingefügt wurden. Dann wird das Element I in den Treap eingefügt.
45
Kapitel 3
Datenmanagement in Netzwerken
Der Kommunikationsoverhead für die Bereitstellung von Datenobjekten, also die
zusätzliche Laufzeit durch den Transport der Pakete, die von mehreren Knoten in
einem Netzwerk bearbeitet werden können, dominiert häufig die Laufzeit von Netzwerkanwendungen. Bei solchen Datenobjekten kann es sich zum Beispiel um Dateien
in einem Local-Area-Network (LAN), globale Variablen auf einem Parallelrechner
oder auch virtuelle Seiten in einem verteilten Speichersystem handeln.
In der Standardimplementierung solcher Systeme haben Datenobjekte häufig ein so
genanntes Home, also einen Rechner bzw. Prozessor, der der Ansprechpartner für dieses Objekt ist. In einer naiven Realisierung dieses Konzeptes wird jeder Zugriff auf
ein Datum an sein Home geschickt, das dann bei einem Schreibzugriff das Objekt
entsprechend modifiziert und bei einem Lesezugriff das gesamte Objekt bzw. einen
angefragten Ausschnitt der Daten zurückliefert.
Unter dem Konzept des Cachings versteht man eine raffiniertere Variante, die es erlaubt, Kopien des Objektes zu erzeugen, die im Netzwerk verteilt werden. Falls ein
Prozessor häufiger auf dasselbe Datenobjekt zugreifen möchte, ist es vielleicht sinnvoll, wenn dieser Prozessor eine lokale Kopie erhält, sodass Anfragen von diesem Prozessor nicht mehr zum Home gesendet werden müssen. Falls jedoch jetzt ein anderer
Prozessor dieses Objekt verändern möchte, muss diese und jede andere Kopie entweder invalidiert oder aktualisiert werden. Es stellen sich die Fragen, wann wir Kopien
erzeugen und wann wir sie wieder löschen sollen.
Grundsätzlich scheint es sogar möglich und sinnvoll zu sein, das Home eines Prozessors zu verschieben, oder sogar das Home-Konzept ganz aufzugeben und verschiedene
gleichrangige Kopien im Netzwerk wandern zu lassen. In einem derartig dynamischen
System stellt sich natürlich auch die Frage, wie die anfragenden Knoten die im Netzwerk verteilten Kopien lokalisieren können, ohne dazu das gesamte Netzwerk abzusuchen.
46
3.1
Definition des File-Allocation-Problems (FAP)
Das Netzwerk wird durch einen ungerichteten Graphen G = (V, E) mit nicht-negativen
Kantenlängen aus R beschrieben. Wir betrachten nur ein Datenobjekt x auf das von
allen Prozessoren im Netzwerk lesend und schreibend zugegriffen werden kann. Es
dürfen beliebig viele Kopien von x erzeugt werden. Die Teilmenge der Knoten, die zu
einem Zeitpunkt t ≥ 0 eine Kopie von x besitzen wird als Residenzmenge Rt ⊆ V, Rt 6= 0/
bezeichnet. Zum Zeitpunkt 0 gilt R0 = {v} für einen beliebigen Knoten v ∈ V . Wir
vernachlässigen zunächst das Problem, wie die Kopien im Netzwerk lokalisiert werden
können und setzen globales Wissen über die Residenzmenge voraus, d.h. zu jedem
Zeitpunkt t kennt jeder Knoten die Menge Rt .
Auf dem Netzwerk muss eine Sequenz von Lese- und Schreibanfragen σ = σ1 · · · σT ,
mit σt ∈ {r(v), w(v)|v ∈ V }, abgearbeitet werden. Dabei steht σt = r(v) für eine Leseanfrage von Prozessor v und σt = w(v) für eine Schreibanfrage von v. Es müssen
die folgenden Spielregeln“ eingehalten werden: Nachdem σt präsentiert ist, führt
”
der Algorithmus die Anfrage durch. Wir kümmern uns nicht um die Details der
Durchführung, sondern definieren stattdessen abstrakte Servicekosten für die einzelnen Zugriffe.
• Falls σt = r(v) ist, dann entsprechen die Servicekosten der Distanz von v zum
nächsten Knoten in Rt−1 , da eine Kopie von diesem weitergeleitet werden muss.
• Falls σt = w(v) ist, dann entsprechen die Servicekosten den Kosten des minimalen Steinerbaumes, der v und Rt−1 aufspannt, also der minimalen Summe der
Kantenlängen, die benötigt wird, um v durch einen Baum mit allen Knoten in
Rt−1 zu verbinden, da jede dieser Kopien aktualisiert werden muss.
Nachdem die Anfrage σt bedient wurde, kann die Residenzmenge angepasst werden,
also Rt−1 in Rt überführt werden. Dazu dürfen neue Kopien erzeugt oder auch vorhandene Kopien verschoben und gelöscht werden. Es muss jedoch immer mindestens eine
Kopie im Netzwerk erhalten bleiben. Das Erzeugen neuer Kopien sowie das Löschen
verursacht keine Kosten. Eine neuerzeugte Kopie kann dann entlang der Kanten vom
erzeugenden Knoten zum Ziel verschoben werden. Das Verschieben einer Kopie entlang einer Kante der Länge ` verursacht dabei Migrationskosten in Höhe von `.
3.2
FAP auf Bäumen
Sei hier zunächst der betrachtete Graph ein Baum T = (V, E). Wir präsentieren einen
einfachen 3-kompetitiven Online-Algorithmus. Dieser Algorithmus hat die folgende
Invariante: Zu jedem Zeitpunkt t ≥ 0 ist der durch die Residenzmenge induzierte Teilgraph zusammenhängend.
Für v ∈ V und t ≥ 0 bezeichne Pt (v) die Knoten auf dem kürzesten Weg, der vom
Knoten v zur Residenzmenge Rt führt, inklusive des Quell- und Zielknotens dieses
47
Weges. Nach der Durchführung der Anfrage σt verändert der Algorithmus die Residenzmenge wie folgt.
• Falls σt = r(v) ist, dann Rt := Rt−1 ∪ Pt−1 (v).
• Falls σt = w(v) ist, dann Rt := Pt−1 (v).
Im Falle einer Leseanfrage durch v erzeugt der Online-Algorithmus also neue Kopien
auf dem Weg Pt−1 (v), und im Falle einer Schreibanfrage von v löscht er die Kopien in
Rt−1 und erzeugt neue Kopien auf Pt−1 (v). Beachte, falls v ∈ Rt−1 ist, so gibt es nach
einer Schreibanfrage von v nur noch eine Kopie, nämlich die Kopie auf dem Knoten v.
Theorem 3.1 Der Online-Algorithmus für FAP auf Bäumen ist 3-kompetitive.
Beweis. Betrachte eine beliebige Kante e = (a, b). O.B.d.A. hat die Kante die Länge
1. Die Entfernung von e aus T würde den Graphen in zwei Teilbäume Ta und Tb zerlegen, die jeweils die Knoten a bzw. b enthalten. Wir unterscheiden drei verschiedene
Konfigurationen.
[A] Nur Ta enthält Kopien von x.
[B] Nur Tb enthält Kopien von x.
[AB] Beide Teilbäume enthalten Kopien.
Beachte, dass in der Konfiguration [AB] insbesondere garantiert ist, dass beide Knoten
a und b jeweils eine Kopie haben müssen, weil ansonsten die Residenzmenge nicht
zusammenhängend wäre. Sei ct ∈ {[A], [B], [AB]} die Konfiguration zum Zeitpunkt t.
Der Schritt von ct−1 nach ct wird als Konfigurationsübergang bezeichnet.
Beobachtung 3.2 Der Online-Algorithmus geht niemals in einem Schritt von der Konfiguration [A] direkt in die Konfiguration [B] über und umgekehrt. Es gibt nur die
Übergänge [A] → [AB], [B] → [AB], [AB] → [A] und [AB] → [B].
Damit können wir die Konfigurationssequenz in disjunkte Phasen der Form [A]+ [AB]+
bzw. [B]+ [AB]+ einteilen. Wir betrachten nun eine derartige Phase und vergleichen die
Kosten des Online-Algorithmus mit den Kosten eines beliebigen Offline-Algorithmus.
• Zunächst zeigen wir, dass der Online-Algorithmus auf Kante e pro Phase genau
Kosten drei hat. O.B.d.A. betrachte eine Phase der Form [A]+ [AB]+ . Die Beschreibung der in solch einer Phase entstehenden Online-Kosten in der Tabelle
3.1 bestätigt unsere Behauptung.
• Als nächstes zeigen wir, dass jeder Offline-Algorithmus mindestens Kosten eins
pro Phase hat. Zum Zwecke des Widerspruchs nehmen wir an, es gibt eine Strategie mit Kosten null. Dann erfordert die Schreibanfrage (*) aus Ta , dass zu diesem
Zeitpunkt keine Kopie in Tb enthalten ist, sonst wären die Kosten mindestens eins.
Außerdem kann keine Kopie migriert werden. Also ist auch zum Zeitpunkt der
Lese-/Schreibanfrage (**) aus Tb keine Kopie in Tb enthalten. Damit verursacht
dieser Zugriff jedoch mindestens Kosten eins.
48
vorherige Konf.
[AB]
[A]
[A]
[AB]
Konf.
[A]
[A]
[AB]
[AB]
Art des Zugriffs
Schreibanfrage aus Ta (*)
Lese-/Schreibanfrage aus Ta
Lese-/Schreibanfrage aus Tb (**)
Leseanfrage aus Ta oder Tb
Online-Kosten
1
0
2
0
Abbildung 3.1: Online-Kosten auf einer Kante in einer Phase der Form [A]+ [AB]+ .
Also hat jeder Offline-Algorithmus mindestens Kosten eins pro Phase, während
der Online-Algorithmus nur Kosten drei hat. Somit ist der Online-Algorithmus 3kompetitive.
Verteilte Ausführung. Bisher sind wir von globalem Wissen ausgegangen. Wir haben angenommen, dass alle Knoten die Konfiguration des Netzwerks kennen. Jetzt
beziehen wir eine verteilte Ausführung in unser Modell mit ein. Wir gehen davon aus,
dass die einzelnen Knoten im Netzwerk nur diejenigen Zugriffe sehen, in die sie involviert sind. Genauer gesagt, ein Knoten sieht einen Lesezugriff nur dann, wenn er auf
dem gewählten Weg zur Zusammenhangskomponente liegt. Analog wird ein Schreibzugriff nur von denjenigen Knoten wahrgenommen, die im für die Aktualisierung oder
Invalidierung der Kopien verwendeten Baum enthalten sind. Auch Migrationen werden nur von Knoten, die auf dem Migrationspfad liegen, beobachtet. Um Informationen über eine Veränderung der Residenzmenge auch an andere Knoten im Netzwerk zu
geben, müssen Informationsnachrichten versendet werden. Im folgenden zeigen wir,
dass Informationsnachrichten für die verteilte Ausführung nicht benötigt werden.
Theorem 3.3 Es gibt einen verteilten 3-kompetitiven Online-Algorithmus für FAP auf
Bäumen.
Beweis. Wir verwenden eine verteilte Variante des Online-Algorithmuns für FAP auf
Bäumen. Wir werden zeigen, wie das so genannte Data-Tracking, d.h. die Lokalisierung der Residenzmenge, auch ohne globales Wissen realisiert werden kann.
Wir erklären einen beliebigen Knoten zur Wurzel des Baumes, z.B. den Knoten der
die initiale Kopie des Datenobjektes hält.
Der Algorithmus hält die folgende Invariante aufrecht: Zu jedem diskreten Zeitpunkt
gibt es eine Kette von Zeigern auf dem Weg von der Wurzel zur Residenzmenge, d.h.
jeder Knoten auf dem Weg von der Wurzel zur Residenzmenge kennt seinen Nachfolger auf diesem Weg. Somit kann jede Lese-/Schreibanfrage auf dem kürzesten Weg zur
Residenzmenge gelangen, indem die entsprechende Nachricht zunächst in Richtung
Wurzel des Baumes läuft und dann den Zeigern zur Residenzmenge folgt. Beachte,
dass diese Zeiger im Falle einer Migration ohne weitere Kommunikation aktualisiert
werden können, da die betroffenen Knoten auf dem Migrationspfad liegen und somit
die Migration beobachten können.
49
Für Schreibzugriffe muss nicht nur ein sondern alle Knoten der Residenzmenge lokalisiert werden. Dazu speichern die Knoten in der Residenzmenge jeweils ab, welche
Nachbarn ebenfalls zur Residenzmenge gehören.
50
3.3
Deterministische untere Schranke für FAP
Die folgende untere Schranke zeigt, dass der obige Online-Algorithmus für FAP auf
Bäumen optimal ist, denn selbst auf einer einzelnen Kante kann man keinen besseren
Faktor als drei erreichen. Dazu konstruieren wir drei Hilfsalgorithmen, deren kostenimmer denen eines beliebigen ALG entsprechen, aber direkt zu berechnen sind.
Theorem 3.4 Betrachte FAP auf einer Kante (a, b) der Länge eins. Jeder deterministische Online-Algorithmus ALG hat eine Kompetitive-Ratio von mindestens drei.
Beweis. Die jeweils zuletzt erzeugte Kopie von ALG bezeichnen wir als neueste Kopie.
Wir betrachten die folgenden drei Offline-Strategien.
• Strategie A hält immer eine Kopie auf a.
• Strategie B hält immer eine Kopie auf b.
• Strategie C hält immer eine Kopie auf demjenigen Knoten, auf dem sich nicht die
neueste Kopie von ALG befindet.
Ein grausamer Gegenspieler konstruiert wie beim Paging die Anfragesequenz σ.
• Wenn ALG auf einem Knoten x ∈ {a, b} keine Kopie hat, dann folgt als nächstes
eine Leseanfrage r(x).
• Wenn ALG auf beiden Knoten a und b Kopien hat, dann folgt als nächstes eine
Schreibanfrage w(x), wobei x derjenige Knoten ist, auf dem sich nicht die neuste
Kopie von ALG befindet.
Die Offline-Strategien A und B haben keine Migrationskosten. Die Migrationskosten
der Offline-Strategie C entsprechen genau den Migrationskosten von ALG. Also haben
die drei Offline-Strategien zusammen dieselben Migrationskosten wie ALG. Bei den
Servicekosten ist die Situation ähnlich. ALG hat in jedem Schritt Servicekosten eins.
Dasselbe gilt für die drei Offline-Strategien zusammen. Also gilt
ALG(σ) = A(σ) + B(σ) + C(σ) ≥ 3 · OPT(σ) .
51
3.4
FAP auf allgemeinen Graphen
Auf allgemeinen Graphen ist ein dynamisches Datenmanagement wesentlich komplexer als auf Baumnetzwerken, da die Wege zwischen Knoten nicht mehr eindeutig sind,
und somit auch die Wahl der Routingwege in das Problem einbezogen werden muss.
Dieser Aspekt erschwert das Datenmanagement in fast jeder Hinsicht, angefangen bei
der Platzierung der Kopien bis hin zum Data-Tracking.
Wir lösen dieses Problem indem wir die zuvor beschriebenen Baumalgorithmen auf
anderen Netzwerken simulieren. Dazu werden wir eine Methode vorstellen, allgemeine Metriken durch so genannte Baummetriken zu approximieren.
Diese Methode kann nicht nur auf FAP sondern auch auf zahlreiche andere Optimierungsprobleme angewendet werden. Die Voraussetzung ist, dass sich die Gesamtkosten
einer Lösung als Linearkombination der Kosten einzelner Kanten beschreiben lässt.
3.4.1
Deterministische Approximation von Metriken
Wie auch bei vielen anderen Problemen, basiert das Kostenmodell für FAP auf den
Distanzen zwischen Knoten in einem Graphen G = (V, E) mit nicht-negativen Kantenlängen. Die konkrete Graphtopologie ist dabei unwesentlich. Um die Kosten zu
ermitteln, wird eigentlich nur die durch G erzeugte Metrik M benötigt. M beschreibt
für jedes Knotenpaar u, v ∈ V die Distanz dM (u, v) zwischen u und v.
a b c

a − 1 2
b 1 − 3 
c 2 3 −

a
1
b
2
3
c
a
1
b
2
c
Abbildung 3.2: Zwei Graphen, die durch die selbe Metrik beschrieben werden können.
Allgemein erfüllt eine Metrik M über einer Knotenmenge V die folgenden Bedingungen:
• Für alle u, v ∈ V gilt: dM (u, v) ≥ 0 (Nicht-Negativität)
• Für alle u, v ∈ V gilt: dM (u, v) = dM (v, u) (Symmetrie)
• Für alle u, v, w ∈ V gilt: dM (u, w) ≤ dM (u, v) + dM (v, w) (Dreiecksungleichung)
Im Folgenden definieren wir, was es bedeutet, eine Metrik durch eine andere Metrik
zu approximieren.
52
Eine Metrik N über V dominiert eine Metrik M über V , falls für jedes u, v ∈ V gilt
dN (u, v) ≥ dM (u, v).
Eine Metrik N über V α-approximiert eine Metrik M über V , falls sie M dominiert
und für alle u, v ∈ V gilt dN (u, v) ≤ αdM (u, v).
Eine Metrik N über V ist eine Baummetrik, falls es einen Baum T = (V, E) gibt,
der die Metrik N erzeugt. Wir möchten allgemeine Metriken durch Baummetriken
approximieren. Die folgende untere Schranke zeigt, dass dies deterministisch nicht
sinnvoll funktionieren kann.
Theorem 3.5 Für jedes n ∈ N gibt es eine Metrik M über n Knoten, sodass für jede
Baummetrik N über n Knoten gilt, falls M durch N α-approximiert wird, gilt α = Ω(n).
Beweis. Sei G = (V, E) der Kreis über n Knoten. Insbesondere sei V = {0, . . . , n − 1}
und E = {(i, j)|i = j + 1 mod n}. Alle Kanten in G haben Länge 1.
3
2
1
0
4
5
11
6
10
7
8
9
Abbildung 3.3: G = (V, E)
G erzeuge die Metrik M. T = (V, ET ) bezeichne den Baum, der N erzeugt. Zur Vereinfachung der Notation nehmen wir an, dass n gerade ist, und dass α < 4n eine ganze
Zahl ist.
Widerspruchsannahme: N ist eine α-Approximation von M.
1. Zuerst zeigen wir, dass jede Kante in ET höchstens Länge α hat. Wenn es eine
Kante e = (a, b) ∈ ET mit Länge > α gäbe, gibt es zwei Teilbäume Ta und Tb ,
sodass für jedes Knotenpaar (u, v) mit u aus Ta und v aus Tb gilt dN (u, v) > α.
Da N die Metrik M α-approximiert, können Nachbarn im Kreis aber höchstens
Abstand α im Baum haben. Also sind entweder alle Knoten aus V im Teilbaum
Ta oder alle im Teilbaum Tb enthalten, auch die beiden Knoten a und b, die durch
die ursprüngliche Kante getrennt wurden. Also hat jede Kante in ET höchstens
Länge α.
2. Jetzt definieren wir zwei Knotenmengen A = {0, . . . α − 1} und B = { 2n , . . . n2 +
α − 1}. Dabei färben wir die Knoten im Rest des Graphs V \ (A ∪ B) mit zwei
Farben: Die Knoten in {α, . . . 2n − 1} werden blau gefärbt und die Knoten in { n2 +
α, . . . n − 1} werden rot gefärbt. Beachte, zwischen je einem blauen und einem
53
3
2
1 A
0
4
u 5
11
v 6
B 7
10
8
9
Abbildung 3.4: Beispiel für n = 4 und α < 4n .
roten Knoten ist die Distanz im Kreis größer als n4 > α. Also kann es keine Kante
(u, v) ∈ ET zwischen einem blauen Knoten u und einem roten Knoten v geben,
die im Kreis ja mehr als 4n voneinander entfernt sind, weil sonst dM (u, v) > α ≥
dN (u, v) gelten würde, was im Widerspruch zur Dominanz von N über M stünde.
Wir fassen zusammen: Zwischen roten und blauen Knoten gibt es keine Kante in
ET .
3. Sei a ∈ A und b ∈ B. Im Kreis haben a und b mindestens die Distanz dM (a, b) ≥
n
n
2 − α ≥ 4 . Aufgrund der Dominanz von N über M folgt, dass die Entfernung im
Baum nicht geringer sein darf, also dN (a, b) ≥ dM (a, b) ≥ 2n − α ≥ n4 . (3)
4. Sei a0 6= a ∈ A. b kann nicht auf dem Pfad liegen, der a und a0 in T verbindet,
denn sonst gäbe es zwei Knoten in A, die im Kreis benachbart sind (a und a’ oder
zwischen ihnen liegende Knoten), aber im Baum mindestens Distanz n4 hätten,
die zwischen einem Knoten a und b liegt. Die α-Approximation erlaubt jedoch
höchstens eine Distanz von α < 4n für im Kreis benachbarte Knoten. Zwischen
zwei Knoten aus A (oder B) liegt also kein Knoten aus B (oder A).
5. Mit dieser Eigenschaft können wir nun die Teilbäume TA und TB definieren: TA
bzw. TB sind die vollständigen Teilbäume, die jeweils eine Wurzel aus A bzw. B
haben und keinen Knoten aus B bzw. A enthalten.
Wenn wir TA und TB aus T entfernen, so bleibt ein zusammenhängender Restbaum R über. Per Definition besteht R nur aus gefärbten Knoten. Tatsächlich
besteht R entweder nur aus blauen oder nur aus roten Knoten, denn sonst würde
es in R ein benachbartes Paar Knoten mit unterschiedlichen Farben geben, was
(2) widerspricht. O.B.d.A. können wir also annehmen das R nur aus roten Knoten
besteht.
6. Die blauen Knoten sind entweder alle in TA oder in TB enthalten, denn sonst gäbe
es zwei blaue im Kreis benachbarte Knoten, die im Baum mindestens Distanz n4
hätten, die laut (3) zwischen zwei Knoten aus a und b liegt.
Die α-Approximation erlaubt jedoch höchstens eine Distanz von α < n4 für im
Kreis benachbarte Knoten. O.B.d.A. können wir also annehmen: Alle blauen
Knoten sind in TA enthalten.
54
7. Jetzt betrachten wir das Knotenpaar u = n2 − 1 und v = n2 . Im Baum finden wir u
in TA , da er zu den blauen Knoten gehört, und v in TB , da er zur Menge B gehört.
Es folgt dN (u, v) ≥ 4n > α. Aus der Nachbarschaft auf dem Kreis folgt jedoch
dM (u, v) = 1.
Also erhalten wir einen Widerspruch zur α-Approximation von M durch N.
3.4.2
Probabilistische Approximation von Metriken
Eine probabilistische α-Approximation einer Metrik M über V durch Baummetriken
ist definiert durch eine Menge von Baummetriken S über V mit einer assoziierten
Wahrscheinlichkeitsverteilung P : S → [0, 1], die die folgenden Bedingungen erfüllt:
• Jede Baummetrik N ∈ S , dominiert die Metrik M.
• Für ein zufällig gemäß P gewähltes N ∈ S gilt: E [dN (u, v)] ≤ α · dM (u, v) für alle
u, v ∈ V .
Bartal hat gezeigt, dass es für jede Metrik M über eine Knotenmenge V eine probabilistische O(log |V | log log |V |)-Approximation durch Baummetriken gibt. Das folgende
leicht verbesserte Ergebnis geht zurück auf Fakcharoenphol, Rao und Talwar.
Theorem 3.6 Für jede Metrik M über eine Knotenmenge V gibt es eine probabilistische O(log |V |)-Approximation durch Baummetriken.
Dieses Ergebnis ist optimal, denn es gibt eine Metrik M für die es nachweisbar keine probabilistische o(log |V |)-Approximation durch Baummetriken gibt. Wir werden
diesen Satz nicht in seiner Allgemeinheit beweisen, sondern uns die grundlegende Beweisidee anhand eines relativ einfachen Beispiels klarmachen. Als Beispiel betrachten
wir die Metrik M, die durch den zwei-dimensionalen (n × n)-Torus G = (V, E), mit
V = {0, . . . n − 1}2 ,
E = {{(x, y), ((x + 1) mod n, y)}, {(x, y), (x, (y + 1) mod n)}|(x, y) ∈ V }
und uniformen Kantenlängen, erzeugt wird.
Theorem 3.7 Sei n = 2d . Für die (n × n)-Torusmetrik M über V = {0, . . . n − 1}2 gibt
es eine probabilistische 8d-Approximation durch Baummetriken.
Beweis. Durch eine hierarchische Partitionierung des Torus definieren wir zunächst
einen Dekompositionsbaum. Dazu teilen wir den Torus in vier disjunkte ( 2n × 2n )Teilgitter, die wiederum rekursiv in vier disjunkte, quadratische Teilgitter aufgeteilt
werden, bis wir einzelne Knoten erreichen.
Mit dieser Partitionierung ist ein 4-ärer Dekompositionsbaum der Tiefe d verbunden,
in dem die Wurzel den gesamten Torus und jeder Knoten auf Ebene i ∈ {1, . . . d} dieses
Baumes jeweils ein Teilgitter mit Seitenlänge 2ni repräsentiert.
55
Abbildung 3.5: Ein 4x4-Torus
Abbildung 3.6: Teilung des 4x4-Torus
7
1
2
9
7
2
3
4
5
6
7
8
9
10
14
11
12
Abbildung 3.7: Beispiel-Baum zum 4x4-Torus
56
13
14
15
16
In jedem dieser Teilnetzwerke wählen wir jetzt iterativ einen Leiter, also einen benannten Knoten, der zur nächsten Ebene verbindet. Wir beginnen mit den Teilgittern auf Ebene d des Dekompositionsbaumes. Nachdem wir die Leiter auf Ebene
i ∈ {1, . . . d} bestimmt haben, widmen wir uns der Ebene i − 1. Als Leiter eines Teilgitters S auf Ebene i − 1 wählen wir einen beliebigen Knoten aus der Menge der Leiter
der Teilgitter auf Ebene i, in die S partitioniert wird. Die Distanz dieses Leiters zu
einem beliebigen Knoten in S ist durch f rac2n2i−1 beschränkt.
Wir beschriften nun die Knoten des Dekompositionsbaumes. Jeder Baumknoten
erhält das Label des Leiters im jeweiligen Teilgitter. Beachte, dass einzelne Label
im Baum mehrfach vorkommen können, während sie im Torus eindeutig sind. Als
nächstes weisen wir den Baumkanten Distanzwerte zu. Eine Kante zwischen zwei
Baumknoten mit Label u und v erhält die Distanz der gleichnamigen Knoten im Torusnetzwerk. Kanten, deren inzidente Knoten dasselbe Label tragen, erhalten dabei
den Distanzwert 0.
Wenn wir nun Baumknoten mit gleichem Label miteinander identifizieren, so erhalten wir eine Baummetrik N über V = {0, . . . n − 1}2 , die die Torusmetrik M dominiert,
weil für jede Kante im Baum ein Weg gleicher Länge im Torus existiert, so dass gilt
dM (u, v) ≤ dN (u, v) für alle u, v ∈ V . Beachte, dass diese Aussage gilt, weil wir die
Leiter so gewählt haben, dass der Graph, der jeweils durch Baumknoten mit gleichem
Label induziert wird, zusammenhängend ist.
Die oben beschriebene Dekomposition ist nicht eindeutig, da wir die Koordinaten
der Partionierung auf der obersten Rekursionsebene nicht festgelegt haben. Tatsächlich
gibt es n2 Möglichkeiten für die Partitionierung auf der obersten Rekursionsebene. Sobald dieser erste Partionierungsschritt jedoch festgelegt ist, sind auch die nachrangigen
Partionierungen eindeutig bestimmt. Tatsächlich erhalten wir also eine Familie von n2
Dekompositionsbäumen mit verschiedenen Beschriftungen von denen jeder eine unterschiedliche Baummetrik über V erzeugt, die die Torusmetrik M dominiert. Um eine
probabilistische Approximation von M zu erhalten, definieren wir jetzt, dass die Menge
S eben aus diesen n2 verschiedenen Baummetriken besteht. Als Wahrscheinlichkeitsverteilung über S wählen wir die uniforme Verteilung.
Wir müssen nun die erwartete Distanz zwischen zwei beliebigen Knoten aus V
bezüglich einer zufällig aus S gewählten Metrik N abschätzen und beweisen, dass die
erwartete Distanz in N höchsten 8d mal so groß ist wie die Distanz in der Torusmetrik
M. Seien u = (u1 , u2 ) und v = (v1 , v2 ) beliebig gewählte Knoten aus V . Bezeichne δ1
die Distanz zwischen diesen beiden Knoten bezüglich der ersten Koordinate (Zeilen)
im Torus und δ2 die Distanz bezüglich der zweiten Koordinate (Spalten). Um eine obere Schranke für dN (u, v) zu erhalten, ist es jetzt sinnvoll sich den Dekompositionsbaum
wieder als vollständigen 4-ären Baum der Tiefe d vorzustellen. Wir identifizieren u
und v mit den Blättern, die das entsprechende Label tragen.
Die Wahrscheinlichkeit, dass u und v durch die horizontale Partitionierung des Torus
auf der obersten Rekursionsebene getrennt werden, ist höchstens delta2 1 /n , da auf dieser Ebene zwei horizontale Schnitte vorgenommen werden, und jeder dieser Schnitte
57
eine der δ1 Kantenschichten, die zwischen den Zeilen von u und v liegen, mit Wahrscheinlichkeit δn1 durchtrennt. Für die vertikale Partitionierung ist die entsprechende Wahrscheinlichkeit höchstens 2δn2 . Bezogen auf den Dekompositionsbaum schließen wir, dass der kürzeste Weg zwischen u und v die Wurzel mit Wahrscheinlichkeit
höchstens f rac2(δ1 + δ2 )n enthält. Allgemein gilt, die Wahrscheinlichkeit, dass der
kürzeste Weg zwischen den beiden Knoten u und v einen Knoten von Ebene i des Dei+1
kompositionsbaumes enthält, ist höchstens 2 ·(δn1 +δ2 ) , da 2i+1 horizontale und 2i+1
vertikale Schnitte vorgenommen werden, die zur Aufteilung von u und v in verschiedene Teilbäume unterhalb der Ebene i führen.
Daraus berechnen wir jetzt welche Baumkanten mit welcher Wahrscheinlichkeit überschritten werden. Wir definieren, dass die Baumkanten auf Schicht i für
i ∈ {0, . . . d − 1} zwischen den Knoten der Ebene i und den Knoten der Ebene i + 1
verlaufen.
• Mit Wahrscheinlichkeit höchstens 2i+1 · (δ1 + δ2 )/n führt der kürzeste Weg von
u nach v über Kantenschicht i.
• Von jeder Kantenschicht werden maximal zwei Kanten benutzt.
• Die Kanten aus Schicht i haben Länge höchsten 2n/2i .
Daraus errechnet sich
E [dN (u, v)] =
d−1 i+1
2 · (δ
∑
i=0
3.4.3
1 + δ2 )
n
·2·
2n
= 8d · (δ1 + δ2 ) = 8d · dM (u, v) .
2i
Randomisierter Online-Algorithmus
Aus der obigen Approximation von allgemeinen Metriken durch Baummetriken konstruieren wir einen randomisierten Algorithmus für FAP auf allgemeinen Graphen. Der
randomisierte Online-Algorithmus für FAP auf einem Graphen G = (V, E) arbeitet wie
folgt. Sei M die durch G erzeugte Metrik. In einem Preprocessing wird die für eine αApproximation von M benötigte Menge von Baummetriken S sowie die zugehörige
Wahrscheinlichkeitsverteilung P berechnet. Eine zufällige Baummetrik N wird aus S
gemäß P gewählt und ein Baum T = (V, ET ) wird konstruiert, der diese Metrik erzeugt. Dann wird der in Satz 3.3 beschriebenen 3-kompetitiven Baumalgorithmus A
für T simuliert.
Lemma 3.8 Der obige Algorithmus ist 3α-kompetitive.
Beweis. Fixiere eine Anfragesequenz σ. Für einen Algorithmus B und eine Metrik Q
bezeichne CBQ die Kosten
M von B aufMσ unter Q. Wir werden beweisen, dass für jeden
Algorithmus B gilt E CA ≤ 3α · CB . Aus dieser Behauptung folgt unmittelbar, dass
der Algorithmus 3α-kompetitive ist.
58
Sei B nun ein beliebiger Algorithmus. Die Gesamtkosten beim FAP lassen sich
als eine Linearkombination von Kosten einzelner Kanten interpretieren. Insbesondere
können wir die Kosten von B auf die Knotenpaare umlegen, d.h. wir können jedem
Knotenpaar u, v ∈ V einen absoluten Kostenwert CB (u, v) zuordnen, sodass für jede
Metrik Q gilt
CBQ = ∑ CB (u, v) · dQ (u, v) .
u,v∈V
Für Algorithmus B auf der zufällig ausgewählten Metrik N gilt somit
"
#
N
E CB = E ∑ CB (u, v) · dN (u, v)
u,v∈V
=
∑
CB (u, v) · E [dN (u, v)]
∑
CB (u, v) · αdM (u, v)
u,v∈V
≤
=
u,v∈V
α ·CBM
.
M
N
Aufgrund derDominanz
von
N
über
M,
ist
E
C
≤
E
CA . Weil A 3-kompetitive
A
N
N
N
für N ist, gilt E CA ≤ E 3 ·CB = 3 · E CB . Insgesamt erhalten wir somit
E CAM ≤ E CAN ≤ 3 · E CBN ≤ 3α ·CBM .
Das obige Lemma zusammen mit Satz 3.6 liefert das folgende Ergebnis.
Korollar 3.9 Für jeden Graphen G = (V, E) gibt es einen verteilten, randomisierten
Online-Algorithmus für FAP der O(log |V |)-kompetitive ist.
3.5
Weiterführende Literatur
- Static and Dynamic Data Management in Networks [Vöc98]
- Caching in Networks: Non-Uniform Algorithms and Memory Capacity Constraints
[Wes01]
59
Kapitel 4
Lastbalancierung
Wir beschäftigen uns in diesem Kapitel mit dem Problem der Lastbalancierung. Bei
diesem Problem werden Jobs an Maschinen verteilt, sodass die maximale Auslastung
der Maschinen minimiert wird. Wir haben eine Menge von möglicherweise verschiedenen Maschinen gegeben und in der Online-Version des Problems erscheinen die Jobs
nacheinander und müssen sofort einer der Maschinen zugewiesen werden. Dabei erzeugt jeder Job auf den Maschinen eine Last (die möglicherweise von der Maschine
abhängt). Zu jedem Zeitpunkt hat also jede Maschine i eine Last li . Das Ziel ist es, die
maximale Auslastung, d.h. max{li : 1 ≤ i ≤ N}, zu minimieren.
Eine andere Betrachtungsweise ist, dass jeder der Jobs auf den Maschinen eine bestimmte Dauer hat und man die Gesamtbearbeitungszeit minimieren möchte. Dabei
ist diese bei nicht teilbaren Jobs stets durch die Dauer des längsten Jobs nach unten
beschränkt.
4.1
Identische Maschinen
Als erstes werden wir uns die einfachste Variante des Lastbalancierungsproblems anschauen. Dabei haben wir N identische Maschinen. Eine Eingabesequenz von Jobs soll
den einzelnen Maschinen zugewiesen werden. Jeder Job erzeugt eine Last auf der zugewiesenen Maschine. Da die Maschinen identisch sind, hängt auch die zugewiesene
Last nicht von der Maschine ab. Man muss also die Jobs nur möglichst gleichmäßig
auf die Maschinen verteilen.
Wir betrachten folgenden Algorithmus.
• Greedy: Jeder eingehende Job wird der Maschine zugewiesen, die die niedrigste
Last hat. Haben zwei Maschinen identische Last, wird die Maschine mit der
kleineren Nummer gewählt.
Theorem 4.1 Für N Maschinen erreicht Greedy eine Kompetitiv-Ratio von 2 − N1 .
Beweis. Wir zeigen zunächst, dass Greedy keine bessere Kompetitiv-Ratio als 2 − N1
erreicht. Dazu betrachten wir eine Sequenz, die zunächst aus N · (N − 1) Jobs mit Last
60
1 besteht, gefolgt von einem einzigen Job mit Last N. Offensichtlich wird Greedy einer
Maschine eine Last von 2N − 1 zuweisen, während ein optimaler Offline-Algorithmus
jeder Maschine genau eine Last von N zuweist. Also sind die Kosten von Greedy auf
dieser Sequenz (2 − N1 )-mal so hoch wie die eines optimalen Offline-Algorithmus.
Wir zeigen nun, dass es keine schlechtere Eingabesequenz gibt. Sei dazu σ eine beliebige Eingabesequenz. O.b.d.A. nehmen wir an, dass die höchste Last von Greedy
auf Maschine 1 entsteht. Sei w das Gewicht des letzten Jobs, der an Maschine 1 zugewiesen wurde und es sei s das Gewicht von Maschine 1 vor dieser Zuweisung. Also
sind die Kosten von Greedy genau w + s. Außerdem ist natürlich die Last auf jeder anderen Maschine ebenfalls mindestens s, denn sonst wäre der letzte Job nicht Maschine
1 zugewiesen worden. Also ist die Gesamtlast mindestens w + N · s. Daraus folgt, dass
OPT(σ) ≥ max{ w+Ns
N , w} ist. Es gilt daher
Greedy(σ) = w + s
w + Ns
≤ w + s + OPT(σ) −
N
w
= w + OPT(σ) −
N
1
= OPT(σ) + (1 − ) · w
N
1
≤ OPT(σ) + (1 − ) · OPT(σ)
N
1
= (2 − ) · OPT(σ) .
N
4.2
Eingeschränkte Maschinen
Im Modell für eingeschränkte Maschinen haben wir wieder N identische Maschinen.
Allerdings kann nicht jeder Job jeder Maschine zugewiesen werden. Daher gibt es zu
jedem Job eine Menge von zugelassenen Maschinen, denen der Job zugewiesen werden darf. Wir können nun den Algorithmus Greedy auf dieses neue Modell erweitern,
indem ein Job der zugelassenen Maschine zugewiesen wird, die die geringste Last hat.
Theorem 4.2 Für N eingeschränkte Maschinen ist Greedy (dlog Ne + 1)-kompetitiv.
Beweis. Sei σ = σ1 · · · σn eine Eingabesequenz, wobei Job σk eine Last wk auf einer
n w
i
zugelassenen Maschine erzeugt. Offensichtlich gilt OPT(σ) ≥ ∑i=1
N .
Wir betrachten nun die Zuweisung dieser Jobs durch Greedy an die einzelnen Maschinen. Wir teilen diese Zuweisung in Schichten ein. Jede Schicht hat eine Dicke von
OPT(σ). Diese Einteilung kann dazu führen, dass Jobs zwischen zwei aneinandergrenzenden Schichten aufgeteilt werden (aufgrund der Größe der Schichten, kann ein Job
61
nicht auf mehr als zwei aneinandergrenzende Schichten aufgeteilt werden). Wir bezeichnen mit Wi die Gesamtlast, die Greedy in Schicht i den Maschinen zuweist (die
Last von Jobs, die auf zwei Schichten aufgeteilt wurden, wird gemäß dieser Aufteilung
berücksichtigt). Es gilt also für die Gesamtlast
n
N
W = ∑ wk = ∑ Wi .
i=1
i=1
Wir bezeichnen mit
i
Ri = W − ∑ W j
j=1
die Restlast, die noch nicht in Schicht 1, . . . i vollständig durch Greedy zugewiesen
wurde. Wir zeigen nun, dass sich in jeder Schicht die Restlast halbiert. Zunächst beweisen wir folgendes Lemma.
Lemma 4.3 Ri ≤ Wi .
Beweis. Wir benötigen die folgende Notation:
• Wi j : Die Last auf Maschine j in Schicht i.
• zik : Die (partielle) Last von Job σk in Schicht i. Für σk gibt es maximal zwei
aufeinanderfolgenden Schichten mit zik > 0.
• Oi j : Die Menge der Jobs, die OPT Maschine j zuweist und die noch nicht in
Schicht 1, . . . i vollständig durch Greedy zugewiesen wurden.
• Ri j : Die Summe der (partiellen) Lasten von Jobs in Oi j .
Wir zeigen, dass Ri j ≤ Wi j ist. Damit ist dann
N
Ri =
N
∑ Ri j ≤ ∑ Wi j = Wi
j=1
,
j=1
und das Lemma folgt.
Wenn Oi j = 0/ ist, folgt Ri j = 0 ≤ Wi j . Wenn Wi j = OPT(σ) ist, folgt Ri j ≤ OPT(σ) =
Wi j .
Daher verbleibt nur der Fall, dass Oi j 6= 0/ und Wi j < OPT(σ) ist. Sei r die Maschine,
der Greedy den Job σk ∈ Oi j zuweist. Aus Wi j < OPT(σ) folgt, dass r 6= j ist. Es gilt
Wir − zik ≤ Wi j , ansonsten hätte Greedy den Job σk der Maschine j zugewiesen. Es ist
Wir = OPT(σ), ansonsten wäre σk 6∈ Oi j . Zusammenfassend gilt:
OPT(σ) − zik ≤ Wi j .
Mit der Beobachtung, dass ∑σk ∈Oi j wk ≤ OPT(σ) ist, können wir dann folgern
Ri j =
∑
wk − zik ≤ OPT(σ) −
σk ∈Oi j
∑
σk ∈Oi j
62
zik ≤ Wi j .
Aus dem Lemma folgt Ri ≤ Wi = Ri−1 − Ri , und somit gilt Ri ≤
Rdlog Ne ≤
Ri−1
2 .
Deshalb ist
R0 W
=
≤ OPT(σ) .
N
N
Damit kann die Restlast Rdlog Ne in Schicht dlog Ne + 1 abgearbeitet werden und der
Satz folgt.
4.3
Verwandte Maschinen
Im Modell der verwandten Maschinen haben wir wieder N Maschinen, die jeden Job
annehmen können. Allerdings hat jede Maschine i eine Geschwindigkeit oder Eignung
αi , so dass ein Job mit der Last w auf Maschine i eine Last von αwi erzeugt. Zunächst
werden wir nun annehmen, dass OPT(σ) ≤ Λ ist. Unter dieser Annahme betrachten
wir den Algorithmus SlowfitΛ .
• SlowfitΛ : Jeder eingehende Job wird der langsamsten Maschine zugewiesen,
die nach der Zuweisung noch eine Last von höchstens 2Λ hat. Wir sagen, dass
SlowfitΛ einen Fehler macht, wenn es keine solche Maschine gibt.
Theorem 4.4 Für eine Eingabesequenz σ, mit OPT(σ) ≤ Λ, macht SlowfitΛ keinen
Fehler und es gilt SlowfitΛ (σ) ≤ 2Λ.
Beweis. Sei σ = σ1 · · · σn eine Eingabesequenz, wobei Job σk die Größe wk hat. Es
reicht zu zeigen, dass SlowfitΛ keinen Fehler macht, denn dann gilt offensichtlich
SlowfitΛ (σ) ≤ 2Λ. Dies wollen wir per Widerspruchsbeweis tun. Dazu nehmen wir
an, dass OPT(σ) ≤ Λ ist und dass SlowfitΛ bei der n-ten Job einen Fehler macht.
O.B.d.A. nehmen wir an, dass die Maschinen von der langsamsten zur schnellsten
aufsteigend angeordnet sind, d.h. α1 ≤ · · · ≤ αN . Mit lt (i) bezeichnen wir die Last
der Maschine i nachdem Job σt zugewiesen ist1 . Wir nennen eine Maschine i ausgelastet, wenn ln−1 (i) > OPT(σ) ist. Wir nennen eine Maschine i überladen, wenn die
Maschinen {i, . . . N} ausgelastet sind.
Sei Γ die Menge der überladenen Maschinen.
Lemma 4.5 Seien Si und Si∗ die Mengen der Jobs, die Maschine i durch SlowfitΛ und
OPT zugewiesen werden. Dann ist
∑
i∈Γ, s∈Si
ws >
∑
ws .
i∈Γ, s∈Si∗
Beweis. Es muss Γ 6= 0/ sein. Ansonsten würde SlowfitΛ der n-te Job der schnellsten Maschine zuweisen, denn die Last eines Jobs auf der schnellsten Maschine ist höchstens OPT(σ). Damit wäre die Last nach dieser Zuweisung höchstens
2 · OPT(σ) ≤ 2Λ und SlowfitΛ würde keinen Fehler machen.
1 b.z.w.
den Zeitpunkt, zu dem Maschine i Job t bearbeitet hat.
63
Für Γ 6= 0/ folgt
∑
ws =
i∈Γ
i∈Γ,s∈Si
>
ws
s∈Si αi
∑ αi ∑
∑ αi · OPT(σ)
i∈Γ
≥
ws
∑ αi ∑∗ αi
i∈Γ
=
s∈Si
∑
ws .
i∈Γ,s∈Si∗
Es gibt mindestens eine Maschine, die nicht überladen ist. Für Γ = {1, 2, . . . , N}
würde gelten
∑ ws = ∑ ws ,
i∈Γ,s∈Si
i∈Γ,s∈Si∗
was im Widerspruch zu Lemma 4.5 steht.
Wir bezeichnen mit f die schnellste Maschine, die nicht überladen ist. Es gibt einen
Jobs σs mit s < n, die von SlowfitΛ einer Maschine m ∈ Γ zugewiesen wird und die von
OPT einer langsameren Maschine m0 6∈ Γ zugewiesen wird. Aus der Annahme, dass ein
solcher Job nicht existiert, können wir folgern, dass jeder Job, der von SlowfitΛ einer
Maschine i ∈ Γ zugewiesen wird, auch von OPT einer Maschine i0 ∈ Γ zugewiesen
wird. Dann gilt
∑ ws ≤ ∑ ws ,
i∈Γ,s∈Si
i∈Γ,s∈Si∗
was ebenfalls im Widerspruch zu Lemma 4.5 steht.
Also können wir folgern
ws
ws
≤
≤ OPT(σ) ≤ Λ .
αf
αm0
Außerdem gilt
ls−1 ( f ) ≤ ln−1 ( f ) ≤ OPT(σ) ≤ Λ .
Daraus folgt, dass ls−1 ( f ) + αwsf ≤ 2Λ ist. Damit hätte SlowfitΛ den Job σs aber der
Maschine f (oder eine langsamere Maschine) anstelle der Maschine m ∈ Γ zuweisen
müssen.
Bisher benötigten wir für den Algorithmus SlowfitΛ eine Schranke Λ bezüglich der
maximalen Last eines optimalen Offline-Algorithmus. Wir werden nun aus SlowfitΛ
den Algorithmus Slowfit konstruieren, der keine solche obere Schranke mehr benötigt.
Der Algorithmus Slowfit läuft in Phasen ab. In der Phase 0 führen wir den Algorithmus SlowfitΛ0 aus, wobei Λ0 der Größe des ersten Jobs entspricht. Wenn der Algorithmus SlowfitΛ0 bei einem Job einen Fehler macht, dann beginnt mit diesem Job
64
die nächste Phase. In der Phase i führen wir den Algorithmus SlowfitΛi aus, wobei
Λi = 2i · Λ0 ist. Auch hier gilt: Wenn der Algorithmus SlowfitΛi bei einem Job einen
Fehler macht, dann beginnt mit diesem Job die nächste Phase.
Theorem 4.6 Der Algorithmus Slowfit ist 8-kompetitive.
Beweis. Wir bezeichnen mit σi den Teil der Eingabesequenz, der in Phasen i abgearbeitet wird. Sei h die Phase, in der Slowfit terminiert. Dann gilt mit Satz 4.4:
OPT(σ) ≥ OPT(σ0 · · · σh−1 r) > 2h−1 · Λ0 ,
wobei r den Job bezeichnet, die den Fehler am Ende von Phase h − 1 erzeugt.
Für die maximale Last von Slowfit gilt demgegenüber:
h
h
Slowfit(σ) = ∑ SlowfitΛi (σi ) ≤ ∑ 2i+1 Λ0 ≤ 2h+2 Λ0 .
i=0
i=0
Da 2(h+2) = 2(h−1) · 23 ist, ist das Theorem bewiesen.
4.4
Weiterführende Literatur
- Online Computation and Competitive Analysis - [BEY98]
65
Literaturverzeichnis
[BEY98] Allan Borodin and Ran El-Yaniv. Online computation and competitive
analysis. Cambridge University Press, 1998.
[CLRS09] Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford
Stein. Introduction to Algorithms (3. ed.). MIT Press, 2009.
[Koz92]
Dexter Kozen. Design and analysis of algorithms. Texts and monographs
in computer science. Springer, 1992.
[Vöc98]
Berthold Vöcking. Static and Dynamic Data Management in Networks.
Dissertation, Universität Paderborn, Heinz Nixdorf Institut, Theoretische
Informatik, 1998.
[Wes01]
Matthias Westermann. Caching in Networks: Non-Uniform Algorithms
and Memory Capacity Constraints. Dissertation, Universität Paderborn,
Heinz Nixdorf Institut, Theoretische Informatik, January 2001.
66
Herunterladen