Zusammenfassung „Parallele Algorithmen“

Werbung
Zusammenfassung
Zur Diplomprüfungsvorbereitung
„Parallele Algorithmen“
„Prof. Dr Amitava Datta“
Sommersemester 2002
Zusammengefasst von Markus Krebs und Andreas Horstmann
November 2002
1
Themenübersicht:
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Grundlagen
PRAM-Modelle
Netzwerkmodelle
Speicherzugriffsarten
Algorithmus: Präfixsummen
Algorithmus: Präfixsummen (rekursiv)
Algorithmus: Pointer Jumping
Strategie: Partitioning und Merging
Algorithmus: Berechnung des Maximums (3 verschiedene)
Strategie: Accelerated Cascading
Algorithmus: List Ranking (3 verschiedene)
Algorithmus: Euler Tour Technik
Algorithmus: Rooting a Tree (umgekehrte Euler Tour Technik)
Die Rake Operation
Algorithmus: Auswertung eines Ausdrucks dargestellt in einem
Baum
Algorithmus: Parallele Suche in einem sortierten Array
Algorithmus: Verschiedene Merging-Algorithmen => Effizient
sortieren
Algorithmus: Verbundene Komponenten
o Strategie: Pseudo-Forest
o Algorithmus: „Verbundene Komponenten für dichte Graphen“
o Algorithmus: „Verbundene Komponenten für dünne(lichte)
Graphen“
o Grafting
o Algorithmus: Erkennen eines Sternen
Algorithmus: 2D Convex Hull Problem
Algorithmus: Halbebenenschnitt
Algorithmus: 2 Variable Linear Programming Problem
Die Klassen NC, P, NP
Das Circuit Value Problem
Beispiele für P-Vollständige Probleme
2
Vorlesung 1.1:
Beispiel: 8 Zahlen aufsummieren => Zeit log n, aber w(n) n log n
W(n) = Working Compelxity =T(n)x P(n)
T(n) = Ausführungszeit
P(n) = Anzahl der Prozessoren
Wann ist eine Par. Algorithmus Effizient ?
Ö Wenn W1(n) in o(w2(n)) liegt
Ö Wenn W1(n) = W2(n) dann der schnellere (kleineres T(n)
Problem: Wenn W1(n) > W2(n) aber T1(n)<T2(n).
Optimale Parallele Algorithmen
Work-optimal: Wenn die Workcomplexity in der Zeitkomplexitaet des zugehörigen
sequentiellen Allgorithmus liegt. W(n)=O(Tseq(n))
Work-time-optimal: Wenn die Zeit des parallelen Alg. (Tpar(n)) nicht verbessert
werden kann.
Beispiel von oben verbessert: Statt Aufteilung von 2 Zahlen an jeden Prozessor
unterteilung in n/log n. D.h. jeder Prozessor hat am Anfang log n Zahlen sequentiell
zu bearbeiten
in n Hierarchiestufen damit haben wir ein w(n)= O((n/log n) * log
n) =O(n).
Vorlesung 1.2:
Warum Parallel-Computing ?
Ö Riesige Rechengebiete, die mit normalen Seq-Rechnern nur in hoher Zeit
berechnet werden könnten (Protein folding, Wetterbericht)
Ö Wegen physikalische Beschränkungen im herkömmlichen VLSI Design
o Minimisierung nur bis auf die größe eine Silizium Atoms theoretisch
möglich. D.h. Grenze in ca. 15 Jahren erreicht, Mooresches Gesetz
verliert dann seine Gültigkeit.
o Lichtgeschwindigkeit: Elektronen brauchen Zeit um durch die
Leiterbahnen zu laufen 3x10^8 m/s. Zeit um zwischen zwei Atomen
„Daten“ auszutauschen ist 10-18 s bei vielen Tausen Transistoren steigt
der Wert noch auf 10-15s. => Grenze ist bei 1000 Teraflops erreicht.
Aktuelle normale Rechner sind im Gigaflop bereich.
Vorteile von Parallel-Computing
Ö Die. o.g. Limits überwinden
Ö Schon heute werden viel „Paralleltechniken“ angewandt wie zB Pipelining
Probleme
Ö Konventionelle von Neumann Architektur
Ö Software und Hardware zu eng verflochten
Ö Lösung durch Random Access Machine Modell
Ö Viele verschiedene Paralelle Modell die alle anders funktionieren
3
o Spezifische Lösungen aber keine allgemeinen
Ö Betriebssyteme sind schwer auf dieser Basis zu erstellen
Das PRAM Modell
Ö N prozessoren greifen auf den gleichen Speicher zu und sollen zu jeder Zeit
auf jede Zelel zugreifen können => evtl. Konflikte
Ö Spezielle Lösung der Uni des Saarlandes => SB-PRAM. Lösung mittels
zwischengeschalteter „Network“ Komponente
Ö PRAM ist ein theoretische Modell, andere Modell zB Butterfly, hypercube und
Vermaschung werden auch verwendet.
Ö Aber Algorithmen für PRAM Modell ist einfach auf andere Systeme
übertragbar
Ö Wir reden hauptsächlich über Algorithmen für PRAM Modelle, andere System
werden nur besprochen, wenn diese Lösungen (Algorithmen) komplett anders
sind.
Vorlesung 2.1:
Parallelcomputer Modell
Ö SIMD
o
Ö MIMD
o
Ö SISD
o
Ö MISD
o
Wichtigstes Modell zum Lösen von regulären Strukturen
Generelleres Modell für Probleme ohne reguläre Struktur
Der normale sequentielle Rechner (KEIN Parallelrechner)
Macht keinen Sinn
SIMD:
N-Prozessoren
Charakteristik:
Ö Jeder Prozessoren kann sowohl Programm als auch Daten in seinem lokalen
Speicher speichern
Ö Jeder Prozessor hat das gleiche Programm im Speicher
Ö In jedem Zyklus führt jeder Prozessor die gleiche Instruktion aus, obwohl die
Daten unterschiedlich sein können
Ö Die Prozessoren Kommunizieren z.B. über Interconnection Netze oder
„shared Memory“
Design Aspekte von SIMD
Ö Modell ist ein Graph, die Knoten sind die Prozessoren, die Kanten die
Verbindungen
Ö Da jeder Prozessor nur ein Teilproblem der Gesamtaufgabe löst, ist es
notwendig, dass die Prozessoren miteinander kommunizieren um das
Gesamtproblem zu lösen
Ö Die wichtigste Design Aspekte für Network SIMD Modelle sind:
o Communication Diameter (Durchmesser)
o Bisection Width
4
o Scalability (Skalierbarkeit)
Communication Diameter
Ö Größter Abstand zwischen zwei Knoten
Ö Wenn Diameter=d => Ω (d)
Bisection Width
Ö Anzahl der Linkentfernungen zum Teilen des Graphen in zwei gleiche Teile
Ö Je größer die Bisection Width, desto besser können die Knoten miteinander
Kommunizieren, da es mehr Wege gibt
Scalability
Ö Einfachheit des Erweiterns des Graphen um einen weiteren Prozessor
Ö Je größer die Bisection Width, desto mehr Links müssen beim Hinzufügen
eines neuen Prozessor angelegt werden
Ö Extremfälle: Vollständig vermaschter Graph, linearer Graph
Zwei wichtige Netzwerkmodelle sind:
Ö Mesh (Masche) (2-Dimensionaler Graph, Matrix)
o Jeder Prozessor hat 4 Nachbarn
o Wenn man etwas hinzufügt müssen nur die Randknoten verbunden
werden => Sehr gute Skalierbarkeit
o Bisecton Width und Diameter = O(Sqrt(n))
Ö Hypercube
o 0,1,2,3… Dimensionen
o d-dimensional Æ 2d Prozessoren
o Direkt verbunden wenn die Bezeichnung nur um ein Bit differiert
o Diameter = d
o Bisection Width = 2d-1
o Skalierbarkeit: einfach zwei Hypercubes verbinden und man erhält d+1
Dimensionen
o Verschiedene Varianten von Hypercubes: Butterfly, shuffle Exchange
Network, Cube connected Cycles
Beispiel für beide: n Zahlen addieren:
Ö Mesh => sqrt(n) Schritte
Ö Hypercube => log(n) Schritte
Ö Bei beiden ablaufen der Dimensionen
Vorlesung 2.2:
Verschiedene PRAM Modelle geordnet nach Mächtigkeit:
Ö EREW (Exclusive Read, Exclusive Write)
Ö CREW (Concurrent Read…)
Ö CRCW
o Common CRCW PRAM (Alle schreiben gleichen Wert auf
Speicherzelle
o Arbitrary CRCW PRAM ( Willkürlicher Erfolg beim schreiben des Werts
o Priority CRCW PRAM (Der Proz. Mit höchster Priorität gewinnt)
5
Ö Ein Algorithmus eines schwächeren Modells läuft in gleicher Zeit und
Komplexität auch auf einem mächtigeren Modell.
Ö Ein Algorithmus eines mächtigeren Modells kann auf einem schwächeren mit
Hilfe von meh Zeit bzw. mehr Prozessoren simuliert werden
Ein Modell A ist schwächer, wenn die Zeitkomplexität höher ist als bei einem Modell
B. Sind die Zeitkomplexitäten gleich, wird nach der Workkomplexity entschieden. Je
größer diese dann ist desto schwächer das Modell.
Beispiel mit n-Zahlen aufsummieren läuft auf einem EREW Modell
Beispiel Matrix Multiplikation
Ö typisches Beispiel für CREW Modell (Zeitkompl.= O(log n), Work = O(n3)
Ö Kann umgewandelt werden für EREW Modell (kopieren der Speicherbereiche
in exklusive Bereiche) Zeitkompl. = O(log n), Work = O(n3), ABER: Viel mehr
Speicher als beim CREW Modell benötigt !
Vorlesung 3.1:
Berechnung der Präfixsumme
Ö Gegeben eine Liste von geordneten Elementen (a0,a1,a2,a3…an-1)
Ö Anwenden eine binären, assoziativen Operators 8
Ö Berechnen des Set (a0, (a08a1), (a08a18a2),…,(a08a18…8an-1))
Bei + wäre das
bei folgendem Set (5,3,-6,2,7,10,-2,8) das Ergebnis (5,8,2,4,11,21,19,27)
Sequentielle Berechnung dauert O(n) Zeit
Parallele Berechnung in 2 Schritten (Bottom-Up und dannTop-Down)
Schritt 1:
sum[v]:=sum[L[v]]+sum[R[v]], Daten warden in Array geschrieben.
Schritt 2:
6
pre[L[v]]:=pre[v]
pre[R[v]:=sum[L[v]]+pre[v]
gelbe Zahlen aus erstem Schritt (sum…)
Problem Ergebnis um eins nach rechts geshiftet, d.h. Summe über alles fehlt, aber
diese steht in der Wurzel aus Schritt 1. => links shift und die Wurzel aus Schritt 1
anhängen.
Zeitkomplexität:
Prozessoren:
O (log n)
O(n)
Es ist möglich die Prozessoren auf O(n/log n) zu reduzieren.
Korrektheitsbeweis:
Nach Preorder prinzip durchlaufen
Lemma: Nach dem zweiten Schritt hat jeder Knoten die Summe seiner
Blättervorgänger
Induktion von der Wurzel ausgehend
Ö Indukionshypothese: Wenn ein Knoten die korrekte summe enthält so
enthalten auch seine Kinder die korrekte Summe.
Ö Basisfall: In der Wurzel zutreffend, da die Wurzel keine übergeordneten
Knoten hat
Ö Weiter: Betrachtung nach linkem und rechtem Kind
Sowohl Schritt 1 als auch Schritt zwei sind auf dem EREW Modell möglich
Vorlesung 3.2:
Rekursive Variante des Präfixsummen Algorithmus
Rekursive Berechnung der Präfix Summen in jeder Hierarchiebene, also immer zwei
Knoten addieren in jeder Ebene
7
Unterscheidung zwischen geraden und ungerade Indices
• Bei den geraden Indices müssen nur die Vorgänger aufaddiert werden.
• Bei den ungeraden Indices muss jeweil auf das ungerade xi zugegriffen
werden, welche nicht in den Vorgängerwerten enthalten ist.
Hier folgt nun eigentlich der Korrektheitsbeweis für den Algorithmus
Zeitkomplexität:
Work.kompl.:
O(log n) (In jedem Schritt wird das Problem halbier!)
O(n) (wegen O(n/log n) Prozessoren)
Pointer Jumping Algorithmus
„Rooted directed Tree“
Def.:
• Alle Knoten ausser dem Wurzelknoten haben OutDeg =1 , der Wurzelknoten
hat OutDeg=0
• Es existiert ein gerichteter Weg von jedem Knoten zum Wurzelknoten nicht
andersrum.
Problemstellung: Zu einem Knoten in einem Wald von Bäumen den zugehörigen
Wurzelknoten finden.
Algorithmus der aus jedem Baum ein Stern erzeugt, bei dem jeder Knoten
direkt an seiner Wurzel hängt:
8
Prefix on rooted directed Trees
Jetzt geben wir jedem Knoten zusätzlich einer Wert, also z.B. ein Gewicht
Berechnung ist gleich wie eben, nur dass zusätzlich das Gewicht bis hin zur Wurzel
in jedem Schritt noch aufaddiert wird.
Komplexität
Zeitkomplexität: O(log h) (h ist die maximale Tiefe des Baumes, in jedem
Iterationsschritt verringert sich die Tiefe um 1/2)
Prozessoren: O(n)
CREW wird benötigt !
Vorlesung 4.1:
Partitioning und Merging Strategie
Partitioning: Einteilung in unabhängige Teilprobleme. Parallel lösen. => ähnlich wie
Divide and Conquer bei sequentiellen Algorithmen, nur dass die Teilprobme beim
Partitioning parallel gelöst werden, bei Divide an Conquer rekursiv.
Merging: Gegeben sind zwei geordnete Listen. Aufgabe: verschmelzen dieser
beiden Listen, damit eine gemeinsame sortierte Liste entsteht.
Der sequentielle Algorithmus funktioniert so:
9
Zwei Pointer durchlaufen die Listen, die Elemente werden paarweise verglichen und
der betreffende Pointer inkrementiert. Die Ergebnisliste wir in ein neues Array
geschrieben. Wenn List 1 länge n hat und Liste 2 länge m, dann hat die Ergebnisliste
entsprechende Länge n+m => Die Komplexität ist O(n+m).
Ö Parallele Lösung durch Partioning Strategie
Bestimmen des Rangs einer Elementes einer Liste:
Rank(ai:A) Anzahl der Elemente in A die kleiner oder gleich ai sind
Rank(bi:A) Anzahl der Elemente in A die kleiner oder gleich bi sind
Die Position eines Elementes in der Ergebnisliste ist die Summer der beiden
Teilränge, also rank(ai:C)=rank(ai:A)+ rank(ai:B)
Paralleles Merging teilt nun das Gesamtproblem in viele kleine Teilproblem auf, die
parallel verarbeitet werden können. Wenn die Problemgröße klein genug ist, wird das
Problem sequentiell gelöst.
Schritt 1:
Die Liste B wird also in log m große Teile geteilt, es gibt also m/log m Teile. Das
letzte Element eines Teils steht immer an Position i* log m, also ein vielfaches von
log m.
Schritt 2:
Weise jedem Endelement der Liste B einen Prozessor zu. Dieser dursucht Liste A
mittels Binärer Suche und teilt diese Liste gemäß dem Endelement von Liste B.
Das Suchen geht in O(log n) Zeit und die Liste wird in m/log m Teile geteilt. Zwei
korrespondierende Blocks zwischen Liste B und A nennt man nun „matching Blocks“.
10
Wenn die Blöcke in Liste A größer als log m sind, dann werden diese in log m Blöcke
unterteilt. Nun geschieht das gleiche mit der Teilliste von B wie eben mit Liste A, Sie
wird mit binärer Suche durchsucht und „Matching Blocks“ zur Teilliste von A werden
gesucht. Jeder Block in Liste A ist jetzt auf jeden Fall in O(log m) Größe.
Dies dauert O(log log n) Zeit .
Schritt 3:
Nun folgt der bereits erklärte sequentielle Merging Algorithmus auf die Matching
Blocks Jeder zugewiesene Prozessor bearbeitet ein Paar von Matching Blocks in
O(log m) Zeit.
Komplexität:
Schritt 1:
Prozessoren:
Zeit:
m/log m
O(1)
Schritt 2:
Prozessoren:
Zeit:
Workin.komp.:
m/log m (Bleibt natürlich gleich)
O(log n)
O(m+n) (O((m/logm)*logn) ist in O(m+n)
Schritt 3:
Prozessoren:
Zeit:
Working: koml:
m/log m
O(log m)
O(m)
Der Algorithmus benötigt das CREW Modell, da die Prozessoren beim Teilen der
Liste gleiche Zellen lesen.
Theorem: Wenn 2 sortierte Listen der Größe n sind, dann können diese in O(log n)
Zeit und in O(n) Operationen gemerged werden.
Vorlesung 4.2:
1. Algorithmus zur Berechnung des Maximums
Berechnung des Maximums in O(1)
Ö Ein Array mit den p ungeordneten distincten Elementen
Ö Ein zweites Boolean Array initialisiert mit „1“
Schritt 1:
Ö Weise jedem Element der Liste p Prozessoren zu => p2 Prozessoren werden
benötigt.
Ö Jeder Prozessor für genau einen Vergleich durch: If A(i) > A(j) then M(j)=0
Ö Übrig bleibt dann genau eine „1“ im Boolean Array, diese markiert das größte
Element
Schritt 2:
11
Suchen der „1“ im Boolean Array mit p Prozessoren in Konstanter Zeit, da jeder
genau ein Element betrachtet. Der Prozessor der die „1“ findet gibt den Index k der
Zahl zurück.
Komplexität:
Prozessoren:
Zeit:
p2
O(1)
Der Algorithmus benötig das Common CRCW Modell, da alle Prozessoren, wenn sie
auf die gleiche Speicherzelle schreiben, das gleiche schreiben, nämlich die „0“.
Der Algorithmus ist also optimal bezüglich Zeit, aber sehr komplex im Bezug auf
Work.
2. Algorithmus zur Berechnung des Maximums
(Work-)Optimale Berechnung des Maximums
Komplexität:
Prozessoren:
Zeit:
Work.kompl.:
O(n) reduzierbar auf O(n/log n)
O(log n)
O(n)
3. Algorithmus zur Berechnung des Maximums
Berechnung des Maximums in O(log log n) Zeit
Kein Binärbaum sonder komplexer. Die Wurzel des Baumes hat
Jeder Knoten im i-ten Level hat nun
Kinder, wobei die Anzahl der Level.
Level k hat immer 2 Kinder ! Æ k=O(log log n)
12
An den einzelnen Knoten sind nun allerdings keine paarweise vergleiche mehr
möglich, da es mehr als 2 Kinder sind, deshalb nimmt man den O(1) Algorithmus von
oben.
Komplexität:
Zeit:
Working.kompl.:
Prozessoren:
O(log log n)
O(n log log n)
O(n)
Accelerated Cascading
Trick: Kaskadieren von zwei Algorithmen.
Beispiel mit Berechnung des Maximums:
Der zweite Algorithmus war workoptimal aber langsam
Der dritte Algorithmus war suboptimal aber sehr schnell
Wir kombinieren diese zwei Algorithmen mit der Accelerated Cascading Strategie.
Wir beginnen mit dem optimalen Algorithmus und reduzieren das Problem bis auf
eine gewisse Ebene, dann nehmen wir den suboptimalen aber sehr schnellen
Algorithmus.
Phase 1:
Bis Level (log log log n) wird der workoptimale Algorithmus verwendet
Komplexität:
Work:
O(n)
Zeit:
O(log log log n)
Die Anzahl der zu berechnenden Elemente reduziert sich auf
Phase 2
Nun kommt der schnelle aber suboptimale Algorithmus zum Zug. Dieser bearbeitet
die übrigen
Elemente
Komplexität:
Work.:
O(n)
Zeit:
O(log log n)
Theorem:
Das Maximum einer Liste von n Elementen kann in O(log log n) Zeit und O(n) work
auf einer Common CRCW PRAM berechnet werden
13
Vorlesung 5.1:
3 verschiedene List Ranking Algorithmen
1. O(log n) Zeit und O(n log n) Work
2. O(log n log log n) Zeit und O(n) Work
3. O(log n) Zeit und O(n) Work
List Ranking:
Lineare Liste, repräsentiert als Successor-Array
Input: Lineare Liste
Output: Distanzen der einzelnen Elemente bis zum Ende der Liste (Ranking)
z.B. Der Nachfolger von 1 (index) ist 5 (inhalt an Position 1) und von 2 ist 1….Der
Nachfolger von 3 ist 3 und ist damit das Ende der Liste.
Sequentiell ist das Problem in O(n) Zeit lösbar Æ Ein work-optimaler paralleler
Algorithmus sollte das Problem in O(n) Work lösen können.
Erster Algorithmus:
O(n) Zeit und O(n log n) Work
• Der Algorithmus basiert auf dem Präfixsummenalgorithmus.
• Am Anfang werden alle Elemente mit „1“ initialisiert, ausser dem Endknoten,
dieser wird mit „0“ initialisiert.
• Jetzt werden für jedes Element die Werte aufsummiert (Präfixsummen)
• Die Werte der einzelnen Elemente sind nun die Distanzen zum Endelement
14
Korrektheit:
• Untersuchung vor der Iteration.
• Untersuchung nach der Iteration
• Untersuchen ob der Algorithmus terminiert
Komplexität:
Iterationen:
Work,Kompl.:
Zeitkompl.:
Prozessoren:
O(log n)
O(n log n)
O(log n)
O(n)
Modell:
CREW-PRAM Modell
Zweiter Algorithmus
Verbesserung des ersten Algorithmus auf O(n) Work bei O(log n log log n) Zeit.
Strategie:
1. Aufteilen der List in Listen mit O(n/log n) Knoten
2. Pointer Jumping anwenden um den Wurzelknoten der nun erzeugten Teillisten
zu finden
3. Die ursprüngliche Liste wiederherstellen und die weggelassenen Knoten
„ranken“.
Schritt 1 ist sehr wichtig:
Ein Set i von Knoten ist unabhängig, wenn
(d.h. der Nachfolger jedes Knotens ist nicht im Set)
.
15
1. Phase:
2-Färbung der Liste:
Es existiert ein einfacher sequentieller-Algorithmus der das Problem in O(n) Zeit löst.
Beim parallelen Algorithmus ist das komplizierter, aber wir gehen davon aus, dass:
Theorem: „Eine verkettetet Liste mit n Knoten kann in O(log n) Zeit und O(n) work
zweigefärbt werden“
Im ersten Durchgang halbiert sich die Liste, wir wollen aber eine Liste mit n/log n
Knoten, d.h. wir müssen den 2-färbe Algorithmus (log log n) mal ausführen.
Speichern der Informationen über die aus einem Set entfernten Knoten:
Entfernt wurden diese mit O(log log n) Iterationen, deshalb muss das Hinzufügen
genauso schnell gehen.
oben: initiale Liste
untern: Knoten wurden entfernt und die Rankings der übrig gebliebenen Elementen
um den Rank des entfernten Knotens erhöht.
Nun werden zu dem Ursprünglichen Array S (Succ. Array), ein Predesscor Array P
und ein Array U, in welchem wir die entfernten Knoten, also Knotenindex, Vorgänger,
Nachfolger und Rank speichern, erzeugt.
16
•
•
•
•
•
Die Vorgänger und Nachfolgerpointer werden nun aktualisiert
Die Ranks der Knoten direkt vor einem entfernten Knoten werden akualisiert
Es gibt leere Arrayzellen
P und S können dann aber in O(n) work un d O(log n) Zeit mit Hilfe der
Präfixsummen komprimiert werden, allerdings nach JEDEM Entfernungsschritt
Wir benötigen ein separates U Array für jeden Iterationsschritt
2. Phase
•
Auf das auf n/log n reduzierte Teilarray wird nun in Phase 2 der suboptimale
Algorithmus angewandt (Alg. 1)
17
•
Ein entfernter Knoten kann nun mit Hilfe des U Arrays in O(1) wiedereingefügt
werden.
Komplexität:
Phase 1:
Die 2-Färbung und die Präfixsummerberechnung:
Zeit:
O(log n)
Work:
O(n)
Ö Gesamtzeit für Phase 1 = O(log n log log n)
Phase 2: In jeder Iteration halbiert sich Anzahl der Elemente in den Arrays. Jede
Iteration benötigt:
Work
O(n) wobei n aber nun die Größe des jeweiligen Arrays ist
Ö Also Gesamt Work O(n), weil n+n/2+n/4+n/8+…. und das ganze log log n mal
Zeit Gesamt:
Work Gesamt
O(log n log log n)
O(n)
Vorlesung 5.2:
Dritter Algorithmus:
Optimaler, randomisierter List Ranking Algorithmus
Zeit O(log n), Work O(n), Prozessoren: O(n/ log n), EREW Modell
Las Vegas Algorithmus (Liefert immer das richtige Ergebnis, braucht aber in seltenen
Fällen sehr lange, bzw. unendlich)
Monte Carlo Algorithmus (sehr schnell, aber das Ergebnis stimmt nur zu einer
angegebenen Wahrscheinlichkeit. Durch merhfaches Ausführen kann man die
Wahrscheinlichkeit erhöhren
Unser jetzt besprochener Algorithmus ist ein Las Vegas Algorithmus
Die Laufzeit von O(log n) wird mit sehr hoher Wahrscheinlichkeit erreicht, ist aber
nicht garantiert.
Der randomisierte Algorithmus ist im Prinzip identisch mit dem zweiten Algorithmus
(der mit der Zweifärbung).
Folgendes ist anders am dritten Algorithmus:
Aufteilung der Listen zunächst in n/log n Listen mit log n Größe
Dann werden jeweils die Endelemente in eine neuen Liste geschrieben, aber:
Ö Es darf nicht passieren, dass zwei in der Ursprungsliste aufeinanderfolgende
Elemente zusammen kommen. Lösung bei einem Konflikt:
Ö Die zwei konfligierenden Prozessoren erzeugen zufällig eine „1“ oder eine „0“.
Der Prozessor, der die „1“ hat darf seine Zahl übergeben (die spielen Schere,
Stein, Papier)
18
Ö Es entstehen nun log n Listen mit jeweils n/log n Elementen !!! (gerade
umgekehrt wie eben)
Ö Nun werden die Listen wieder wie in Algorithmus zwei mit dem Suboptimalen
Ranking Algorithmus zusammengefügt.
Komplexität:
Ö Die erwartete Zeit bis eine log n große Liste leer ist, ist (4 log n), da mit
Ö Wahrscheinlichkeit von ¼ ein Element entfernt wird. („1“ und „0“ ergeben 4
Möglichkeiten!!!)
Ö Wie große ist nun die Wahrscheinlichkeit, das es viel länger geht ?
o Die Wahrscheinlichkeit, dass es nach 16 log n Schritten noch nicht leer
ist, ist nach Chernoffs Ungleicheit kleiner als 1/n
o Also ist die Wahrscheinlichkeit, dass nach 16 log n Schritten überhaupt
noch eine nicht-leere Liste vorhanden ist, kleiner als
o Alle Knoten sind dann normalerweise nach O(log n) Schritten entfernt
Ö Das Wiederzusammenfügen und die Berechnung der Ranks dauert O(log n)
Ö Also terminiert der Algorithmus mit sehr hoher Wahrscheinlichkeit nach
o Zeit: O(log n)
o Work O(n)
Vorlesung 6.1:
„Die Euler Tour Technik“
Parallele Tiefensuche in einem Baum ist schwierig. Man kann den Endknoten erst
dann bestimmen, wenn man bereits die Vorgängerknoten besucht hat (sequentiell).
Lösung: Umwandlung des Baumes in eine Liste
Ö Gute Algorithmen für Listen vorhanden !!!
Ö Die Euler Tour erstellt eine Liste aus einem Baum, indem zusätzliche Kanten
eingefügt werden (magentafarben !).
19
Ö Die Liste wird dann in Tiefensuche erstellt, man erhält einen Zyklus, einen so
genannten Eulerkreis
Ö Hat der Baum n Knoten, dann erhalten wir eine Liste mit 2n-2 Knoten, wobei
jede Kante des Baumes nun ein Knoten der Liste ist
Definitionen:
Ö Für jeden Knoten v aus V ist p(v) der Vorgänger von v
Ö Jeder Rote Knoten der Liste repräsentiert eine Kante der Art <p(v),v>
Ö Zählt man die roten Knoten, so erhält man direkt die PreOder Nummerierung
(den index erhält man indem man die roten Knoten mit „1“ bewertet und die
magentafarbenene mit „0“ und darauf die Präfixsummen berechnet)
Ö Unser Ursprünglicher Baum heisst T=(V,E) und unser neuer Eulergraph heisst
jetzt T’=(V,E’). Jede Kante (u,v) aus E wird durch zwei Kanten (u,v) und (v,u)
ersetzt
Ö Indegree und Outdegree jedes Knotens ist nun gleich. Bei einem Blatt sind
diese jeweils 1
Ö T’ ist nun unser Eulergraph
Ö Ein Eulerkreis ist eine Tour den Baum entlang, bei dem jede Kante des
Graphen genau einmal besucht wird und man am Ende wieder am
Ausgangspunkt angelangt ist. Jeder Knoten wurde dann passiert.
Ö Ein Eulerkreis ist dann möglich, wenn jeder Knoten gleichen Indegree wie
Outdegree hat
Konstruktion des Eulerkreises
Ö Jede Kante hat genau eine Nachfolgerkante
Ö Speichere zu jedem Knoten seine adjazenten Knoten ab
Ö
(u0,u1…) sind die Nachbarknoten
von v und d ist die Anzahl derer
Ö Der Nachfolger der Kante <ui,v> ist
Ö mod d erzeugt hierbei einen Kreis, also den letzten Schritt der Euler Tour
20
Korrektheit:
Lemma: Die Succesor Funktion s definiert nur einen Zyklus, kein Set von Zyklen
Diese Lemma wird nun mit Induktion bewiesen
Parallele Konstruktion der Euler Tour
Ö Wir nehmen an, dass der Baum als eine Set von Adjazenzlisten gegeben ist
21
Ö In dieser Liste müssen die Pointer auf die Nachfolgerknoten sein
Ö Die Euler Tour kann man mit O(n) Prozessoren dann in konstanter Zeit O(1)
berechnen
Ö Jedem Knoten der Adjazenzliste wird ein Prozessor zugewiesen
Ö Es wird keine Concurrend read oder Write benötigt
Ö EREW Modell ist ausreichen
Vorlesung 6.2:
„Rooting a Tree“
Rücktransformation Euler-Tour Æ Baum, durch Angabe der gewünschten Wurzel
Ö Aufsplitten des Euler Zyklus an der gewünschten „Wurzelstelle“
Ö z.B. Wurzel=4, dann splitten der Kante zwischen <6,4> und dem Nachfolger
<4,3>
Ö Es entsteht nun wieder ein Baum
22
Algorithmus:
Eingabe: Die Euler Tour eines Baumes und ein spezieller Knoten r (Die neue Wurzel)
Ausgabe: Für jeden Knoten v (ohne r) den Vorgänger p(v).
, d.h. die zu
1. Aufsplitten der Euler Tour in dem
löschende Kante wird „0“ gesetzt. U ist der letzte Knoten der Adjazenzliste von
r
2. Weise jeder Kante den Wert „1“ zu und berechne die Präfixsummen parallel
3. Für jede Kante <x,y> setzen wir x =p(y), wenn die Präfixsumme von <x,y>
kleiner ist als die von <y,x>
Berechnungen auf Bäume
• Berechnen der Euler Tour
• Rooting eines Baumes mit einem bestimmten Knoten (Rücktransformation)
Wenn man diese zwei Schritte gemacht hat, kann man folgende Funktionen
ausführen:
• Postoder berechnen
• Preorder berechnen
• Inorder berechnen
• Level jedes Knotens
• Anzahl der Nachfolger jedes Knotens
Im Prinzip geht alles dann über die Präfixsummenberechnung wobei den Knoten
geschickt „1“ Werte zugewiesen werden.
23
Tree Contraction – Bäume Zusammenziehen
Manche Bäume sind für Euler Touren ungeeignet. Ein wichtiges Problem ist z.B. die
Darstellung von arithmetischen Ausdrücken.
Die Rake Operation
• T=(V,E) sein ein Binärbaum mit Wurzel und für jede Kante v ist p(v) der
Vorgänger
• Sib(v) ist das Kind von p(v) und das Geschwisterkind von v
• Für ein Blatt u mit p(u) ungleich r tue folgendes:
o Entferne u und p(u) von T
o Verbinde sib(u) mit p(p(u))
Beim Baum Zusammenziehen, führen wir die Rake Operation mehrfach und parallel
aus.
•
•
Man kann die Rake Operation nicht ausführen, wenn die Vorgängerknoten
zweier zu entfernender Blätter miteinander verbunden sind, z.B. geht hier 1
und 8 nicht!
Man muss die Rake Operation also auf nicht zusammenhängende Blätter
anwenden und zwar von links nach rechts, wie sie kommen.
24
Algorithmus:
1. Nummeriere die Blätter von links nach recht durch (in einem Eulerpfad
erscheinen die Blätter gerade von links nach rechts)
2. Weise jeder Kante <v,p(v)> eine „1“ zu, wenn v ein Blatt ist
3. Der linkste und der rechteste Knoten werden ausgelassen, da diese beiden
nach der vollständigen Kontraktion (3-Knoten Baum) als einzigste direkt mit
der Wurzel verbunden sind
4. Präfixsummenberechnung auf die Ergebnisliste Æ damit sind die Blätter nun
von links nach rechts durchnummeriert (Index)
5. Nun werden alls Blätter n in einem Array A gespeichert.
6. Im Subarray Aodd werden die Blätter mit den ungeraden Indexen gespeichert
und in Aeven die mit den geraden Indexen. Diese beiden Array können in
konstanter Zeit O(1) und in O(n) Work erstellt werden
Nun kommt der Rake Algorithmusm zur Anwendung:
1. Führe folgendes (log n +1) mal aus:
i. Paralleles Anwenden der Rake Operation auf alle linken Kinder
die im Array Aodd gespeichert sind
ii. Paralleles Anwenden der Rake Operaton auf den Rest der
Elemente von Aodd.
iii. Setze A auf Aeven
Komplexität
Zeit: O(log n) Kontraktionszeit
25
Work: O(n) Erstellen der Euler Tour
Gesamtzahl der Iterationen:
Vorlesung 6.3:
Auswertung eines Ausdruckes in einem Baum
• Um einen Ausdruck bottom-up auszuwerten benötigt man O(n) Zeit für einen
langen dünnen Baum. Darum wendet man die Tree Contraction an.
• Für jeden internen Knoten v weisen wir eine Bezeichnung (av,bv) zu. Wobei av
und bv Konstanten sind.
• Der Wert eines Ausdrucks an einem Knoten ist dann: (avX+bv), wobei X der
unbekannte Wert des Unterbaumes von v ist.
Invariante:
• Sei u der interne Knoten der den Operator
enthält.
• Seien v und w die Kinder von u mit den Bezeichnungen (av,bv) und (aw,bw).
Ö Dann ist der Wert bei u:
Beispiel
•
•
•
Jeder Knoten wird mit (1,0) initialisiert
Knoten „2“ markiert und der Level Hochgezogen
Die erste Zahl in der Klammer bezeichnet den Multiplikator und die zweite
Zahl den Summanden der auf die Multiplikation aufaddiert wird s.o.
26
•
Gemäß der Rake Operation wird nun der ganze Baum zusammengezogen bis
man das Endergebnis hat. (3er Baum aus dem man das Endergebnis direkt
berechnen kann)
Das Gesamtergebnis des Terms ist nun 50 !
Komplexität:
Zeit: O(log n)
Work: O(n)
27
Vorlesung 7.1:
Paralleler Such-Algorithmus in einem sortierten Array
• n ist die Anzahl der Elemente des Arrays
• p (<n) ist die Anzahl der verwendeten Prozessoren
•
Die Komplexität ist
Zeit
Eingabe:
• Ein sortiertes Array S=(x1,x2,….xn)
• Eine Query Element y
Ausgabe:
•
Zwei Elemente (xi und xi+1)aus S zwischen denen y liegt !
(ACHTUNG; Fehler in der Folie, hier korrigiert!)
•
•
•
Durch mehrere Iterationen wird das betreffende Array immer mehr verkleinert.
Es wird in p+1 Teile unterteilt, wobei wir p mal Binärsuche anwenden um y zu
finden. Die wird solange iteriert, bis die Größe des Arrays auf p gesunken ist.
Dann folgt ein direkter Vergleich (jeder Prozessor hat nun ein Element und
betrachtet seines und das des Nachfolgers)
Jeder Prozessor betrachtet sein letztes Element und vergleicht ob es größer
oder kleine y ist. Mit den beiden Ergebnissen wird das nächste Intervall
festgelegt, in welchem die Iteration weiterläuft.
Wenn das Array jetzt nur noch Größe p hat (entspricht der Anzahl der
Prozessoren), dann wird wie folgt vorgegangen.
o Wir weisen jedem Element einen Prozessor zu
o Direkter Vergleich seine Elements und des Nachfolgers
o In konstanter Zeit möglich !
Komplexität:
• In der ersten Iteration wird die Größe des Arrays von n auf n/(p+1) reduziert
• In weiteren k Iterationen reduziert sich die Größe auf p
• Deshalb n/(p+1k)=p Æ n=(p+1)k+1
Ö
28
Merging
Normales Ranking
Ö Rankings von jedem Element berechnen
Ö Daraus die Rankings der Ergebnisliste berechnen du damit das
Ergebnisnaufbauen
Ranking einer kurzes Zahlensequenz in eine sortierte Liste
Ö Sei X die sortierte Liste mit n Elementen
Ö Sei Y eine willkürliche Liste von m=O(ns) Elementen wobei s zwischen 0 und 1
liegt (die Y Liste ist damit kleiner als die X Liste !!!)
Ö Wenn wir
wir jedes Element von Y in
Prozessoren verwenden, dann können
Zeit in X ranken.
Ein schneller Merging-Algorithmus
Ö Wir haben nun zwei sortierte Arrays A und B mit n bzw. m Elementen.
Ö Schnelles Merging ist ein wichtiger Bestandteil von Divide and Conquer
Sortieralgorithmen
Eingabe:
• Zwei sortierte Listen A und B mit n bzw. m Elementen
Ausgabe:
• rank(B:A) und rank(A:B)
•
•
Wir teilen das Array B in SQRT(m) Teile auf mit SQRT(m) Elementen
Wir ranken nun jeweils das letzte Element von B in die Liste A dadurch kann
man die nun korrespondierenden Listen unabhängig und parallel mergen.
29
•
•
•
•
•
•
•
Die SQRT(m) Elemente aus B können nun in O(1) in mittels paralleler Binärer
Suche mit m Prozessoren in A gerankt werden.
Die Liste A hat auch SQRT(m) Blöcke
Die Blöcke können nun paarweise und rekursiv gemerged werden
Diese beiden paarweisen Blöcke nennen wir B’ und A’ mit den Elementen m’
und n’
Wenn nun m’ größer als n’, dann wird B’ unterteilt in SQRT(m’) Blöcke
Wenn n’ größer als m’, dann wird A’ unterteilt in SQRT(n’) Blöcke
Die jeweils korrespondierende Liste muss natürlich dann auch wieder gemäß
der Endelemente unterteilt werden Æ Rekursion
Beispiel:
Vorlesung 7.2:
30
•
•
•
Die Rekursion zwischen allen Paaren von Blöcken läuft parallel ab
Die Rekursion stoppt, wenn das Subproblem klein genug ist, dass es
sequentiell in O(1) gelöst werden kann
Am Ende des Algorithmus kennen wir rank(A:B) und rank(B:A), dann können
wir die Elemente in sortierter Reihenfolge in eine andere Array schreiben
Komplexität:
Zeit:
Work
O( log log m)
O((m+n)log log m)
Dieser Algorithmus ist zwar Zeitoptimal, aber noch nicht Work-optimal. Im folgenden
machen wir den Algorithmus work-optimal
Work-optimaler Merging Algorithmus
Work-Optimal heisst, ihn auf Workingkomplexität von O(m+n) zu bringen
• Wir haben nun der Einfachheit n Elemente in jeder Liste
• Wir teilen in (n/log log n) Blöcke von log log n Elementen auf
• Wir nehmen das letzte Element jedes Blocks von A bzw. B und schreiben
diese in eine Liste A’ bzw. B’ (A’ und B’ enthalten nur die Endelemente). Nun
haben A’ bzw. B’ (n/log log n) Elemente.
31
•
•
•
•
•
Nun berechnen wir rank(A’:B’) und rank(B’:A’). Das dauert O(log log n) Zeit
und letztendlich O(n) work (O((n/log log n) X log log n))
Jetzt berechnen wir mittels eines Prozessors noch rank(A’:B) um zu sehen in
welchen Blöcken B die Boundary Elemente aus A’ liegen
Jetzt wird die genaue Position (ranking) von Pi in Bk mittels Binärer Suche
und einem Prozessor ermittelt. Dies dauert wegen der (log log n) Elemente
(log log log n) Zeit !
Da alles parallel berechnet wird, benötigen wir O(n/loglog n) Prozessoren
rank(B’:A) geht analog
32
•
•
•
•
•
•
•
•
•
Betrachten wir nun Ai, einen der log log n großen Blöcke in A
Wir kennen rank(p:B) und rank(q:B) für die beiden Boundary Elemente p,q aus
A
Nun rufen wir unseren Algorithmus rekursiv auf mit Ai und den Elementen die
zwischen rank(p:B) und rank(q:B) lin B liegen
Möglicherweise sind aber zu viele Elemente dazwischen, und dadurch auch
mehrere Blöcke von B. Also werden nun die Grenzen dieser Blöcke wieder in
Ai gerankt
Dann bekommen wir Paar von Blöcke n ein log log n großer Block aus B und
ein kleinerer aus Ai
Jetzt haben wir nur noch ein Teilproblem von O(log log n) Größe
Es gibt O(n/log log n) Paare die von O(n/log log n) Prozessoren in O(log log n)
Zeit gemerged werden.
Die verschiedenen ranking Berechnungen dauern O(log log n Zeit) und
benötigen O(n) work,. Auch der letzte Mergeschritt benötigt diese Zeit.
Also können wir zwei sortierte Arrays der größe n in
Zeit
Work
O(log log n)
O(n)
Auf einem CREW PRAM Berechnen.
Effizient sortieren
• Mit dem eben vorgestellten Merging Algorithmus kann man wunderbar
sortieren (Merge Sort)
• Man hat ein unsortiertes Array von Elementen und teilt dies rekursiv (DaC) in
gleich große Teile bis auf Blattebene auf (ein Element pro Blatt)
• Dann werden die Kinder-Arrays gemerged (mit dem optimalen
Mergealgorithmus) bis hin zur Wurzel
• Auf jedem Level des Binärbaumes haben wir n Elemente verteilt auf
verschiedene Arrays
• Damit benötigen wir O(log log n) Zeit und O(n) work in jedem Level zum
paarweisen Mergen. Der Binärbaum hat eine Tiefe von O(log n) also
Zeit
Work
•
O(log n log log n)
O(n log n)
Dieser Algorithmus ist zwar workoptimal, aber nicht Zeitoptimal. Es gibt noch
einen besseren genannt „Cole’s pipelined merge sort algorithm“ der nur O(log
n) Zeit benötigt und sogar auf einem EREW PRAM läuft. S gitbt aber auch
noch einen viel eingacheren aber gleich effizienten Algorithmus, der mit
Randomisierung arbeitet
Vorlesung 8.1:
Parallele Graphen Algorithmen
Verbundene Komponenten
Sei G=(V,E) ein ungerichteter Graph mit |V|=n und |E|=m
33
Definition: Zwei Knoten u und v sind miteinander verbunden:
• Wenn u und v gleich sind, oder
• Wenn es einen Pfad von u nach v gibt
Diese Relation ist eine Äquivalenzrelation (Transitiv, reflexiv, symmetrisch)
Jede Äquivalenzklasse wird dann verbundene Komponente aus G genannt
Der Algorithmus bestimmt nun alle zusammenhängenden Knoten jedes Graphen
2 versch Algorithmen, Eingabe durch
• Adjazenzmatrix:
o Time O(log²n)
o Work O(n²) (Jeder Eintrag der Matrix muss mindestens einmal gelsen
warden)
• Kantenliste
o Time: O(log n)
o Work: O((m+n)log n) (Sehr gut für einen dünnen Graphen)
Strategie mit Pseudoforest
•
•
Ein Pseudoforest ist ein gerichteter Graph mit Outdeg=1
Die Wurzel muss auch wieder mit einem Knoten verbunden werden (=>
Genau 1 Zyklus)
Allgemeine Strategie:
• Man definiert sich eine Funktion D:VÆV die uns einen Pseudoforest (V,F)
erzeugt. Wobei F={<v,D(v)>|v € V}. Die Rücktransformation geht nicht immer.
34
Eigenschaften des Pseudoforest
Ö Jeder gerichtete Baum mit Wurzel in einem Pseudoforest enthält einen Zyklus
Beweis:
•
Wenn es zwei Zyklen C1 und C2 in einem Baum gibt, dann müssen diese
verbunden sein (s.o.) Wenn dies aber der Fall ist, dann gibt es automatisch
einen Knoten mit Outdeg=2. Æ Es gibt nur einen Zyklus
Vorgehensweise zur Erstellung des Pseudoforest:
• Der Algorithmus ist Iterativ
• In jeder Iteration werden Gruppen von adjazenten Knoten in größere Gruppen
gemerged
• Der Algorithmus terminiert wenn es nichts mehr zu mergen gibt
• Jede Gruppe wird nun repräsentiert durch einen gerichteten Graphen mit
Wurzel, wobei die Wurzel der Repräsentant der Gruppe ist
Optimaler Algorithmus für dichte Graphen (Gespeichert in Adjazenzmatrix !!!)
Sei A eine nXn Adjanzenzmatrix eines ungerichteten Graphen G=(V,E)
• A(i,j)=1, wenn i,j € E
• C(v)=min{u|A(u,v)=1}
o C(v)=v, wenn v ein isolierter Knoten ist (ohne Nachbarknoten)
o C(v) ist der kleinste Knoten adjazent zu v
Lemma:
C definiert einen Pseudoforest F der die Knotenmenge V aufteilt in V1…Vs, wobei
jede Vi ein Set von Knoten aus V des gerichteten Baumes Ti ist
1. Alle Knoten in jedem Vi gehören zur gleichen zusammenhängenden
Komponente von G
2. Jeder Zyklus in F ist entweder ein Zyklus auf sich selbst oder er enthält nur
zwei Kanten (zwischen zwei benachbarten Knoten)
3. Der Zyklus jedes Baumes Ti in F enthält den kleinsten Knoten in Ti
Die nun folgenden Beweise haben wir mit Mut zur Lücke weggelassen.
Vorlesung 8.2:
Die Iteration im Einzelnen:
35
1. Berechne die C Funktion für jeden Knoten aus jeder Zeile der Adjazenzmatrix
o Für jeden Knoten vi ist dies der kleinste Index der i-ten Zeile, welcher
eine „1“ enthält.
2. Schrumpfe jedes Set Vi von Knoten zu einem „Super-Knoten“. (Stern machen)
3. Erstelle eine neue Adjazenzmatrix aus den „Super-Knoten“.
Schritt 2 genauer:
•
•
•
Schrumpfen der Knotensets zu Sternen, d.h. alle Knoten sind die Kinder ihrer
Wurzel (wir möchten damit von jedem Knoten die Wurzel wissen)
Stichwort: „Pointer Jumping“ – Modifiziert zum Erkennen von Zyklen, sonst
Endlosschleife.
Danach ist jeder Knoten repräsentiert durch die Wurzel des Sternes
Schritt 3 genauer:
Erstellen der Adjazenzmatrix für die Superknoten (oben: Knoten 1,2,8)
• Vergleiche die Kindknoten und die Superknoten (Verknüpfungen zwischen
zwei Superknoten gibt es natürlich nicht) der einzelnen Sterne paarweise
miteinander und prüfe in der Ausgangsadjazenzmatrix ob diese eine
gemeinsameKante besitzen. (oben sind das die Vergleiche:
(5,4),(5,3)…(5,7),(4,9)…(7,9),(5,9) => die Sterne 1 und 2 sind z.B. über die
Kante zwischen den Knoten 5 und 4 miteinander verbunden (siehe
ursprüngliche Adjazenzmatrix))
36
Als Ergebnis iseht man nun aus A2 dass die beiden Sterne mit den Superknoten 1 und 2 miteinander verbunden sind
Nächste Iteration:
Am Ende haben wir nun in unserem Beispiel nur noch 2 „Connected Components“
(„1“ und „8“)
37
•
•
Nummerierung aller Knoten der einzelnen Komponenten mit ihrem
„Superknoten“
Um dies zu erreichen werden die Schritte des Algorithmus umgekehrt
ausgeführt
Knoten 2 bekommt die Nummer „1“ zugewiesen und damit bekommen alle Kinder
von „1“ und „2“ den Wert „1“ zugewiesen. Die Kinder von Knoten „8“ bekommen den
Wert „8“ zugewiesen.
Komplexität
Schritt 1 der Iteration: Berechnen der C Funktion (n minimum Berechnungen):
Für jede Zeile benötigen wir
Work:
Time:
O(n)
O(log n)
Und damit Gesamt:
Work:
Time:
O(n²)
O(log n) (wegen parallelberechnung)
38
Schritt 2 der Iteration: Zusamennziehen zu einem Stern mittels Pointer Jumping bzw.
List Ranking
Work:
O(n log n)
Time:
O(log n)
Schritt 3 der Iteration: Berechnen der Adjazenzmatrix der Superknoten
Zeit:
O(1)
Prozessoren O(n²)
Work:
k=k-ter Iterationsschritt
nk= Anzahl der zu bearbeitenden Elemente im k-ten Iterationsschritt.
Insgesamte Komplexität
•
•
•
Wir benötigen das „Common CRCW“ Modell (änderbar in CREW Modell)
Workkomplexität: O(n²)
Zeitkomplexität:
O(log n)
Die Workkomlexität könnte viel günstiger als O(n²) sein, wenn man einen
„Sparsegraphen“ (wenig Kanten) hat, der anstatt in eine Adjazenzmatrix in eine
Kantenliste gespeichert ist. Für „Densegraphen“ (viele Kanten) geht das nicht
schneller.
Vorlesung 9.1:
Optimaler Algorithmus für dünne Graphen (Gespeichert in Kantenliste)
•
Das problem bei dem Algorithmus für dichte Graphen eben war, dass wir in
jeder Iteration den „rooted directed tree“ in einen Stern umwandeln mussten,
was O(log n) Zeit benötigte.
•
Die C Funktion war zu eng definiert, deshalb konnten wir die den „rooted
directed trees“ nicht effizient zusammenfügen.
•
Im nun folgenden Algorithmus werden wir eine neue, allgemeinere Funktion D
verwenden um die Bäume zu mergen.
•
Wir werden auch nicht in jeder Iteration den Baum in einen Stern umwandeln
sondern wir werden den Pointer Jumping Algorithmus inkrementell verwenden
39
Grafting
Sei D eine Funktion auf die Knotenmenge V
• D.h. D angewendet auf v ergibt einen neuen Knoten w
o D(v)=w
• Initilisiert ist jeder Knoten v für D(v)=v
•
•
•
Ti und Tj sind zwei Bäume des Pseudoforest der durch D definiert wird
ri und rj sind die Wurzeln der beiden Bäume und v ist ein Knoten von Tj
Das Grafting von Ti auf Tj wird mittels D(ri)=v gemacht
•
Um nun die Höhe der entstandenen Bäume wieder zu reduzieren, wendet
man Pointer Jumping an.
Das Pointer Jumping auf einen Knoten v hat den Effekt D(v)=D(D(v))
Gesamte Strategie
• Wir repräsentieren jeden Baum durch seine Wurzel, deshalb wissen wir nicht
zu welchem Baum die Knoten u und v gehören !
• Wenn wir nun von einem Knoten die Wurzel kennen, dann können wir Grafting
in O(1) anwenden. Entweder u oder v ist nun ein Kind seiner Wurzel.
40
•
Wenn nun beide Knoten direkte Kinder ihrer Wurzeln sind, dann kann
passieren, dass Ti nach Tj gegrafted wird und umgekehrt, damit erhalten wir
einen ungewollten Zyklus.
•
Für jede Kante (u,v)€ E, wenn D(u)=D(D(u)) und wenn D(v)<D(u), dann
graften wir Ti auf Tj . Wir setzen D(D(u))=D(v).
o In anderen Worten: Wenn D(u) eine Wurzel ist (dann gilt D(u)=D(D(u)))
und wenn d(v)<D(u) dann setzen wir die Wurzel von u unter v (Graften)
Problem:
Wir wollen sicherstellen, dass die Bäume um einen konstanten Faktor verkleinert
werden, damit wir das problem in O(log n) Zeit lösen können, sonst klappt das nicht.
Die Grafting Operation oben stellt dies nicht sicher.
Mit diesem Conditional Grafting könnte es sogar Ω(n) dauern:
Beispiel (Worst Case):
•
•
Die Knoten des Sterns Ti sind kleiner als alle adjazenten Knoten von Tj
Der gerichtete Baum Tj hat kleinere adjazente Knoten in den Sternen T1…Tk
41
•
•
•
•
Aber es gibt keine Kante zwischen zwei Bäume T1…Tk
In diesem Fall wird Tj als erstes nach T1 gegrafted. Dann wird Tj U T1 nach
T2 gegrafted usw.
Somit wird am Ende(Tj U T1 U T2….U Tk) nach Ti gegrafted
So dauert es Ω(n) Time um alle Bäume zu mergen
Also, wir benötigen eine andere Operation um Bäume schneller zu mergen
Ö Unconditional Grafting
Nach jeder Iteration von Conditional Grafting versuchen wir nun die Sterne in andere
Bäume zu mergen:
In unserem schlechten Beispiel eben, könnten wir nun alle Sterne T1…Tk in einer
Iteration nach Tj mergen.
Beobachtungen:
•
Sowohl nur conditional- als auch nur unconditional Grafting ist nicht
ausreichend ! Verwenden wir nur unconditional Grafting, erhalten wir Zyklen.
•
Also führen wir in jeder Iteration erst conditional Grafting und dann
unconditional Grafting durch. (Macht man es andersherum, kann es wieder
Zyklen geben)
42
Vorlesung 9.2:
Erkennen eines Sternes
Für unconditional Grafting müssen wir erkennen können, ob eine
zusammenhängende Komponente ein Stern Ist.
Wir weisen jedem Knoten v einen Prozessor zu, welcher folgendes berechnet:
43
Star(v) ist am Ende „true“ wenn v zu einem Stern gehört, sonst nicht.
Korrektheit:
Behauptung 1:
Am Ende jeder Iteration sollte gelten:
• Der durch D definierte Pseudoforrest besteht aus „Directed Trees“ mit SelbstLoops an den Wurzeln
• Alle Knoten in einem Baum gehören zur gleichen verbundenen Komponente
Ö Prüfung durch Induktion über die Iterationsnummer k
Ö Basisfall k=0 Æ Erfüllt die Bedingung
Ö Gilt für i-te Iteration Æ soll auch für die i+1-te Iteration gelten
Ö Wir wenden nur conditional- unconditional Grafting und Pointer Jumping an.
Die 3 Operationen verändern an der Bedingung nichts, also ist die
Behauptung auch für den i+1-ten Schritt erfüllt
Behauptung 2:
•
•
Sei r die Wurzel eines Sternes nach einer Iteration
Alle Knoten v in der Zusammenhangskomponente von r hängen direkt an r
(D(v)=r für alle v)
Ö Beweis durch Gegenbeweis:
Ö Sei v ein Knoten und D(v) != r;
Ö v ist in einem „rooted directed tree“ mit Wurzel w
Ö wenn w eine Wurzel ist und v direkt an w hängt, v aber auch in der
Zusammenhangskomponente von r ist, dann kann r keine Wurzel eines
Sternes sein.
Ö Der Knoten r muss also an den Baum (mit Wurzel) w gegraftet worden sein
Implikationen:
44
Ö Wenn ein „rooted directed tree“ ein Stern ist am Ende einer Iteration, dann
sind alle Knoten dieses Sternes in der gleichen Zusammenhangskomponente.
o Deshalb können wir die Iteration stoppen, wenn alle „rooted directed
trees“ nun Sterne sind.
o Wie man einen Stern erkennen kann wissen wir bereits
Ö Wir haben nun alle verbundenen Komponenten gefunden, wenn die Bäume
alle Sterne sind
Behauptung 3:
•
•
Ö
Ö
Ö
Ö
Sei d die Tiefe des Baumes T bevor Pointer Jumping in der Iteration
angewendet wurde.
Nach dem Pointer Jumping ist die Tiefe 2d/3.
Wenn d gerade ist, dann haben wir nach dem Pointer Jumping d/2 als Tiefe
Wenn d ungerade ist, dann haben wir danach (d+1)/2 als Tiefe
Am schlechtesten ist es bei d=3, dann haben wir eine Tiefe von 2 nach dem
Pointer Jumping
Also reduziert sich die Tiefe auf mindestens 2d/3
Behauptung 4:
•
Sei K eine zusammenhangskomponente von G
o |K| ist die Anzahl der Knoten in K
o Am Ende der k-ten Iteration ist hk(K) die Summe der Höhen der Bäume
die die Knoten aus K enthalten
o Wenn alle Knoten aus K noch keinen Stern gebildet haben, dann gilt:
Ö Wenn wir zwei Bäume aus K aneinander Graften, dann erhöht sich die
Gesamthöhe der Bäume nicht
Ö In jedem Schritt reduziert das Pointer Jumping die Höhe jedes Baumes aus K
um 2/3
Ö Nach k-Iterationen ist die Gesamthöhe dann
Ö Somit ist nach O(log n) Schritten die Gesamthöhe auf 1 reduziert, also, wenn
alle Knoten in einem Stern sind
45
Ö Das heisst also, dass wir alle Knoten in den Zusammenhangskomponenten in
O(log n) Schritten zu einem Stern machen können
Komplexität:
• Die zwei Grafting Operationen und das Pointer Jumping gehen in O(1) Zeit
o Dazu weisen wir jeder Kante und jedem Knoten einen Prozessor zu
• Der Algorithmus macht O(m+n) work in jeder Iteration
• Es gibt O(log n) Iterationen Æ Gesamtwork O((m+n)*log n)) und O(log n) Zeit
• Beim uncondtional Grafting versuchen ggf. mehrere Prozessoren den gleichen
Baum zu Graften Æ Das „Arbitrary CRCW PRAM Modell“ wird benötigt
Eine kleine Korrektur
Der Algorithmus ist ein wenig falsch, da er Zyklen im ersten Schritt erzeugen kann.
Wir müssen ihn deshalb etwas modifizieren:
•
•
•
Es kann passieren, dass hier „1“ und „3“ einen Loop bilden, was nicht erlaubt
ist (keine eindeutige Wurzel mehr)
Korrekt wäre, das entweder „1“ oder „3“ einen „Selbstloop“ hat
Wir machen folgendes um dies zu verhindern:
o Wir Graften nach dem Conditional Grafting im Ersten Schritt keine
Sterne mehr im Unconditional Grafting
o Wir Graften nun also nur noch Einzelknoten oder selbstloops, aber
keine Sterne mit Sternen mehr
o Diese Problem tritt in den weiteren Iterationsschritten nicht mehr auf
46
Vorlesung 10.1:
Ein optimaler paralleler Algorithmus zur Lösung des 2D Convex Hull Problems
Problemstellung:
• Eingabe: Eine Menge S von Punkten (p1…pn)
• Ausgabe: Die Konvexe Hülle CH(S) dieser Punkte
o Die Konvexe Hülle ist das kleinste Polygon das alle Punkte aus S
enthält
o Jeder Knoten aus CH(S) wird Extrempunkt genannt. Die Konvexe Hülle
ist also eine sortierte Liste von Extrempunkten
47
•
Die Magentafarbene Hülle ist auch eine konvexe Hülle um die Punkte herum,
aber nicht die kleinste ! Die kleinste ist die rote Hülle.
•
•
Pmin ist der Punkt mit der kleinsten x Koordinate
Pmax ist der Punkt mir der größten x Koordinate
•
Diese Zwei Punkte teilen die Konvexe Hülle in eine obere Hülle und eine
untere.
•
•
•
•
Die Linie Pmin nach Pmax teilt die Konvexe Hülle in die zwei Teile
Sei x(p) bzw. y(p) jeweils die x bzw. y Koordinaten des Punktes p
Sei L eine Linie mit y=ax+b und eine Punkt q = (α,β)
Wir sagen, q ist unter L, wenn β < aα + b; q ist dann über L, wenn β > aα + b
•
Bei einem gegeben Set S von n Punkten könnne wir Pmin und Pmax in O(n) Zeit
finden. Die Punkte über und unter der Linie von Pmin und Pmax können wir
ebenfalls in O(n) Zeit finden
•
Wir können nun die obere Hülle UH(S) berechnen bzw, die untere Hülle LH(S)
•
Am Ende kann man die beiden Teilhüllen wieder zur konvexen Hüllen
zusammenfügen.
Komplexität beim sequentiellen Algorithmus
Zeit:
θ(n log n)
Man kann diese untere Grenze Zeigen, wenn man zeigen kann, dass das Convex
Hull Problem äquivalent zum Sortieren ist
Ö Wir müssen einen O(n log n) work Algorithmus entwerfen um optimal zu sein
48
Berechnung der oberen Hülle (UH(S))
Der Algorithmus für die untere Hülle ist Äquivalent
Eine Linie L ist eine Tangent eines Polygons P, wenn alle Knoten von P auf der
gleichen Seite von L sind
Divide an Conquer Algorithmus
•
•
•
•
Es gibt zwei Phasen: Top-Down und dann Bottom-Up
Zuerst sortieren wir die Punkte nach den x-Koordinaten
In der Top-Down Phase unterteilen wir das Set S rekursiv in zwei Teile und
berechnen die Konvexe Hülle, wenn das Teilproblem klein genug ist
In der Bottom-Up Phase mergen wir die Teilhüllen paarweise um am Ende die
ober Hülle zu erhalten (Strategie entsprich dem sequentiellen Mergesort)
Zusammenfügen zweier oberer Teilhüllen
49
Hauptproblem ist das Berechnen einer gemeinsamen Tangente.
• Um das Problem am Ende in O(n log n) work zu lösen, benötigen wir einen
Algorithmus, der das Mergen in O(1) Zeit erledigt.
• Wir finden zunächst eine Tangente von einem willkürlichen Punkt aus UH(S1)
zu UH(S2)
•
•
•
•
Wir haben nun die Tangente ri nach qri
Nehmen wir nun eine zweite Linie von ri zu irgendeinem Punkt ql in UH(S2)
Wir versuchen nun herauszufinden, ob qri oberhalb oder unterhalb der Linie
von ri nach ql liegt. Dies können wir in O(1) lösen.
Wenn die Nachbarknoten von ql (ql-1 und ql+1) nicht beide auf der gleichen
Seite der Linie ri nach ql liegen, dann ist qri oberhalb von ql
Zum Findem von qri benutzen wir den „Parallele Suche“ Algorithmus
•
•
Wir teilen Das Problem in P+1 Teile, wenn wir P Prozessoren verwenden.
Nach jeder Iteration bleibt 1/(p+1)-stel Teil übrig in dem qri liegt Æ Rekursiv
Wir benötigen das CREW PRAM Modell
Vorlesung 10.2:
•
Wir haben nun die Linie ri qri jetzt können wir feststellen ob u (ein Punkt der
Common Tangente) oberhalb oder unterhalb der Linie riqri liegt und zwar in
O(1)
50
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Nehmen wir an UH(S1) bestehe aus t Punkten
Nehmen wir an UH(S2) bestehe aus s Punkten
Wir teilen nun die t bzw s Punkt in SQRT(t) bzw SQRT(s) intervalle
Wir machen nun folgende parallele Suche mit SQRT(t)*SQRT(s) Prozessoren
Für jedes Boundary Element ri aus UH(S1) berechnen wir das zugehörige qri.
(Wurde vorhin erklärt) mit SQRT(s) Prozessoren geht das in O(1) Zeit
Wir haben nun damit einen Bereich bestimmt in dem u liegen muss (zwischen
rj und rk)
Der Bereich rjrk ist SQRT(t) groß
Die Berechnung dauert O(1) und benötigt SQRT(s)*SQRT(t) = O(n)
Prozessoren
Auf der der anderen Seite geht das Ganze analog
Wir erhalten nun also zwei Bereiche sowohl in UH(S1) als auch in UH(S2) in
denen u und v liegen müssen.
Nun werden alle möglichen Kombinationen von Linien durch die Elemente
beider Seiten in den Bereichen analysiert Æ Eine davon ist dann letztendlich
die „Common Tangente“
Es gibt also SQRT(s)*SQRT(t)=O(n) Linien deshalb können wir das Ganze in
O(1) Zeit berechnen wenn wir O(n) Prozessoren verwenden
Alle Punkte liegen unterhalb der Common Tangente (eigentlich klar, weil das
ist die Definition der Common Tangente)
Aber woher weiss der Algorithmus nun welches die Common Tangente ist
Eine Linie ist dann die Common Tangente, wenn die Nachbarn der zu
untersuchenden 2 Punkte (linke und rechte Teil Konvex-Hüll) beide unterhalb
dieser Linie liegen. O(n) Linien können wir nun wieder in O(1) Zeit berechnen
und in O(n) Work
51
•
Die Punkte in der mitte unterhalb der Common Tangente müssen zum
vollständigen Verschmelzen noch entfernt werden (reject). Dies kann in O(1)
Zeit durchgeführt werden.
Zusammenfassend:
•
•
•
•
•
Das ganze Problem wird mit Hilfe von Divide an Conquer gelöst
Die Tiefe der Rekursion beträgt O(log n)
Das Merging der Teilhüllen geht in jedem Rekursionslevel in O(1) bei O(n)
Prozessoren und O(n) work
Also ist die Gesamtzeit O(log n) und die Work O(n log n)
Benötigt wird das CREW Modell (wegen der parallelen Suche). Es gibt auch
ein Modell EREW, aber das ist wohl komliziert.
Intersection von Half-Planes (Schnitt von Halbebenen)
• Sei L eine Linie mit y=ax+b
• Seien H+(L) und H-(L) die zwei Halbebenen über und unterhalb von L
• In H+(L) sind alle Punkte (α,β) sodass gilt β≥aα+b
• In H-(L) sind alle Punkte (α,β) sodass gilt β≤aα+b
• Intuitiv ist H+(L) ein Set von Punkten über oder auf L
• Intuitiv ist H-(L) ein Set von Punkten unter oder auf L
•
•
Schneidet man nun verschiedene Halbebenen erhält man eine konvexe
Fläche die aber nicht vollständig geschlossen sein muss (rechtes Bild)
Wir wollen also nun diese Grenzen bzw die zugehörigen Schnittpunkte
berechnen
Bezeichnung: links: Primal Space, rechts: Dual Space
•
Sei T eine Funktion die einen Punkt p=(a,b) in eine Linie T(p); definiert durch
y=ax+b, transformiert.
52
•
•
•
Die Funktion T ist umkehrbar, sodass sie bei Eingabe einer Linie L (y=ax+b)
einen Punkt T(L)=(-a,b) erzeugt.
Wichtige Eigenschaft:
o Ein Punkt p ist unter einer Linie dann und nur dann, wennT(p) unterhalb
des Punktes T(L) ist
o Betrachten wir ein Set von Linie L1,…,Ln und die Region C ergibt sich
durch den Schnitt aller H+(Li). Die Region C besteht nun aus allen
Punkten die über allen Linien sind.
In der Transformierten Domain (rechts), besteht
aus allen Linien über den Punkten T(Li).
(Dies wurde in der Vorlesung irgendwie gar nicht erklärt !?)
•
•
In unserem DualSpace berechnen wir nun die konvexe Hülle
Die daraus entstehenden Linien transformieren wir wieder zurück in Punkte
und diese Punkte definieren die Schnittfläche.
Zusammenfassend:
•
•
•
•
•
Um den Schnitt zweier Halbebenen zu berechnen, konvertieren wir zunächst
die Linien in „Dualpoints“
Dann berechnen wir die Konvexe Hülle dieser Punkte
Letztendlich bekommen wir dann die Extrempunkte des Halbebenenschnitts
durch konvertieren der Liniensegmente der konvexen Hülle in Punkte
Die Transformation dauert O(1) Zeit, wenn wir jeder Linie einen Prozessor
zuweisen
Die Konstruktion der konvexen Hülle dauert O(log n) Zeit und O(n log n) work
auf einem CREW PRAM
Mit Hilfe des Konvex Hull Algorithmus kann man auch das sogenannte „2
Variable Linear Programming Problem“ lösen.
Das Problem ist folgendermaßen definiert
53
•
•
•
•
•
•
Jedes Constraint ist eine Halbeben. Die gesuchte Region ist ein Set von
Punkten die alle Constraints erfüllt.
Die Lösung ist es einen Punkt in dieser Region zu finden, der die Funktion
(Objective Function) minimiert.
Diese wird an einem bestimmten Extrempunkt der Region minimiert
Wir können nun alle O(n) Extrempunkte der Region mit Hilfe des
Halbebenenschnitt Algorithmus finden.
Damit können wir denjenigen Extrempunkt finden der die Funktion minimiert.
Der Algorithmus benötigt O(log n) zeit und O(n log n) work auf einem CREW
PRAM.
Vorlesung 11.1:
Die Klasse NC und wann ist ei9n Problem parallelisierbar ?
Definition: Ein Poblem ist parallelisierbar, wenn es sehr schnell (in
Polylogaritmischer Zeit, also O(logkn)) auf einer akzeptablem Menge von
Prozessoren (O(nc)) gelöst werden kann. (c und k sind Konstanten und n die
Eingabegröße)
Die Klasse NC (Nick’s Class) zur Ehren von Nick Pipenger:
Die Klasser NC besteht aus allen Problemn die auf einem PRAM in
Polylogarithmischer Zeit mit polynomiell vielen Prozessoren, gelöst werden können:
Definition: Die Klasse NC ist also definiert als ein Set alle Sprachen L, die
• Alle Eingaben von Größe n haben
• L kann auf einem PRAM in O(logkn) Zeit erkannt werden
Die Klassen NC, P und NP
•
P war die Klasse aller Probleme, die in polynomieller Zeit auf einer
deterministischen Toruingmaschine gelöst werden können
•
Offensichtlich ist NC eine Teilmenge von P, es ist aber nicht klar, ob NC auch
eine Teilmenge von P ist, also beide Mengen gleich sind. (Die meisten Leute
glauben, das sie nicht gleich sind.)
•
Wenn die beiden Klassen nicht gleich sind, dann muss es Probleme aus P
geben, die sich zwar auf einer RAM gut lösen lassen, aber nicht auf einem
PRAM
54
•
Die Klasse der P-Vollständigen Probleme sind besonders gute Kandidaten zur
Prüfung ob sie in NC liegen.
•
Das Problem ist das gleiche wie bei den Klassen P und NP
•
Wenn jemand einen polynomiellen Algorithmus für ein NP-vollständiges
Problem findet, dann können wir alle NP-Vollständigen Probleme in
polynomieller Zeit lösen.
•
Genau gleich ist das zwischen NC und P, wenn man einen
polylogarithmischen Algorithmus für ein P-Vollständiges findet, dann können
wir alle P-Vollständigen Probleme in polylogarithmischer Zeit lösen.
•
•
•
NP Æ in nichtpolynomieller Zeit auf RAM lösbar
PÆ in polynomieller Zeit auf RAM lösbar
NCÆ in polylogarithmischer Zeit auf PRAM lösbar
•
Wie können wir nun prüfen, ob ein Problem P-Vollständig ist ?
Definition von NC-Reduzierbar
o Seien L1 und L2 zwei Sprachen
o L1 ist NC-reduzierbar auf L2 wenn,
ƒ Es einen NC Algorithmus gibt, der einen beliebigen Input u1 für
L1 in eine Eingabe u2 für L2 umwandelt, sodass
ƒ u1 € L1, dann und nur dann wenn u2 € L2
Definition von P-Vollständigkeit
Eine Sprache L ist P-Vollständig, wenn
• L€P
• Jede Sprache in P NC-Reduzierbar ist auf L
Die nächste Frage ist, ob es überhaupt ein P-Vollständiges Problem gibt.
55
Das Circuit Value Problem (CVP)
• Wir haben einen Boolschen Schaltkreis be idem „Not“, „Or“ und „And“ erlaubt
sind. „Or“ und „And“ haben jeweils zwei Eingabewerte, „Not“ hat nur Einen
•
Problem: Den Ausgabewert für eine bestimmt Eingabe zu finden
•
Unser Boolscher Schaltkreis ist also definiert durch eine Menge von Gattern
•
Jedes Gi aus C ist dann
o Entweder ein Eingabewert, oder
o
o mit j,k < i
CVP ist P-Vollständig ?
Wir müssen zunächst prüfen ob CVP überhaupt in P liegt
• Die ist eigentlich klar, denn wenn wir ein n-Gate CVP nehmen, dann könne wir
die Gatter sequentiell in O(n) Zeit auswerten.
Nun müssen wir prüfen, ob eine beliebige Sprache L € P NC-Reduzierbar ist auf das
CVP
Wir stellen dazu nun einen NC Algorithmus zur Verfügung, der eine willkürliche
Instanz IL von L nimmt, diese auf eine Instanz ICVP von CVP abbildet und IL dann
„Yes“ antworten lässt, wenn ICVP eine „1“ als Wert trägt.
56
Turing Maschine
•
Wenn L€P, dann existiert eine „Determinischte Einband Touringmaschine“ M
die L in polynomieller Zeit T(n) akzeptiert für eine Eingabemenge n.
•
Wir können annehmen, dass die Eingabebits aufeinanderfolgend auf dem
Band liegen, der Rest des Bandes ist leer. Der I/O Kopf der Touringmaschine
scannt am Anfang Zelle 1 des Bandes und schreibt nach T(n) Zeit das
Ergebnis wieder in Zelle 1.
•
Q sei die endliche Menge der Zustände Q={q1,…,qs} der Touringmaschine M.
q1 ist der Startzustand.
•
Sei Σ(a1,…,am) das Band-Alphabet
•
Die Überführungsfunktion ist:
•
Wir werden nun zeigen, wie man einen boolschen Schaltkreis C konstruiert
,so dass der Wert von C „1“ ist, dann und nur dann, wenn M L akzeptiert.
•
Zu Beachten ist, das M nur auf T(n) Zellen in T(n) Zeit zugreifen kann. Die
Indizes i sind somit zwischen 1 und T(n).
•
Die Zeitschritte t sind zwischen 0 und T(n)
•
Es gibt nur s Zustände in M, weil alle Zustände qj zwischen q1 und qs liegen.
Hilfsfunktionen:
Der Schaltkreis C wird durch die folgenden boolschen Funktionen definiert:
• H(i,t), sodass
o H(i,t)=1, nur wenn der Kopf gerade die Zelle i zum Zeitpunkt t scannt
• C(i,j,t), sodass
o C(i,j,t)=1,nur wenn die Zelle i, das Zeichen aj zum Zeitpunkt t enthält
• S(k,t), sodass
o S(k,t)=1, nur wenn der Zustand von M qk ist zum Zeitpunkt t.
Vorlesung 11.2:
•
Unser Schaltkreis besteht aus T(n) Levels
57
•
•
•
Für jeden Zeitschritt der Touringmaschine M, emuliert dieser Level das
Verhalten der Touringmaschine M.
Level l enthält die Gates, die die Boolschen-Funktionen H(i,l), C(i,j,l),S(k,l)
berechnen für i zwischen 1 und T(n)
Anmerkung: Wir wissen nicht genau wie M die Sprache L erkennt.Aber in
unserem Schaltkreis C halten wir alle mögliche Schritte von M in jedem Level
fest.
•
Die Anzahl der Gatter in jedem Level i ist T(n)
•
Zum Zeitpunkt t=0 gilt folgendes:
o H(i,0)=1, wenn i=1 ist, 0 sonst
o C(i,j,0)=1, wenn Zelle i zu Anfang aj enthält
o S(k,0)=1, wenn k=1, 0 sonst
Nun definieren wir uns die Funktionen in Abhängigkeit aller möglichen Eingaben und
I/O Kopfpositionen, also:
Für die Funktion H
Es gibt zwei Möglichkeiten auf die Position i zu kommen, und zwar von i-1 indem
man nach rechts geht, oder von i+1 indem man anschließen nach links geht usw.
Komplexität zum Erstellen:
Zeit: O(1)
Work: O(T(n)²)
Für die Funktion C:
58
Komplexität zum Erstellen:
Zeit: O(1)
Work: O(T(n)²)
und für die Funktion S:
Komplexität zum Erstellen:
Zeit: O(log n)
Work: O(T(n)²)
Den Endwert unseres Schaltkreise produziert die Funktion:
•
Es ist nun klar, dass unser Schaltkreis von einem NC Algorithmus konstruiert
werden kann, weil T(n) polynomiell in n ist.
•
Die Ausgabe unseres Schaltkreises ist nur dann „1“, wenn M die Sprache L
erkennt.
•
Weil L eine beliebige Sprache aus P ist, folgt daraus, dass CVP P-Vollständig
ist
Implikationen:
•
•
TRANSITIVITÄT: Wenn L1 NC reduzierbar auf L2 ist und L2 NC reduzierbar
auf L3 ist, dann ist L1 NC reduzierbar auf L3
Wenn L ein P-Vollständiges Problem ist und L in NC liegt, dann gilt P=NC.
(offenes Problem)
Prüfung anderer P-Vollständiger Probleme:
•
•
Sei eine Sprache L P-Vollständig. Wenn nun L NC reduzierbar auf eine
andere Sprache L’ aus P ist. Dann ist auch L’ P-Vollständig.
(genau das benötigt man um auch andere Probleme auf P-Volständigkeit zu
prüfen)
o Wenn wir also zB das CVP NC reduzieren können auf ein anderes
Problem in P, dann ist auch dieses P-Vollständig.
Liste P-Vollständiger Probleme:
(nicht polylogarithmisch lösbar, also nicht in NC)
„Ordered depth-first search“
• Gegeben sei ein gerichteter Graph G=(V,E) in Form einer Adjazenzmatrix und
• gegeben seihen weiterhin drei Knoten s,u,v.
• Wir wollen nun wissen ob u vor v besucht wurde, wenn wir bei s starten.
„Maximum Flow“
• Gegeben sei ein Netzwerk mit gewichteten Kanten und zwei herausragenden
Knoten (nämlich der Quelle und der Senke)
59
•
•
Problem: Festzustellen ob der „Maximum Flow“ ungerade ist
Applet unter: http://riot.ieor.berkeley.edu/riot/Applications/graal-flow/graal.html
„Linear inequalities“
• Gegeben sei eine n x m Matrix A und ein n-dimensionaler Vektor b.Alle
Einträge sind ganze Zahlen.
• Problem: Gibt es einen rationalen Vektor x, sodass gilt Ax ≤ b
60
Fragenkatalog:
1.
2.
3.
4.
5.
6.
7.
8.
9.
Was ist die Working-Komplexität?
Wann ist ein paralleler Algorithmus Effizient?
Wann ist ein Algorithmus Work-Optimal bzw Work-Tine-Optimal?
Was ist ein Parallelrechner?
Welchen Sinn macht Parallelrechnen ? Wo liegen die Grenzen?
Was sind die Vorteile/Probleme von Parallelrechnern?
Erkläre das PRAM Modell?
Welche Parallelcomputer-Modelle gibt es?
Was sind die wichtigsten Design-Aspekte für Network SIMD Modelle? Erkläre
diese 3?
10. Welche Netzwerkmodelle gibt es? (Mesh, Hypercube)
11. Welche verschiedenen PRAM Modelle gibt es bzgl. des Speicherzugriffs?
12. Sind diese untereinander kompatibel?
13. Wann ist ein solches Modell schwächer als ein Anderes? (Erst Zeit, dann
Work)
14. Algorithmus „Präfixsumme“: Was berechnet dieser? Wie funktioniert er?
Komplexität?
15. Algorithmus „Präfixsumme“: Es gibt eine rekursive Variante, wie funktioniert
diese?
16. Algorithmus „Pointer Jumping“: Was berechnet dieser? Für was kann man den
Algorithmus gut brauchen? Welche Komplexität hat er?
17. Was versteht man unter der „Partitioning und Merging Strategie“?
Komplexität?
18. 3 Algorithmen zur „Berechnung des Maximums“: Welche verschiedenen
Lösungsansätze gibt es? Welche Strategien verfolgen diese? Was ist
Accelerated Cascading? Komplexitäten?
19. 3 Algorithmen zum „List Ranking“: Welche verschiedenen Algorithmen zum
List Ranking gibt es? Welche Strategie verfolgen diese jeweils? Kompexität?
20. Was ist die „Euler Tour Technik“? Für was benötigt man diese? Was ist ein
Eulerkreis? Was ist das besondere im Parallelen?
21. Wir haben für die Euler-Tour-Technik auch eine Umkehrung kennengelernt,
„Rooting a Tree“ – Wie funktioniert diese Technik? Was ist Tree Contraction?
Wie funktioniert die Rake-Operation bzw. der Rake Algorithmus?
22. Algorithmus zur „Auswertung eines Ausdruckes“, dargestellt als Baum: Wie
funktioniert das?
23. Algorithmus „Parallele Suche in einem sortierten Array“: Welche Techniken
werden hier angewandt? Welche Mergingverfahren haben wir dabei
kennengelernt?
24. Wie kann man effizient sortieren? (vorheriger Mergingalgorithmus)
25. Parallele Graphen-Algorithmen: Was kann man verbundene Komponenten
erkennen? Was ist ein Pseudo-Forrest?
26. Welche Eingabemöglichkeiten gibt es für Graphen? (Adjanzenzmatrix,
Kantenliste)
27. Was ist ein dichter Graph, was ist ein lichter Graph? Wann nimmt man
welchen Algorithmus?
28. Was ist Grafting? Wie kann man einen Stern erkennen? Was ist unconditonal
Grafting, was ist conditional Grafting?
61
29. Was ist das 2D Konvexe-Hülle Problem? Kennen Sie einen optimalen
parallelen Algorithmus zur Lösung? Was versteht man unter der Upper-Hull
bzw. Lower-Hull? Wieso teilt man die Hülle? Wie erhält man die Teilhüllen?
30. Was ist die Common Tangente?
31. Was ist Halbebenen-Schnitt? Wie funktioniert der Algorithmus? Was versteht
man unter „Primal Space“ und „Dual Space“?
32. Was ist das „2 Variable Linear Programming Problem“? Wie kann man dieses
mit Hilfe des „Convex-Hull“ Algorithmus lösen?
33. Wann ist ein Problem parallelisierbar? (Definition)
34. Was ist die Klasse NC, wie ist sie definiert?
35. Parallelen zum P/NP Problem?
36. Was heisst NC Reduzierbarkeit?
37. Was ist P-Vollständigkeit?
38. Was versteht man unter dem „Circuit Value Problem“ CVP? Warum ist dieses
P-Vollständig und wie weißt man das nach? (Touring Maschine)
39. Welche anderen P-Vollständigen Probleme wurden angesprochen?
62
Herunterladen