Zum Hauptinhalt springen

1.2.2 Primitive Operationen & 1.2.3 Rechenmodell

Um Laufzeiten geometrischer Algorithmen sauber angeben zu können, muss man festlegen, was ein Rechenschritt ist. Dazu dienen die primitiven Operationen und das Rechenmodell.

1.2.2 Primitive geometrische Operationen​

Primitive Operationen sind Operationen, die nur Objekte konstanter Größe betreffen. Sie gelten im Rechenmodell als Operationen mit konstanter Laufzeit und konstantem Speicherbedarf, also O(1)O(1).

Primitiv ✔Nicht primitiv ✘
Schnittpunkt zweier GeradenLiegt ein Punkt in einem Polygon?
Liegt ein Punkt im Halbraum einer Hyperebene?Schnitt zweier Polygone
Links-/Rechtstest Punkt vs. gerichtete GeradeKonvexe Hülle von nn Punkten
Abstand zweier Punkte

Warum ist „Punkt in Polygon“ nicht primitiv? Ein Polygon hat nn Ecken, nn ist nicht konstant. Der Test muss (im Allgemeinen) alle nn Kanten anschauen und kostet O(n)O(n).

Merkregel: Primitiv ist, was sich mit einer festen Anzahl arithmetischer Operationen auf einer festen Anzahl von Koordinaten berechnen lässt, unabhängig von der Eingabegröße.

Der Orientierungstest​

Steht so nicht explizit auf den Folien von 1.2.2, ist aber das Beispiel „Punkt liegt im Halbraum einer Hyperebene“ in 2D. In Kapitel 2 („liegt rr links von pqpq?“, „Rechtskurve?“) wird er ständig benutzt.

Gegeben drei Punkte a,b,c∈R2a,b,c\in\mathbb{R}^2. Liegt cc links, rechts oder auf der gerichteten Geraden durch aa nach bb?

Man bildet das 2D-Kreuzprodukt der Vektoren b−ab-a und c−ac-a:

orient⁡(a,b,c):=(bx−ax)(cy−ay)−(by−ay)(cx−ax)=det⁡(1axay1bxby1cxcy)\operatorname{orient}(a,b,c) := (b_x-a_x)(c_y-a_y) - (b_y-a_y)(c_x-a_x) = \det\begin{pmatrix} 1 & a_x & a_y\\ 1 & b_x & b_y\\ 1 & c_x & c_y\end{pmatrix}
ErgebnisLage von ccKurve a→b→ca\to b\to c
>0>0links von ab⃗\vec{ab}Linkskurve (gegen den Uhrzeigersinn)
<0<0rechts von ab⃗\vec{ab}Rechtskurve (im Uhrzeigersinn)
=0=0auf der Geraden ababkeine Kurve, kollinear

Warum funktioniert das? b−ab-a ist die Richtung, in die man läuft, c−ac-a zeigt zum Testpunkt. Das Kreuzprodukt ist positiv, wenn man b−ab-a gegen den Uhrzeigersinn um weniger als 180° drehen muss, um auf c−ac-a zu kommen, wenn also cc links liegt.

Zum Ausprobieren: Zieh die Punkte. Die grüne Seite ist „links von ab⃗\vec{ab}“, die orange „rechts“. Lege cc genau auf die Gerade, dann wird das Ergebnis 0.

linksrechtsabc
orient(a,b,c) = (bx−ax)(cy−ay) − (by−ay)(cx−ax) = (8)·(5) − (3)·(3) = 31
c liegt links von a→b – Linkskurve (gegen den Uhrzeigersinn). Fläche des Dreiecks abc = |31| / 2 = 15.5. · Ziehe a, b oder c (Punkte rasten auf dem Gitter ein).

Zusatzbedeutung: 12∣orient⁡(a,b,c)∣\tfrac12\lvert\operatorname{orient}(a,b,c)\rvert ist der Flächeninhalt des Dreiecks abcabc. Ist er 0, ist das Dreieck entartet, die Punkte sind kollinear.

Beispiele:

aabbccRechnungErgebnis
(0,0)(0,0)(2,0)(2,0)(1,1)(1,1)2⋅1−0⋅1=22\cdot1 - 0\cdot1 = 2links ✔ (über der x-Achse)
(0,0)(0,0)(2,0)(2,0)(1,−1)(1,-1)2⋅(−1)−0⋅1=−22\cdot(-1) - 0\cdot1 = -2rechts
(0,0)(0,0)(2,0)(2,0)(5,0)(5,0)2⋅0−0⋅5=02\cdot0 - 0\cdot5 = 0kollinear
(0,0)(0,0)(1,2)(1,2)(2,1)(2,1)1⋅1−2⋅2=−31\cdot1 - 2\cdot2 = -3rechts

Kosten: 2 Multiplikationen, 5 Subtraktionen, ein Vorzeichenvergleich, also primitiv, O(1)O(1).

Warum Kreuzprodukt statt Winkel?

Man könnte auch Winkel mit atan2 berechnen und vergleichen. Der Orientierungstest liefert dieselbe Information aber ohne trigonometrische Funktionen, ohne Division und ohne Sonderfall bei senkrechten Geraden (keine Steigung ∞\infty). Er ist schneller und weniger anfällig für Rundungsfehler.

1.2.3 Rechenmodell: Real RAM​

Um Laufzeiten zu zählen, braucht man ein abstraktes Maschinenmodell. In der algorithmischen Geometrie ist das die Real RAM (Real Random Access Machine):

  • Abzählbar unendlich viele Speicherzellen, adressierbar durch natürliche Zahlen.
  • Jede Speicherzelle kann beliebige reelle Zahlen oder ganze Zahlen enthalten, mit unendlicher Genauigkeit.
  • Folgende Operationen sind primitiv und kosten konstante Zeit:
    • arithmetische Operationen: +, −, ×, /,  mod , div⁡+,\ -,\ \times,\ /,\ \bmod,\ \operatorname{div}
    • Vergleiche reeller Zahlen
    • indirekte Adressierung (Zeiger, Arrayzugriff)
    • Wurzeln, trigonometrische Funktionen, Logarithmen

Real RAM vs. echter Computer (Ergänzung)​

Das Modell ist eine Idealisierung:

Real RAMEchter Rechner (double)
exakte reelle Zahlen64-Bit-Gleitkomma, ca. 16 Dezimalstellen
orient⁡=0\operatorname{orient}=0 ist exakt entscheidbarRundungsfehler, fast kollineare Punkte bekommen evtl. das falsche Vorzeichen
 \sqrt{\ }, sin⁡\sin kosten O(1)O(1)kosten real deutlich mehr als ++ und ×\times

Für die Laufzeitanalyse ist das Modell richtig. Für die Implementierung muss man wissen, dass Tests auf „=0=0“ mit Gleitkommazahlen fragil sind. Die Folien zu Kapitel 2 sagen beim naiven Algorithmus ausdrücklich: „Rundungsfehler der Gleitkommaarithmetik vernachlässigen“. Abhilfen in der Praxis sind ganzzahlige Koordinaten, exakte Arithmetik oder robuste Prädikate.