Was bisher geschah I Motivation, Beispiele I geometrische Objekte im 2 : Punkt, Gerade, Halbebene, Strecke, Polygon I maschinelle Repräsentation geometrischer Objekte I konvexe Mengen im I konvexe Hülle conv(P) endlicher Punktmengen P ⊆ I zwei Algorithmen zur Berechnung der konvexen Hülle im I Bewertungskriterien für geometrische Algorithmen: R Rd Rd R2 I I Laufzeit Robustheit gegenüber I I Spezialfällen Rundungsfehlern 73 Motivation Geoinformationssysteme enthalten Informationen über I Straßen I Radwege I Orte (und Ortsnamen) I Straßennamen I ÖPNV-Strecken I Regionengrenzen I Hotels, Restaurants, Touristenziele meist getrennt in eigenen Schichten (layers) ermöglicht selektive Anzeige, Ein- und Ausblenden aktuell interessanter Informationen Darstellung der Kreuzungen, z.B.: I Radweg - Straße I Bahnlinie - Ländergrenze Aufgabe: Bestimmung aller Schnittpunkte einer gegebenen endlichen Menge von Kurven im 2 R 74 Geographische Daten Verkehrsnetze und Regionengrenzen meist repräsentiert als endliche Mengen endlicher Polygonzüge im 2 , 2 also endliche Mengen von Strecken S = {s1 , . . . , sn } ⊆ 2(R ) maschinelle Darstellung durch Endpunkte der Strecken, also Menge von Paaren {(s1,a , s1,b ), . . . , (sn,a , sn,b )} ⊆ ( 2 )2 R R Aufgabe: Bestimmung aller Schnittpunkte einer gegebenen endlichen Menge von Strecken AG-Aufgabe LSI (line segment intersection) 75 Streckenschnittpunkte R R Strecke (im 2 ) mit den Endpunkten p, q ∈ 2 : pq = {x ∈ 2 | ∃l ∈ [0, 1] : p + l(q − p)} R Zwei Strecken pq, rs schneiden einander gdw. pq ∩ rs 6= ∅ gegeben: S = {s1 , . . . , sn } = {(s1,x , s1,y ), . . . , (sn,x , sn,y )} ⊆ ( R2)2 76 Streckenschnittpunkte – Spezialfälle I Schnittpunkte an Endpunkten der Strecken I Schnittpunkte mehrerer Strecken I Strecken mit unendlich vielen gemeinsamen Punkten werden zunächst vernachlässigt Berechnung des Schnittpunktes SP (unterhalb der Sweep-line): 2 2 , s = (s , s ) ∈ 2 2 Eingabe: r = (ra , rb ) ∈ a b R Ausgabe: (Maybe-Typ): I Schnittpunkt(p) falls ra rb ∩ sa sb = {p} mit p ∈ I „kein Schnittpunkt“, sonst R R2 77 Streckenschnittpunkte – Algorithmus Algorithmus : LSI-1 Eingabe : S = {s1 , . . . , sn } ⊆ Ausgabe : P = {p1 , . . . , pm } ⊆ R 2 2 R2 (Menge aller Schnittpunkte) P=∅ für jedes i ← 1, . . . , n − 1, j ← i + 1, . . . , n : wenn SP(si , sj ) = Schnittpunkt(q) dann P ← P ∪ {q} Laufzeit: O(n2 ) optimal im allgemeinen Fall, weil n2 Schnittpukte existieren können 78 Streckenschnittpunkte praktisch häufig vorkommender Fall: I viele Strecken I wenige Schnittpunkte gesucht: besserer Algorithmus für diesen Fall Ziel: Algorithmus mit (auch) von der Anzahl der Schnittpunkte (Ausgabe) abhängigen Laufzeit 79 Wenige Streckenschnittpunkte Beobachtung: Projektion πy : 2R → 2R auf die y -Achse: für Strecke s dargestellt durch (sa , sb ) = ((sa,x , sa,y ), (sb,x , sb,y )) π(s) = π(sa sb ) = [min(sa,y , sb,y ), max(sa,y , sb,y )] 2 Falls π(s) ∩ π(r ) = ∅, dann SP(r , s) = kein Schnittpunkt Idee: Schnittpunktberechnung nur für Streckenpaare r , s mit π(s) ∩ π(r ) 6= ∅ 80 Strecken mit überlappenden y -Projektionen statt Projektion auf y -Achse und separater Lösung dieses 1D-Problems: Idee Sweep-line-Algorithmus: I sweep line (horizontale Gerade) gleitet von oben nach unten über die Menge aller Strecken (insbesondere über deren Endpunkte) in S I Beginn oberhalb aller Punkte in S I mit Verwaltung von Zusatzinformation (Zustand, Status) Z , hier Menge der aktuell „interessanten“ Strecken Ereignismenge E, enthält die y -Koordinaten, an denen die Zusatzinformation aktualisiert wird, hier (zunächst) Menge aller Streckenendpunkte 81 Strecken mit überlappenden y -Projektionen Verwaltung der Menge Z (Zustand) der aktuell „interessanten“ Strecken: I I zu Beginn Z = ∅ Änderung von Z an y -Koordinaten, bei denen 1. eine neue Strecke s ∈ S interessant wird (oberer Endpunkt von s), 2. eine Strecke s ∈ Z uninteressant wird (unterer Endpunkt von s), I also an allen Endpunkten von Strecken in S (Ereignismenge E) Aktualisierung von Z und Schnittpunktberechnung: 1. für alle r ∈ Z : I I Berechnung von SP(s, r ) und Z ← Z ∪ {s}, 2. Z ← Z \ {s} 82 LSI – Algorithmus 2 Algorithmus : LSI-2 Eingabe : S = {s1 , . . . , sn } ⊆ ( Ausgabe : P = {p1 , . . . , pm } ⊆ R2)2 R2 (Menge aller Schnittpunkte) P ← ∅ (Schnittpunktmenge) Z ← ∅ (Zustand) E ← ∅ (Ereignismenge) für jedes s = (sa , sb ) ∈ S : E ← E ∪ {sa , sb } solange E 6= ∅ : p ← max(E) E ← E \ {p} (Z , P) ← LSI-2-Ereignisbehandlung(p, Z , P) Laufzeit: O(n + 2nL(LSI-2-Ereignisbehandlung(p, Z , P))) 83 LSI-2 – Ereignisbehandung Algorithmus : LSI-2-Ereignisbehandlung Eingabe : Ereignis p, Zustand Z , Schnittpunktmenge P Ausgabe : Zustand Z 0 , Schnittpunktmenge P 0 wenn p oberer Endpunkt der Strecke s ∈ S dann für jedes r ∈ Z : wenn SP(r , s) = Schnittpunkt(q) dann P 0 ← P ∪ {q} Z 0 ← Z ∪ {s} wenn p unterer Endpunkt der Strecke s ∈ S dann Z 0 ← Z \ {s} Laufzeit: O(|Z |) mit |Z | ≤ n 84 LSI-2 – Problem auch in LSI-2 werden Schnittpunkte für weit voneinander entfernte Strecken berechnet Laufzeit: z.B. für S = {((i, i), (i, −i)) | i ∈ {1, . . . , n}} L(SP) ∈ O(n2 ), obwohl LSI(S) = ∅ 85 Benachbarte Strecken Beobachtung: nur benachbarte Strecken in Z können einander schneiden Verwaltung von Informationen über Nachbarschaftsbeziehungen im Zustand reduziert die Anzahl der Schnittpunktberechnungen für jede neu in Z hinzukommende Strecke auf höchstens zwei (statt |Z |) 86 Verbesserung von LSI-2 – Reihenfolge in Z I Verwaltung der Strecken in Z nach (aktueller) x-Koordinate sortiert I Jede in Z neue Strecke wird sortiert in Z eingefügt. Dabei entstehen bei jedem Einfügen / Löschen ≤ 2 neue benachbarte Streckenpaare (nur je ≤ 2 Schnittpunktberechnungen nötig) aber: Berechnung aller aktuellen x-Koordinaten an jedem Ereignis zu aufwendig Wie ist das ohne Berechnung aller aktuellen x-Koordinaten an jedem Ereignis möglich? 87 Verbesserung von LSI-2 – Ereignismenge Problem: Reihenfolge der Strecken in Z ändert sich nicht nur beim Einfügen / Löschen von Strecken in / aus Z (Streckenendpunkten), sondern auch an Schnittpunkten Lösung: Schnittpunkte auch als Ereignisse behandeln, d.h. an allen gefundenen Schnittpunkten p: I p zur Ereignismenge E hinzufügen I die sich in p schneidenden Strecken si und si+1 in Z vertauschen I Schnittpunkte zwischen si und si+1 und ihren neuen Nachbarn bestimmen Geeignete Datenstrukturen zur effizienten Umsetzung ? 88 Datenstruktur zur Verwaltung der Zustände Operationen: I beliebiges Element sortiert in Z einfügen I beliebiges Element aus Z entfernen I Zugriff auf Nachbarn I (Nachbarn Vertauschen) geeignet: balancierter binärer Suchbaum Daten: Blätter (Information): Strecke s = (sa , sb ) innere Knoten (Wegweiser): Maximum des linken Teilbaumes (Information des „rechtesten“ Knotens im linken Teilbaum) 89 Datenstruktur zur Verwaltung der Ereignisse Operationen: I beliebiges Ereignis einfügen I beliebiges Element in E finden (Mehrfacheinträge vermeiden) und evtl. Information ergänzen I „nächstes“ Ereignis ausgeben und aus E entfernen geeignet: balancierter binärer Suchbaum Daten zu jedem Ereignis: R2 (Schlüssel, lexikographisch geordnet) I Punkt p ∈ I Menge U(p) ⊆ S aller Strecken mit oberem Endpunkt p 90 Informationen zu Schnittpunkten Ausgabe: Menge aller Schnittpunkte, jeweils mit den Daten: R2 I Punkt p ∈ I Menge U(p) ⊆ S aller Strecken mit oberem Endpunkt p I Menge L(p) ⊆ S aller Strecken mit unterem Endpunkt p I Menge C(p) ⊆ S aller Strecken mit innerem Punkt p einzige Operation: I Einfügen (Anhängen) 91 LSI – Algorithmus 3 Algorithmus : LSI-3 Eingabe : S = {s1 , . . . , sn } ⊆ ( Ausgabe : P = {p1 , . . . , pm } ⊆ R2)2 R2 (Menge aller Schnittpunkte) P ← ∅ (Schnittpunktmenge) Z ← ∅ (Zustand) E ← ∅ (Ereignismenge) für jedes s = (sa , sb ) ∈ S : E ← E ∪ {sa , sb } (beim oberen Endpunkt mit Zusatzinfo s) solange E 6= ∅ : p ← max(E) E ← E \ {p} (E, Z , P) ← LSI-3-Ereignisbehandlung(p, E, Z , P) Laufzeit: O(n + m + 2(n + m)L(LSI-3-Ereignisbehandlung(p, E, Z , P))) mit Schnittpunkt-Anzahl m 92 LSI-3 – Ereignisbehandung Algorithmus : LSI-3-Ereignisbehandlung Eingabe : Ereignis p, Ereignismenge E, Zustand Z , Schnittpunktmenge P Ausgabe : Ereignismenge E 0 , Zustand Z 0 , Schnittpunkmenge P 0 (L(p), C(p)) ← Menge aller s ∈ Z mit (unterem,inneren) Punkt p wenn |U(p) ∪ L(p) ∪ C(p)| > 1 dann P 0 ← P ∪ {p} (mit Zusatzinformation U(p), L(p), C(p)) Z ← Z \ (L(p) ∪ C(p)) Z 0 ← Z ∪ U(p) ∪ C(p) (sortiert knapp unterhalb p) wenn U(p) ∪ C(p) = ∅ dann (sl , sr ) ← (linker, rechter) Nachbar von p wenn SP(sl , sr ) = Schnittpunkt(p) dann E 0 ← E ∪ {p} (falls p 6∈ E) sonst s0 ← „linkeste“ Str. in U(p) ∪ C(p), sl ← linker N. von s0 in Z 0 wenn SP(sl , s0 ) = Schnittpunkt(p) dann E 0 ← E ∪ {p} (. . . ) s00 ← „rechteste“ Str. in U(p) ∪ C(p), sr ← rechter N. von s00 in Z 0 wenn SP(sr , s00 ) = Schnittpunkt(q) dann E 0 ← E ∪ {q} (. . . ) 93 LSI-3 – Laufzeit Für n Strecken mit k Schnittpunkten I alle 2n Streckenenden in balancierten Suchbaum E einfügen: O(n log n) I LSI-3 – Ereignisbehandung für jedes Ereignis in E: I I I I nächstes Ereignis finden und löschen: O(log(n + k )) ≤ 2 Ereignisse einfügen (und evtl. vorher suchen): O(log(n + k )) ≤ O(m(p))-mal für m(p) = |U(p) ∪ L(p) ∪ C(p)| Strecke in Z einfügen / löschen: O(log(n + k )) insgesamt über alle Ereignisse : P O(m log(n + k )) mit m = p∈E m(p) Problem: m > n + k möglich, falls m(p) > 1 Lösung: Abschätzung mit Euler-Formel für planare Graphen |V | − |E| + f ≥ 2 ergibt m ∈ O(n + k ) Gesamtlaufzeit: O((n + k ) log(n + k )) 94