1. Motivation 2. Verbundene Komponenten 3. Minimal spannende Bäume 1. Kruskals Algorithmus 2. Sollins Algorithmus 4. Kürzeste Pfade von einem Ausgangsknoten ausgehend 5. Zusammenfassung Minimal spannende Bäume Problemstellung - siehe Kruskals Algorithmus Finden einer Menge von Kanten, die alle Knoten eines gewichteten und ungerichteten Graphens mit minimaler Summe der Kantengewichte verbindet 4 Beispielgraph A 5 2 B C 6 3 D 3 7 E F 4 1 5 G 1 H 1 2 I Sequentieller Algorithmus von Sollin (1/2) Vorgehensweise - Ähnliche Vorgehensweise wie der Algorithmus von Hirschberg - Knoten sind zunächst ebenfalls jeweils ein Teilbaum - Je Iteration wird für jeden Teilbaum die Kante mit geringsten Gewicht zu einem anderen Teilbaum gesucht - Falls kein Zyklus entsteht werden Teilbäume über die Kante verbunden 4 Kantenwahl in der 1. Iteration A 5 4 A C H 3 1 3 1 7 G D I 3 F D 3 E - Kantenwahl nicht deterministisch - Abhängig von der Laufzeit und Datenstruktur E F 4 H 1 5 G 1 1 C 6 B 2 B 1 2 I Sequentieller Algorithmus von Sollin (2/2) 4 Kantenwahl in der 2. Iteration A 4 A B 2 C 1 1 3 G 1 D I 4 2 E 4 A B G 1 1 5 3 1 H C I D 2 3 F E E F 3 Ein möglicher minimal Spannender Baum D 3 H 1 5 7 G F 2 C 6 H 1 3 5 B 1 2 I Parallelisierung des Algorithmus von Sollin (1/2) Vorgehensweise - Iteration können nicht parallelisiert werden, lediglich die einzelnen Schleifen Parallele Version ist der sequentiellen sehr ähnlich - in paralleler Version: Vorverteilung - in paralleler Version: Vorverteilung Parallelisierung des Algorithmus von Sollin (2/2) Verwendete Operationen - Find(v): Gibt Namen der Menge wieder, in der sich ein Knoten befindet - Union(v,w): Zusammenfassen der Mengen v und w zu einer Menge - in paralleler Version: Vorverteilung - in paralleler Version: Vorverteilung - Aber: Sperren der Teilbäume nötig, um exklusiven Zugriff auf Teilbäume für Prozessoren zu erhalten Laufzeit des parallelen Algorithmus auf dem UMA-Multiprozessormodell (1/2) Iteration - Verminderung der Anzahl Teilbäume um mind. Faktor 2 je Iteration, da jeder Teilbaum mit mind. einem weiteren Teilbaum verbunden wird max. logn Iterationen nötig Union- und FindOperationen - langsam wachsende Zeitkomplexität Θ (log* n) For-Schleifen in den Iterationen - Initialisierung (9-11): Θ ( n / p ) können vereinfachend als Konstanten angenommen werden Durch Vorverteilung der n Teilbäume auf die p Prozessoren 2 - Suche der Kante mit geringstem Gewicht (12-19): Θ ( n / p ) Es können max. n–1 Kanten von n Knoten abgehen 2 Somit Vorverteilung der max. n nötigen Untersuchungen auf die p Prozessoren Laufzeit des parallelen Algorithmus auf dem UMA-Multiprozessormodell (2/2) Letzte For-Schleife in den Iterationen - Verbinden der Teilbäume (20-28): Θ ( n) Vorverteilung der n Teilbäume auf die p Prozessoren ABER Worst Case: Zum Sperren muss ein Prozessor auf alle anderen p-1 Prozessoren warten - Zusätzlich in jeder For-Schleife: Θ ( p ) Datenstruktur muss für Vorverteilung in den Schleifen max. p-Mal gesperrt werden Resultierende Zeitkomplexität 2 2 Θ (log n) X Θ ( n / p n / p n 3 p) = Θ (log n *(n / p n / p n p)) Gute Beschleunigung bei p < < n 1. Motivation 2. Verbundene Komponenten 3. Minimal spannende Bäume 4. 1. Kruskals Algorithmus 2. Sollins Algorithmus Kürzeste Pfade von einem Ausgangsknoten ausgehend 5. Zusammenfassung Kürzeste Pfade von einem Ausgangsknoten ausgehend Problemstellung Bestimmen der kürzesten Pfade eines Knotens zu allen anderen Knoten des gerichteten und gewichteten Graphens - Von Moore im Jahr 1959 entwickelt Moores Algorithmus - benötigt ein Distanzarray und eine Queue für abzuarbeitende Knoten - Pfade vom Ausgangsknoten haben zu Beginn das Gewicht ∞, außer zu sich selbst - Queue enthält initial lediglich den Ausgangsknoten B 4 Beispielgraph A D 1 2 1 3 C E Sequentieller Algorithmus von Moore (1/2) Distanzarray Ausgangssituation Vorgehensweise In den Iterationen A 0 B ∞ C ∞ D ∞ E ∞ Queue A - Löschen des ersten Knoten in der Queue - Überprüfung, ob bisherige Distanzen zu den Nachbarknoten des gelöschten Knoten aktualisiert werden müssen: Distanz zum gelöschten Knoten + Distanz zwischen den beiden Knoten < Bisherige Distanz des Nachbarknotens - Einfügen der erreichbaren Knoten an das Ende der Queue, falls sie noch nicht in der Queue stehen und sich ihr Wert im Distanzarray verringert hat 1. Iteration B 4 A D 1 2 1 Distanzarray 3 C E A 0 B 4 C 1 D ∞ E ∞ Queue B C Sequentieller Algorithmus von Moore (2/2) 2. Iteration B 4 A D 1 2 1 3. Iteration Distanzarray 3 C B 4 A E 0 B 4 C 1 D 7 E ∞ Distanzarray 3 D 1 2 1 A C E A 0 B 3 C 1 D 7 E ∞ Queue C D Queue D B ... Distanzarray Letzte Iteration A 0 B 3 C 1 D 6 E 7 Queue E Keine abgehenden Kanten Algorithmus terminiert Parallelisierung des Algorithmus Möglichkeiten 1. Parallele Untersuchung der abgehenden Kanten des gelöschten Knotens - Eingeschränkt parallel wg. begrenzten Anzahl der abgehenden Kanten 2. Parallele Bearbeitung der in der Queue befindlichen Knoten + Entstehende Aufgaben für die einzelnen Prozessoren größer als bei 1. Naive Vorgehensweise Auftretende Probleme - Gleichzeitige Initialisierung der Knoten mit der Distanz ∞ durch Vorverteilung - Beginn der parallelen Bearbeitung der in der Queue befindlichen Knoten, bis die Queue leer ist (1) Problem des (vorzeitigen) Stoppens von Prozessoren, da Queue (momentan) leer (2) Konflikte bei der gleichzeitigen Aktualisierung des Distanzarrays (3) Konflikte beim Einfügen und Entnehmen aus der Queue durch die Prozessoren Lösungsmöglichkeiten für die Probleme zu (1) - Einführung der Variablen halt (global) und waiting(i) (für jeden Prozessor) - Falls Prozessor i keinen zu bearbeitenden Knoten in der Queue findet, wird waiting(i) auf true gesetzt - Falls Prozessor 1 keinen zu bearbeitenden Knoten in der Queue findet und alle Variablen waiting(i) auf true stehen, wird halt auf true gestellt und alle Prozesse können terminieren zu (2) - Einführung eines Sperrmechanismus für die Variable distance(v), um einem Prozessor alleinigen Zugriff und somit die Aktualisierung der Variable zu ermöglichen zu (3) - Einführung eines Sperrmechanismus für die Queue, so dass nur ein Prozessor exklusiven Zugriff besitzt ABER: Beeinträchtigung der Geschwindigkeitsbeschleunigung durch gegenseitiges Blockieren der Prozessoren beim Einfügen und Entnehmen Lösung: Datenstruktur Linked Array Linked Array (1/3) Ansatz - Entnehmen und Einfügen werden separat mit jeweils einem Array abgebildet - Rollen zwischen den benötigten Arrays wechseln in jeder Iteration Array zum Einfügen in die Queue - Je Iteration besitzt jeder der p Prozessoren einen Bereich (in einem Array), in den er zu untersuchende Knoten einstellen kann: X11 ... X21 X31 ... ... X41 ... ... Bereich für P1 Bereich für P2 Bereich für P3 Bereich für P4 . . . - Am Ende der Iteration wird der Bereich mit p Verweisen auf den nächsten Bereich aufgefüllt: X11 X12 X13 ... X1N V1 V2 V3 ... X21 X22 X23 ... Linked Array (2/3) Array zur Entnahme aus der Queue - In der nächsten Iteration kommt es nun zum Rollentausch - Jeder Prozessor entnimmt nun aus diesem Array den p-ten Knoten und bearbeitet ihn - Mit Hilfe der Verweise arbeiten sich die Prozessoren durch das Array, bis Verweis außerhalb des Arrays gefunden wird Prozessor hat Arbeit in der entsprechenden Iteration beendet und kann stoppen - Beispiel mit 4 Prozessoren: P1 P2 P3 ... P1 P2 P3 P4 P1 X11 X12 X13 ... X1N V1 V2 V3 V4 ... X21 X22 X23 ... Linked Array (3/3) Vorteile - Keine Konflikte beim Entnehmen und Einfügen in die Queue unter den Prozessoren Bessere Beschleunigung durch die Parallelisierung - Gleichmäßige Lastverteilung zwischen den Prozessoren Nachteile Falls es keinen separaten Prozessor zum Einfügen in die Queue gibt: - Knoten können im Array zur Entnahme aus der Queue doppelt enthalten sein Weiterhin Sperrmechanismus für die Variable distance(v) nötig - Problem der Größe der Einfügebereiche für die Prozessoren Benötigtes Array muss erheblich größer dimensioniert werden Maximal: p x (n + p) 1. Motivation 2. Verbundene Komponenten 3. Minimal spannende Bäume 1. Kruskals Algorithmus 2. Sollins Algorithmus 4. Kürzeste Pfade von einem Ausgangsknoten ausgehend 5. Zusammenfassung Zusammenfassung Motivation - Graphen bilden mathematisch Probleme der Realität ab - Parallelisierung sinnvoll, um Problemlösung zu ermöglichen oder zu beschleunigen Verbundene Komponenten - Finden der Knoten, die zu jeweils einer Komponente gehören - Viele Algorithmen für Parallelrechnermodelle basieren auf Hirschbergs Algorithmus Minimal spannende Bäume - Finden einer Menge von Kanten, die alle Knoten eines gewichteten und ungerichteten Graphens mit minimaler Summe der Kantengewichte verbindet - Vorgestellte Algorithmen: Kruskal und Sollin, da parallelisierbar - Parallelisierung durch einen Heap bzw. parallele Schleifendurchläufe Kürzeste Pfade von einem - Bestimmung der kürzesten Pfade eines Knotens zu allen anderen Knoten des Ausgangsknoten gerichteten und gewichteten Graphens - Parallelisierung des Algorithmus birgt einige Probleme in sich - Größere Beschleunigungsmöglichkeiten durch Datenstruktur Linked Array