Geometrische Algorithmen Bin Hu Algorithmen und Datenstrukturen 2 Arbeitsbereich für Algorithmen und Datenstrukturen Institut für Computergraphik und Algorithmen Technische Universität Wien
Einführung Einführung Motivation Effiziente Algorithmen, die aufgrund geometrischer Daten (v.a. Koordinaten) im d-dimensionalen Raum gewisse Eigenschaften ausnutzen Anwendung Bildverarbeitung Computergraphik Chip Design...
Teil I Scan-Line Prinzip
Scan-Line Prinzip Grundlagen Scan-Line Prinzip Idee Gegeben eine Menge von Objekten in einem 2D Raum Vertikale Linie fegt v.l.n.r. über die Objektmenge und betrachtet nur Objekte, die gegenwärtig relevant sind Statisches 2D Problem dynamisches 1D Problem Aufteilung der Objekte bezüglich Scanline L Tote Objekte liegen vollständig links von L Aktive Objekte werden gegenwärtig von L geschnitten Inaktive Objekte liegen rechts von L, werden zukünftig von L geschnitten
Scan-Line für Schnitt iso-orientierter Liniensegmente Einführung Schnitt iso-orientierter Liniensegmente Aufgabenstellung Gegeben: n horizontale und vertikale Liniensegmente s 1,..., s n Gesucht: Alle Paare sich schneidender Segmente F H B C A E G D
Scan-Line für Schnitt iso-orientierter Liniensegmente Einführung Vereinfachte Annahme Alle Anfangs- und Endpunkte horizontaler Segmenten und alle vertikalen Segmente haben paarweise verschiedene x-koordinaten Naives Verfahren Alle Paare von Liniensegmenten auf Schnitt testen. Laufzeit: O(n 2 )
Scan-Line für Schnitt iso-orientierter Liniensegmente Algorithmus Scan-Line Verfahren Scan-Line L fegt v.l.n.r. über die Fläche und trifft auf die Liniensegmente. Mögliche Fälle: 1 Anfangspunkt eines horizontalen Segments s: s in L einfügen 2 Endpunkt eines horizontalen Segments s: s aus L löschen 3 Vertikales Segment s: s mit allen Liniensegmenten in L auf Schnitt testen Bemerkung Scan-Line muss sich nicht kontinuierlich fortbewegen Es genügt, Haltepunkte bei relevanten Ereignissen zu setzen
Scan-Line für Schnitt iso-orientierter Liniensegmente Algorithmus Algorithmus 1 Scan-Line für iso-orientierte Liniensegmente 1: Q = Menge der Haltepunkte in aufsteigender x-reihenfolge; 2: L = ; // Menge der aktiven Segmente, nach y sortiert 3: solange (Q ) { 4: p = nächster Haltepunkt von Q; 5: falls (p Anfangspunkt eines h. Segments s) dann { 6: Füge s in L ein; 7: } sonst { 8: falls (p Endpunkt eines h. Segments s) dann { 9: Entferne s aus L; 10: } sonst { 11: // p ist x-wert eines v. Segments [(p, y u ), (p, y o )] 12: Für alle h. Segmente t aus L mit y-koord. zwischen [y u, y o ]: gebe (s, t) als sich schneidendes Paar aus; 13: } 14: } 15: }
Scan-Line für Schnitt iso-orientierter Liniensegmente Algorithmus Beispiel: B A D C E A A A A A D D E D D E E E 0 (A,B) (A,C) (C,D)
Scan-Line für Schnitt iso-orientierter Liniensegmente Algorithmus Realisierung von L? Benötigte Operationen: 1 Einfügen eines neuen Elements 2 Entfernen eines Elements 3 Bestimmen aller Elemente in [(p, y u ), (p, y o )] (Bereichsabfrage) Mögliche Datenstrukturen Balancierte Binärbäume (AVL, Rot-Schwarz, etc.) Randomisierte Skiplisten...
Scan-Line für Schnitt iso-orientierter Liniensegmente Analyse Analyse Bereichsabfrage: O(log n + r) mit r = Anzahl der Elemente zwischen [(p, y u ), (p, y o )] Gesamtlaufzeit: O(n log n + R) mit R = Anzahl der sich schneidenden Segmente
Scan-Line für Schnitt von allgemeinen Liniensegmenten Einführung Schnitt von allgemeinen Liniensegmenten Aufgabenstellung Gegeben: Menge S = {s 1,..., s n } von n Liniensegmenten in der Ebene Gesucht: Menge echter Schnittpunkte (Kreuzung von Segmenten, die keine Endpunkte sind) y x
Scan-Line für Schnitt von allgemeinen Liniensegmenten Einführung Vereinfachende Annahmen Kein Segment ist senkrecht Schnitt zweier Segmente ist leer oder genau ein Punkt Nie mehr als 2 Segmente schneiden sich in einem Punkt Alle Endpunkte und Schnittpunkte haben paarweise verschiedene x-koordinaten
Scan-Line für Schnitt von allgemeinen Liniensegmenten Einführung Beobachtungen Schneiden sich Segmente s i mit s j, dann... waren s i und s j Nachbarn unmittelbar vor dem Schnittpunkt Es genügt, nur benachbarte Segmente auf Schnitt zu testen vertauscht sich die Anordnung von s i und s j in L nach dem Schnittpunkt Schnittpunkte sind auch Ereignisse Sie werden während des Scans dynamisch zur Ereignisstruktur hinzugefügt
Scan-Line für Schnitt von allgemeinen Liniensegmenten Algorithmus Zu betrachende Ereignisse Anfang eines Segments Ende eines Segments Schnitt zweier Segmente Verwendete Datenstrukturen Ereignisstruktur ES: speichert Ereignisse, aufsteigend nach x-koordinaten sortiert Initialisierung: Anfangs- und Endpunkte aller Segmente Scan-Line-Status Struktur SSS: speichert die aktiven Segmente, nach y-koordinaten sortiert Initialisierung: Leere Menge
Scan-Line für Schnitt von allgemeinen Liniensegmenten Algorithmus 40 KAPITEL 3. GEOMETRISCHE ALGORITHMEN Algorithmus 14 Algorithmus für das Segment-Schnitt Problem in allgemeiner Lage Initialisiere ES und SSS; Sortiere die 2n Endpunkte aufsteigend nach x-koordinate; Speichere resultierende Ereignisse in ES ; solange ES nicht leer { E = ES.NächstesEreignis(); falls E ist Segment Anfang dann { SSS.FügeEin(E.Segment); VS = SSS.Vorg(E.Segment); E = TesteSchnittErzeugeEreignis(E,VS); falls E dann { ES.FügeEin(E ); } NS = SSS.Nachf(E.Segment); E = TesteSchnittErzeugeEreignis(E,NS); falls E dann { ES.FügeEin(E ); } } falls E ist Segment Ende dann { VS = SSS.Vorg(E.Segment); NS = SSS.Nachf(E.Segment); SSS.Entferne(E.Segment); E = TesteSchnittErzeugeEreignis(VS,NS) falls E dann { ES.FügeEin(E ); } } falls E ist Schnittpunkt dann { Gib E.SegmentO und E.SegmentU aus; SSS.Vertausche(E.SegmentO,E.SegmentU); VS= SSS.Vorg(E.SegmentU); E =TesteSchnittErzeugeEreignis(E.SegmentU,VS); falls E dann { ES.FügeEin(E ); } NS = SSS.Nachf(E.SegmentO); E = TesteSchnittErzeugeEreignis(E.SegmentO,NS); falls E dann { ES.FügeEin(E ); } } }
Scan-Line für Schnitt von allgemeinen Liniensegmenten Algorithmus Algorithmus 2 Scan-Line für allgemeine Liniensegmente Initialisiere ES und SSS; solange ES nicht leer { E = ES.NächstesEreignis(); falls E ist Segment Anfang dann {... } falls E ist Segment Ende dann {... } falls E ist Schnittpunkt dann {... } }
Scan-Line für Schnitt von allgemeinen Liniensegmenten Algorithmus Fall 1: E ist Anfang eines Segments 1 E in Scan-Line-Status Struktur SSS einfügen 2 E mit seinem Vorgänger auf Schnitt testen Gegebenenfalls Schnittpunkt in Ereignisstruktur ES einfügen 3 E mit seinem Nachfolger auf Schnitt testen Gegebenenfalls Schnittpunkt in Ereignisstruktur ES einfügen
Scan-Line für Schnitt von allgemeinen Liniensegmenten Algorithmus Fall 2: E ist Ende eines Segments 1 Vorgänger und Nachfolger von E auf Schnitt testen Gegebenenfalls Schnittpunkt in Ereignisstruktur ES einfügen 2 E aus Scan-Line-Status Struktur SSS entfernen
Scan-Line für Schnitt von allgemeinen Liniensegmenten Algorithmus Fall 3: E ist Schnittpunkt zweier Segmente s o und s u 1 E als Schnittpunkt von s o und s u ausgeben 2 Reihenfolge von s o und s u in Scan-Line-Status Struktur SSS vertauschen 3 s u mit seinem Vorgänger auf Schnitt testen Gegebenenfalls Schnittpunkt in Ereignisstruktur ES einfügen 4 s o mit seinem Nachfolger auf Schnitt testen Gegebenenfalls Schnittpunkt in Ereignisstruktur ES einfügen
Scan-Line für Schnitt von allgemeinen Liniensegmenten Analyse Analyse Anzahl der Ereignisse: 2n + k mit k = Anzahl der Schnittpunkte, k = O(n 2 ) Zugriff auf Ereignisstruktur ES: O(log n 2 ) = O(log n) Zugriff auf Scan-Line-Status Struktur SSS: O(log n) Äußere Schleife wird maximal 2n + k mal durchlaufen Pro Durchlauf maximal 5 Operationen auf ES und SSS Gesamtaufwand: O((n + k) log n) Speicheraufwand: O(n 2 )
Scan-Line für Schnitt von allgemeinen Liniensegmenten Zusammenfassung Zusammenfassung Scan-Line fegt über eine Menge von Objekten Unterteilung: Tote Objekte, Aktive Objekte, Inaktive Objekte Nur gegenwärtig Aktive Objekte werden betrachtet Statisches 2D Problem dynamisches 1D Problem
Teil II Mehrdimensionale Bereichssuche
Mehrdimensionale Bereichssuche Aufgabenstellung Gegeben k-dimensionaler, rechteckiger Bereich D n Punkte im k-dimensionalen Raum Gesucht Alle Punkte, die in D liegen
Mehrdimensionale Bereichssuche Beispiele Beispiele k = 1: Zahlen in einer Folge zwischen a und b k = 2: Städte in einem Quadrat mit 100 km Seitenlänge und Mittelpunkt Wien k > 2: Datenbankabfragen: Personen mit Eigenschaften haben Informatik studiert zwischen 25 und 39 Jahre alt jährliches Einkommen zwischen 30.000,- und 50.000,- besitzen kein Handy
Mehrdimensionale Bereichssuche Lösungsansätze 1-dimensionaler Fall Realisierung: Balancierte Binärbäume, Skiplisten, etc. Aufwand: O(log n + R), R... Anzahl der Punkte im Bereich Höhere Dimensionen Naive Methode: alle Punkte durchtesten O(k n) Grid-Methode: Suchraum in Gridzellen unterteilen Mehrdimensionale Bäume
Mehrdimensionale Bereichssuche Zweidimensionale Bäume A G C F E D B G D A C B F E Struktur wie binäre Suchbäume Knoten representieren Punkte Verwendet abwechselnd x- und y-koordinaten als Schlüssel
Mehrdimensionale Bereichssuche Suche Algorithmus 3 Bereichssuche(Knoten p, Richtung d, Bereich D) falls p NULL dann { falls d == vert dann { (l, r) = (D.y 1, D.y 2 ); coord = p.y; rneu = horiz; } sonst { (l, r) = (D.x 1, D.x 2 ); coord = p.x; rneu = vert; } falls p D dann Ausgabe von p; falls l < coord dann Bereichssuche(p.left, rneu, D); falls coord < r dann Bereichssuche(p.right, rneu, D); }
Mehrdimensionale Bereichssuche Aufbau Aufbau Erstellung eines effizienten Baums? Möglichst balanciert, damit Höhe in O(log n)
Mehrdimensionale Bereichssuche Aufbau Vorgangsweise 1 Punkte nach x- bzw. y-koordinaten sortieren Folgen X und Y 2 Folge Y am Median-Element aufteilen Median-Element kommt in die Wurzel Teilfolgen Y 1 und Y 2 (beide etwa gleich lang) Teilfolgen X 1 und X 2 : dieselben Elemente wie in Y 1 und Y 2 in gleicher Reihenfolge wie in X 3 Analoge Fortsetzung mit X 1 und Y 1, sowie X 2 und Y 2, usw. bis Teilfolgen aus einem Element Blätter des Baumes
Mehrdimensionale Bereichssuche Aufbau Algorithmus 4 Aufbau(l, r, knoten, Xdir) falls l r dann { m = l+r 2 ; falls Xdir == true dann { knoten.eintrag = X[m]; Partitioniere Feld(Y, l, r, m); } sonst { knoten.eintrag = Y [m]; Partitioniere Feld(X, l, r, m); } lsohn = neuer linker Sohn(knoten); rsohn = neuer rechter Sohn(knoten); Aufbau(l, m 1, lsohn,!xdir); Aufbau(m + 1, r, rsohn,!xdir); }
Mehrdimensionale Bereichssuche Analyse Aufbau Rekursion: T (n) = 2T ( n 2 ) + c n Θ(n log n) Bereichsabfrage O( n + R), R... Anzahl der Punkte im Bereich
Mehrdimensionale Bereichssuche Höhere Dimensionen Erweiterung auf kd Bäume Analog wie 2D Bäume alle Dimensionen (in abwechselnder Reihenfolge) durchlaufen Performance Aufbau: Θ(k n log n) Suche: O(k n 1 1 k + R)
Mehrdimensionale Bereichssuche Zusammenfassung Zusammenfassung Effiziente Bereichsabfrage mittels mehrdimensionale Bäume Jede Ebene entspricht eine bestimmte Dimension Aufbau des Baumes mittels Aufteilung der sortierten Punktefolge an den Median-Elementen balanciert Suche analog wie bei Binärbäumen, unter Beachtung der aktuellen Dimension