Geometrische Algorithmen

Werbung
Geometrische Algorithmen
Geometrische Algorithmen
Bin Hu
Algorithmen und Datenstrukturen 2
Arbeitsbereich für Algorithmen und Datenstrukturen
Institut für Computergraphik und Algorithmen
Technische Universität Wien
Geometrische Algorithmen
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
Geometrische Algorithmen
Part I
Scan-Line Prinzip
Geometrische Algorithmen
Scan-Line Prinzip
Grundlagen
Scan-Line Prinzip
Idee
Gegeben: 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
Geometrische Algorithmen
Scan-Line für Schnitt iso-orientierter Liniensegmente
Einführung
Schnitt iso-orientierter Liniensegmente
Aufgabenstellung
Gegeben: n horizontale und vertikale Liniensegmente
s1 , . . . , sn
Gesucht: Alle Paare von Segmente, die sich schneiden
H
F
B
C
A
E
G
D
Geometrische Algorithmen
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(n2 )
Geometrische Algorithmen
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
Geometrische Algorithmen
Scan-Line für Schnitt iso-orientierter Liniensegmente
Algorithmus
Beispiel:
B
C
A
D
E
A A AAADD 0
EDDE
EE
(A,B)
(A,C)
(C,D)
Geometrische Algorithmen
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 6= ∅) {
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, yu ), (p, yo ) ]
12:
Für alle h. Segmente t aus L mit y-Koord. zwischen
[ yu , yo ]: gebe (s, t) als sich schneidendes Paar aus;
13:
}
14:
}
15: }
Geometrische Algorithmen
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, yu ), (p, yo ) ]
(Bereichsabfrage)
Mögliche Datenstrukturen
Balancierte Suchbäume (AVL, Rot-Schwarz, etc.)
Randomisierte Skiplisten
...
Geometrische Algorithmen
Scan-Line für Schnitt iso-orientierter Liniensegmente
Analyse
Analyse
Bereichsabfrage: O(log n + r ) mit
r = Anzahl der Elemente zwischen [ (p, yu ), (p, yo ) ]
Gesamtlaufzeit: O(n log n + R) mit
R = Anzahl der sich schneidenden Segmente
Geometrische Algorithmen
Scan-Line für Schnitt von allgemeinen Liniensegmenten
Einführung
Schnitt von allgemeinen Liniensegmenten
Aufgabenstellung
Gegeben: Menge S = {s1 , . . . , sn } von n Liniensegmenten in
der Ebene
Gesucht: Menge echter Schnittpunkte (Kreuzung von
Segmenten, die keine Endpunkte sind)
y
x
Geometrische Algorithmen
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
Ereignisse
Anfangspunkt eines Segments
Endpunkt eines Segments
weitere Ereignisse?
Geometrische Algorithmen
Scan-Line für Schnitt von allgemeinen Liniensegmenten
Einführung
Beobachtungen
Schneiden sich Segmente si mit sj , dann...
waren si und sj “Nachbarn” unmittelbar vor dem Schnittpunkt
⇒ Es genügt, nur benachbarte Segmente auf Schnitt zu
testen
vertauscht sich die Anordnung von si und sj in L nach dem
Schnittpunkt
⇒ Schnittpunkte sind auch Ereignisse
⇒ Sie werden während des Scans dynamisch zur
Ereignisstruktur hinzugefügt
Geometrische Algorithmen
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
Geometrische Algorithmen
Scan-Line für Schnitt von allgemeinen Liniensegmenten
Algorithmus
Algorithmus 2 Scan-Line 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 0 = TesteSchnittErzeugeEreignis(E.Segment,VS);
falls E 0 6= ∅ und E 0 ∈
/ ES dann {
ES.FügeEin(E 0 );
}
NS = SSS.Nachf(E.Segment);
E 0 = TesteSchnittErzeugeEreignis(E.Segment,NS);
falls E 0 6= ∅ und E 0 ∈
/ ES dann {
ES.FügeEin(E 0 );
}
}
falls E ist Segment Ende dann {
VS = SSS.Vorg(E.Segment);
NS = SSS.Nachf(E.Segment);
SSS.Entferne(E.Segment);
E 0 = TesteSchnittErzeugeEreignis(VS,NS)
falls E 0 6= ∅ und E 0 ∈
/ ES dann {
ES.FügeEin(E 0 );
}
}
falls E ist Schnittpunkt dann {
Gib E.SegmentO und E.SegmentU aus;
SSS.Vertausche(E.SegmentO,E.SegmentU);
VS= SSS.Vorg(E.SegmentU);
E 0 =TesteSchnittErzeugeEreignis(E.SegmentU,VS);
falls E 0 6= ∅ und E 0 ∈
/ ES dann {
ES.FügeEin(E 0 );
}
NS = SSS.Nachf(E.SegmentO);
E 0 = TesteSchnittErzeugeEreignis(E.SegmentO,NS);
falls E 0 6= ∅ und E 0 ∈
/ ES dann {
ES.FügeEin(E 0 );
}
}
}
Geometrische Algorithmen
Scan-Line für Schnitt von allgemeinen Liniensegmenten
Algorithmus
Algorithmus 3 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 {
...
}
}
Geometrische Algorithmen
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
Geometrische Algorithmen
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
Geometrische Algorithmen
Scan-Line für Schnitt von allgemeinen Liniensegmenten
Algorithmus
Fall 3: E ist Schnittpunkt zweier Segmente so und su
1
E als Schnittpunkt von so und su ausgeben
2
Reihenfolge von so und su in Scan-Line-Status Struktur SSS
vertauschen
3
su mit seinem Vorgänger auf Schnitt testen
Gegebenenfalls Schnittpunkt in Ereignisstruktur ES einfügen
4
so mit seinem Nachfolger auf Schnitt testen
Gegebenenfalls Schnittpunkt in Ereignisstruktur ES einfügen
Geometrische Algorithmen
Scan-Line für Schnitt von allgemeinen Liniensegmenten
Analyse
Analyse
Anzahl der Ereignisse: 2n + k mit
k = Anzahl der Schnittpunkte, k = O(n2 )
Zugriff auf Ereignisstruktur ES: O(log n2 ) = 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(n2 )
Geometrische Algorithmen
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
Geometrische Algorithmen
Part II
Mehrdimensionale Bereichssuche
Geometrische Algorithmen
Mehrdimensionale Bereichssuche
Aufgabenstellung
Gegeben
n Punkte im k-dimensionalen Raum
k-dimensionaler, rechteckiger Bereich D
Gesucht
Alle Punkte, die in D liegen
Geometrische Algorithmen
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 Smartphone
Geometrische Algorithmen
Mehrdimensionale Bereichssuche
Lösungsansätze
1-dimensionaler Fall
Realisierung: Balancierte Suchbä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)
Mehrdimensionale Bäume
Geometrische Algorithmen
Mehrdimensionale Bereichssuche
Zweidimensionale Bäume
A
C
G
D
B
E
B
A
E
D
G
F
C
F
Struktur wie binäre Suchbäume
Knoten representieren Punkte
Verwendet abwechselnd x- und y -Koordinaten als Schlüssel
Geometrische Algorithmen
Mehrdimensionale Bereichssuche
Suche
Algorithmus 4 Bereichssuche(Knoten p, Richtung d, Bereich D)
falls p 6= NULL dann {
falls d == vertikal dann {
min = D.y1 ;
max = D.y2 ;
coord = p.y ;
rNeu = horizontal;
} sonst {
min = D.x1 ;
max = D.x2 ;
coord = p.x;
rNeu = vertikal;
}
falls p ∈ D dann Ausgabe von p;
falls min ≤ coord dann Bereichssuche(p.left, rNeu, D);
falls coord ≤ max dann Bereichssuche(p.right, rNeu, D);
}
Geometrische Algorithmen
Mehrdimensionale Bereichssuche
Aufbau
Aufbau
Erstellung eines effizienten Baums?
→ Möglichst balanciert, damit Höhe in O(log n)
Geometrische Algorithmen
Mehrdimensionale Bereichssuche
Aufbau
Vorgehensweise
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 Y1 und Y2 (beide etwa gleich lang)
→ Teilfolgen X1 und X2 :
dieselben Elemente wie in Y1 und Y2
in gleicher Reihenfolge wie in X
3
Analoge Fortsetzung mit X1 und Y1 , sowie X2 und Y2 , usw.
bis Teilfolgen aus einem Element → Blätter des Baumes
Geometrische Algorithmen
Mehrdimensionale Bereichssuche
Aufbau
Algorithmus 5 Aufbau(l, r , knoten, Xdir )
falls l ≤ r dann {
m = d l+r
2 e;
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);
}
links = neuer linker Nachfolgeknoten;
rechts = neuer rechter Nachfolgeknoten;
Aufbau(l, m − 1, links, !Xdir );
Aufbau(m + 1, r , rechts, !Xdir );
}
Geometrische Algorithmen
Mehrdimensionale Bereichssuche
Analyse
Aufbau
Rekursion: T (n) = 2T ( n2 ) + c · n
→ Θ(n log n)
Bereichsabfrage
√
O( n + R), R . . . Anzahl der Punkte im Bereich
Geometrische Algorithmen
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− k1
+ R)
Geometrische Algorithmen
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 Suchbäume, unter Beachtung der
aktuellen Dimension
Herunterladen