• Keine Ergebnisse gefunden

Rheinische Friedrich-Wilhelms-Universität Bonn Institut für Informatik I. Thomas Helten. Kinetische. 27. April 2006

N/A
N/A
Protected

Academic year: 2022

Aktie "Rheinische Friedrich-Wilhelms-Universität Bonn Institut für Informatik I. Thomas Helten. Kinetische. 27. April 2006"

Copied!
26
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Rheinische Friedrich-Wilhelms-Universit¨ at Bonn

Institut f¨ur Informatik I

Thomas Helten

Kinetische Segmentb¨aume

27. April 2006

Seminararbeit im SS 2006 Betreuer: Elmar Langetepe

(2)
(3)

Zusammenfassung

Kinetische Segmentb¨aume basieren, wie ihr Name schon vermuten l¨asst, auf der Datenstruktur der Segmentb¨aume. Sie erweitern diese um die F¨ahigkeit, nicht nur konstante Intervalle zu speichern, sondern auch solche Intervalle, deren Endpunkte sich kontinuierlich ver¨andern.

Solche Eigenschaften sind in vielen Bereichen w¨unschenswert, da es h¨aufig Situationen gibt, wo man mit ver¨anderlichen Daten zu tun hat.

Ein Beispiel w¨are kinetisches binary space partitioning (kurz BSP), wie sie bei de Berg, Comba und Guibas[2] beschrieben wird. Binary space partitioning ist ein effektives Verfahren, um einen Vektorraum in eine Menge konvexer Regionen zu zerlegen. Diese Zerlegung wird durch Halbebenen-Tests erreicht, wobei zur Bestimmung der Halb- ebenen meist vorhandene Geometrie der Szene verwendet wird. Die Zerlegung wird in einem Bin¨arbaum gespeichert, dessen Bl¨atter die konvexen Regionen repr¨asentieren. Mit einer solchen Datenstruktur lassen sich viele Probleme gerade in der Computergraphik effizient an- gehen. Als Anwendungsbeispiele seien Visibilit¨ats-Berechnungen oder Frustrum-Culling erw¨ahnt. Paterson und Yao[4] stellen einen BSP- Baum vor, der auf einem herk¨ommlichen Segmentbaum beruht. Dieser wird nun von de Berg et al. aufgegriffen und durch einen kinetischen Segmentbaum erweitert. Damit besitzt der BSP-Baum die F¨ahigkeit, ein korrektes BSP auch in Szenen zu gew¨ahrleisten, bei denen sich Objekte kontinuierlich bewegen. Diese Ausarbeitung konzentriert sich darauf, neben der Beschreibung des kinetischen Segmentbaumes auch eine kleine Einf¨uhrung in die Terminologie der kinetischen Datenstruk- turen, sowie eine kurze Vorstellung des allgemeinen Segmentbaumes zu geben. Da das Thema desbinary space partitioning sehr umfangreich ist, w¨urde eine zus¨atzliche Einf¨uhrung und die letztendliche Anwen- dung den Rahmen dieser Ausarbeitung mehr als sprengen. Bei weite- rem Interesse sei aber auf das abschließende Literaturverzeichnis ver- wiesen.

(4)

Inhaltsverzeichnis

1 Die Kinetische Datenstruktur 3

1.1 Erl¨auterungen . . . 3

1.2 Definition der Eigenschaften von kinetischen Datenstrukturen 4 1.3 Ein m¨oglicher Ablauf . . . 5

2 Der Segmentbaum 8 2.1 Eine Problem-Situation . . . 8

2.2 Definition und Aufbau des Segmentbaumes . . . 9

2.3 Anwendungsbeispiel . . . 10

3 Der kinetische Segmentbaum 12 3.1 Erweiterungen bez¨uglich des Segmentbaumes . . . 12

3.2 Ein Ereignis tritt ein . . . 13

3.3 Erweitern eines Segmentes . . . 14

3.4 Ein Beispiel f¨ur das Erweitern . . . 15

3.5 K¨urzen eines Segmentes . . . 18

3.6 Ein Beispiel f¨ur das K¨urzen . . . 19

3.7 Was ist sonst noch zu beachten? . . . 21 4 Genauere Betrachtung der Antwortzeit 22

(5)

1 Die Kinetische Datenstruktur

1.1 Erl¨auterungen

Viele Ph¨anomene in der realen Welt haben die Eigenschaft, dass sie sich fortlaufend ver¨andern. Daraus folgen einige Probleme, wenn man bestimm- te Eigenschaften in Datenstrukturen speichern und aktuell halten will. Bei- spielsweise will man von n Werten auf der Y-Achse stets den gr¨oßten be- trachten. In einem statischen Szenario ist dies trivial, man bestimmt den gr¨oßten Wert in O(n) und ist fertig, da sich die Werte nie ver¨andern. In ei- nem dynamischen Szenario ver¨andern sich jedoch diese Werte kontinuierlich und es stellt sich die Frage, wie man nun an das Problem mit dem gr¨oßten Y-Wert heran geht. Man k¨onnte nun einfach naiv zum Anfrage-Zeitpunkt mit dem oben erw¨ahnten Verfahren den gesuchten Wert ermitteln, jedoch w¨urde man dadurch viel Rechenzeit verschwenden, wenn sich die Anord- nung nur selten ver¨andert. Man sieht schnell, dass man hier etwas einsparen kann, wenn man sich n¨aher mit den Eigenschaften des Problems vertraut macht. Angenommen, die Bewegung der Werte ist linear abh¨angig von der Zeit t, dann l¨asst sich die Entwicklung leicht in einem Diagramm deutlich machen. Dieses Diagramm besitzt eine Zeit-Achse t und eine Werte-Achse y. Die Messwerte in Abh¨angigkeit von der Zeit bilden in diesem Diagramm Geraden. H¨atten die Messwerte andere Abh¨angigkeiten von der Zeit, dann w¨aren auch andere Funktionen, sowohl stetige als auch nicht stetige, denk- bar. Man sieht schnell, dass die Bestimmung des gr¨oßten Y-Wertes gleich der Bestimmung der oberen Kontur von n Funktionen ist; siehe Abbildung 1.

Diese obere Kontur w¨urde uns stets den gr¨oßten Y-Wert liefern. Jedoch for- dert dieser Ansatz, dass die Entwicklung der Y-Werte ¨uber die gesamte Zeit bekannt sei. Dies ist allerdings nicht immer gegeben. Es k¨onnte ebenso sein, dass sich die Funktionen, von denen die Y-Werte abh¨angen, im Verlauf der Beobachtung spontan ¨andern. Dies h¨atte zur Folge, dass die anfangs berech- nete Kontur nicht mehr korrekt sein k¨onnte.

Eine kinetische Datenstruktur bietet die M¨oglichkeit, eben solche Betrach- tungen zu machen und dabei bestimmte Daten bereit zu halten. In unserem Fall w¨are dies der gr¨oßte Y-Wert. Man nennt dies das Attribut der kineti- schen Datenstruktur. Obwohl sich die einzelnen beteiligten Objekte st¨andig ver¨andern, liegen sie meist in einer gewissen Ordnung vor. In diesem Fall w¨are dies die Reihenfolge der Werte auf der Y-Achse. Solange sich diese Ordnung nicht ver¨andert, kann sich auch unser Attribut nicht ver¨andern.

Man spricht hierbei von Zertifikaten. Es ist jedoch m¨oglich, dass es Situa- tionen gibt, wo ein Zertifikat seine G¨ultigkeit verliert. Ein Beispiel hierf¨ur w¨are, wenn zwei Y-Werte ihre Reihenfolge tauschen. Eine solche Situati- on nennt man Ereignis. Jetzt gibt es Ereignisse, die Zertifikate ver¨andern, die eine Aktualisierung des Attributes zur Folge haben und solche, wo nur intern etwas aktualisiert werden muss. Die ersten nennt man externe Er-

(6)

eignisse, die zweiten interne Ereignisse. Die Zeitpunkte solcher Ereignisse werden zu Beginn berechnet, soweit dies das Wissen ¨uber die Bewegung der betrachteten Objekte zul¨asst. Diese berechneten Ereignisse werden in der Reihenfolge ihres Eintretens in einer priority queue gespeichert. Wie schon erw¨ahnt, k¨onnen sich auch die Funktionen, mit denen die Bewegungen vor- aus gesagt werden, ver¨andern. In diesem Fall m¨ussen eventuell Ereignisse in der queue verworfen und neu berechnet werden. Die Zeit, die ben¨otigt wird, um die Datenstruktur im Falle eines Ereignisses zu aktualisieren, wird Antwortzeit oder engl.response time genannt.

y

t

y2

y1 y3 y4

y5 obere Kontur

Abbildung 1: Obere Kontur der Y-Werte in Abh¨angigkeit von t.

1.2 Definition der Eigenschaften von kinetischen Datenstruk- turen

Definition 1 Eine kinetische Datenstruktur ist...

1. lokal, wenn jedes Ereignis nur wenige (poly-logarithmisch1 viele) Zer- tifikate beeinflusst.

2. effizient, wenn die Anzahl von internen Ereignissen im Vergleich zur Anzahl der externen Ereignisse vernachl¨assigbar klein ist.

3. kompakt, wenn die Anzahl der Zertifikate ungef¨ahr proportional zur Anzahl der betrachteten Objekte ist.

4. responsiv, wenn die worst-case Antwortzeit poly-logarithmisch ist.

1poly-logarithmisch bedeutet in diesem FallO(logxn) wobeixIIN

(7)

1.3 Ein m¨oglicher Ablauf y

t

y2

y1

t0 t1

internes Ereignis externes Ereignis

e1

e2

e3

y3

t2 t3 t4

Abbildung 2: Ein m¨oglicher Ablauf mit Ereignissen.

An dieser Stelle sei noch einmal auf das Beispiel mit dem gr¨oßten Y- Wert verwiesen. Abbildung 2 zeigt einen m¨oglichen Ablauf, bei dem der gr¨oßte Y-Wert bestimmt werden soll. In diesem Beispiel wird davon ausge- gangen, dass eine Funktion zwar ver¨andert werden kann, sie jedoch immer zusammenh¨angend ist. Diese Annahme ist sinnvoll, da Bewegungen in der Natur zwar spontan ihre Richtung ¨andern k¨onnen, sich aber die Position eines Objektes oder Lebewesen nicht sprunghaft ¨andert.

t0: Dies ist die Ausgangssituation. Zu betrachten sind drei Y-Werte, die durch lineare Funktionen beschrieben werden. Die Zertifikate lauten hierbei Z1 = (y1 ist kleinste Funktion), Z2 = (y2 ist mittlere Funk- tion) und Z3 = (y3 ist gr¨oßte Funktion). F¨ur jedes Zertifikat wird nun berechnet, wann dieses ung¨ultig wird. Dies geschieht genau dann, wenn sich die am Zertifikat beteiligte Funktion mit einer benachbar- ten schneidet. Aufgrund der aktuellen Funktionen der Y-Werte wird errechnet, dass zum Zeitpunktt1 sowohl das ZertifikatZ1 als auch das Zertifikat Z2 ihre G¨ultigkeit verlieren. Dies sei das Ereignis e1. Das ZertifikatZ3 ist vom Zeitpunkt t0 aus gesehen nicht bedroht, da sich die Funktion des Wertes y3 mit keiner benachbarten schneidet. Das errechnete Ereignise1 wird nun in diepriority queue einsortiert.

t1: Zu diesem Zeitpunkt verlieren, wie errechnet, die Zertifikate Z1 und Z2 ihre G¨ultigkeit. Da an diesem Ereignis e1 nicht das Zertifikat des gr¨oßten Y-Wertes beteiligt ist, ist dies eininternes Ereignis. Das Er- eignis wird nun aus der queue entfernt. Aufgrund der Tatsache, dass

(8)

die beteiligten Funktionen ihre Reihenfolge bzgl. des Y-Wertes ¨andern, m¨ussen zwei neue Zertifikate f¨ur diese Funktionen ausgestellt werden.

Diese Zertifikate lauten Z4 = (y2 ist kleinste Funktion) und Z5 = (y1 ist mittlere Funktion). Eine weitere Konsequenz, die aus dem Tausch entstanden ist, ist die Tatsache, dass die Funktionen jetzt auch jeweils einen anderen Nachbarn haben k¨onnen. In diesem Fall ist esy1, welche als neuen Nachbarn, die Funktiony3 bekommen hat. Da benachbarte Funktionen ihre Zertifikate bedrohen k¨onnen, muss nun getestet wer- den, ob sich y1 und y3 schneiden werden. Dies ist zum Zeitpunkt t3 der Fall. Dieses Ereignis e2 wird in diepriority queue einsortiert.

t2: Zu diesem Zeitpunkt tritt ein Sonderfall ein, denn hier wird die Funk- tion des Wertesy2 ver¨andert. Dies hat zur Folge, dass ¨uberpr¨uft wer- den muss, ob sich neue Schnitte mit den Nachbarn ergeben, oder alte Schnitte wegfallen. An dieser Stelle ist auch die obige Annahme wich- tig, die ausschließt, dass Funktionen Spr¨unge machen. W¨are dies der Fall, so m¨usste zus¨atzlich bestimmt werden, welche Funktionen die neuen Nachbarn vony2sind. In Abbildung 2 sieht man, dass aufgrund der neuen Steigung vony2, ein zus¨atzliches Ereignis e3 eintreten wird.

Weil nur zum Zeitpunktt2 benachbarte Funktionen auf Schnitt gete- stet werden, wird dieses Ereignis zum jetzigen Zeitpunkt nicht erkannt.

t3: Das Ereignise2tritt ein, welches wegen der Tatsache, dassy3als gr¨oßte Funktion beteiligt ist, ein externes Ereignis ist. Als Folge des Ereig- nisses verlieren die ZertifikateZ3 und Z5 ihre G¨ultigkeit. Statt dessen werden die Zertifikate Z6 = (t1 ist gr¨oßte Funktion) und Z7 = (y3 ist mittlere Funktion) erstellt. Weiterhin muss ¨uberpr¨uft werden, ob mit den neuen Nachbarn neue Schnitt-Ereignisse stattfinden, oder alte nicht mehr auftreten k¨onnen. Dies ist in diesem Fall das eben schon erw¨ahnte Ereignis e3, welches zum Zeitpunkt t4 auftreten wird. Die priority queue wird entsprechend aktualisiert.

t4: Auch hier tritt wieder ein Schnitt-Ereignis auf, welches analog zu den oben betrachteten bearbeitet wird.

Bleibt noch zu erw¨ahnen, welche Eigenschaften die betrachtete kinetische Datenstruktur hat:

Aufgrund der Tatsache, dass jedes Ereignis nur h¨ochsten zwei Zertifi- kate bedroht, n¨amlich die der beteiligten Funktionen, ist die kinetische Datenstrukturlokal.

Da nur sehr wenige Ereignisse eine Ver¨anderung des Attributes mit sich f¨uhren, ist die kinetische Datenstruktur nichteffizient.

Die kinetische Datenstruktur istkompakt, da es genau so viele Zertifi- kate wie betrachtete Objekte gibt.

(9)

Die Antwortzeit bei einem Ereignis ist in diesem Beispiel konstant.

Folglich ist die kinetische Datenstrukturresponsiv.

F¨ur weitere Beispiele und Hintergr¨unde sei aufData Structures for Mo- bile Data von Basch, Guibas und Herschberger[1] verwiesen.

(10)

2 Der Segmentbaum

2.1 Eine Problem-Situation y

x

s1

s2

s3 s4

0 1 2 3 4 5 q 6 7

Abbildung 3: Liniensegmente mit einer Aufspieß-Anfrageq.

Angenommen man hat eine Menge vonnLinien-Segmenten in der Ebene und m¨ochte regelm¨aßig wissen, welche dieser Segmente von einer senkrech- ten Aufspieß-Anfrage geschnitten wird. Als Beispiel nehme man folgende Anordnung aus Abbildung 3. Man sieht vier Liniensegmente, die in der Ebe- ne liegen und eine Aufspieß-Anfrage q. Naiv l¨asst sich eine solche Anfrage in linearer Zeit abh¨angig von der Anzahl der Liniensegmente beantworten.

Man k¨onnte zum Beispiel bei jedem der Liniensegmente pr¨ufen, ob je ein Endpunkt links und einer rechts von der Aufspießanfrage liegt. Dies ist je- doch nicht optimal.

Wenn man sich einmal genauer das Problem anschaut, so f¨allt auf, dass ei- gentlich nur die X-Koordinaten der Endpunkte interessant sind. Denn allei- ne mit ihnen kann man die Aufspieß-Anfrage schon beantworten. Nat¨urlich k¨onnte man das Problem mit der Aufspieß-Anfrage analog f¨ur gesuchte Y- Werte formulieren. Die Verfahrensweise bleibt die gleiche. Hier wird das Pro- blem jedoch ausschließlich f¨ur Anfragen bzgl. eines X-Wertes beschrieben. In Abbildung 3 sind an den Endpunkten senkrechte Linien angebracht, die eine Projektion der Liniensegmente auf die X-Achse darstellen. Die projizierten Endpunkte begrenzen Intervalle auf der X-Achse, welche zu einem oder meh- reren Liniensegmenten geh¨oren. Die Intervall-Grenzen sind in der Abbildung in der Reihenfolge ihrer X-Koordinaten durchnummeriert. Man sieht nun, dass die Segmente in eine Menge von Intervallen zerfallen. So besteht zum Beispiel das Segment s1 aus den Intervallen [1 : 2],[2 : 3],[3 : 4],[4 : 5] und [5 : 6], Segment s2 aus den Intervallen [0 : 1],[1 : 2] und [2 : 3], Segment s3 aus den Intervallen [2 : 3],[3 : 4] und [4 : 5] und Segment s4 schließlich aus den Intervallen [4 : 5],[5 : 6] und [6 : 7]. Umgekehrt kann man nun jedem dieser Intervalle alle Segmente zuordnen, die dieses Intervall enthalten.

(11)

Intervall Liniensegmente

[0 : 1] s2

[1 : 2] s1, s2 [2 : 3] s1, s2, s3 [3 : 4] s1, s3 [4 : 5] s1, s3, s4 [5 : 6] s1, s4

[6 : 7] s4

Tabelle 1: Intervalle und dazugeh¨orige Liniensegmente.

Betrachtet man nun die Aufspieß-Anfrage, so muss gekl¨art werden, in welchem der obigen Intervalle sie liegt. Verwendet man ein Array mit wahl- freiem Zugriff, so l¨asst sich diese Frage in O(logn) mit Hilfe einer bin¨aren Suche beantworten. Als Vergleichskriterium dienen die X-Koordinaten der Endpunkte, die ja die Intervalle darstellen, und die X-Koordinate der Aufspieß- Anfrage. Hat man das Intervall bestimmt, so kann man in konstanter Zeit in einer Tabelle, der gleichen Form wie Tabelle 1, die gesuchten Liniensegmen- te nachschlagen. Der Gesamtaufwand der Aufspieß-Anfrage w¨are folglich in O(logn). Allerdings w¨are der Speicherplatz-Aufwand im worst case in O(n2). Dies l¨asst sich vermeiden, in dem eine Hierarchie aufgebaut wird, die benachbarte Intervalle sukzessive zusammen fasst und die Liniensegmente in den gr¨oßtm¨oglichen Intervallen speichert. Hier kommen die Segmentb¨aume ins Spiel, die dies leisten. Dabei ben¨otigen sie f¨ur eine Anfrage insgesamt auch nurO(logn) viel Zeit!

2.2 Definition und Aufbau des Segmentbaumes

Segmentb¨aume sind Datenstrukturen, die eine Menge von Intervallen spei- chern und Aufspießanfragen erlauben. Die Anwort auf solche Aufspieß-Anfragen sind nun alle diejenigen Intervalle, welche den angefragten Wert enthalten[3].

Definition 2 Seien I = {i0, . . . , in−1} n Intervalle mit je zwei (m = 2n) Endpunkten. F¨ur alle Intervalle ausI miti= [a:b] geltea, b∈ {0, . . . , m− 1}. Weiterhin seien alle Intervalle [j :j+ 1],∀j IIN Elementar-Intervalle.

Ein Segmentbaum ist ein vollst¨andiger Bin¨arbaum mitw, m≤w <2m Bl¨attern, der folgende Bedingungen erf¨ullt:

1. Die Bl¨atter des Segment-Baumes enthalten als Beschriftung die Elementar- Intervalle.

2. Die Beschriftung des Vaterknoten ist die Vereinigung der Beschriftung seiner Kinder.

(12)

3. Die Intervalle aus I werden mit Algorithmus 2.1 in den Baum ein- gef¨ugt, wobei i das einzuf¨ugende Intervall und node die Wurzel des Segmentbaumes ist. Die eingef¨ugten Intervalle werden dabei in den Bl¨attern des Baumes, meist als Referenz, gespeichert. Die Funktion interval(node) gibt dabei das Interval der Beschriftung wieder und hat nichts mit den gespeicherten Intervallen zu tun.

Algorithm 2.1procedure insert(i: TInterval, node: TSegTreeNode) if interval(node)⊆i then

f¨ugei zur Intervall-Menge vonnode hinzu;

else

left := leftChild(node);

right := rightChild(node);

if left 6=nil and interval(left)∩i 6=∅then insert(i,left);

end if

if right 6=nil and interval(right)∩i 6=∅then insert(i,right);

end if end if

Die Mengen von Intervallen in den Knoten werden im folgendenSegment- listengenannt, da die gespeicherten Intervalle gerade die Segmente repr¨asen- tieren. Sowohl der Speicherplatzbedarf, als auch die Dauer des Aufbaus eines Segmentbaumes ist inO(nlogn), dies sei hier nur erw¨ahnt und kann in der entsprechenden Literatur[3] nachgelesen werden.

2.3 Anwendungsbeispiel

Ausgehend von der bekannten Abbildung 3 sieht man vier Liniensegmen- te, die in einem Segmentbaum gespeichert werden sollen, damit Anfragen der Art:

”welche Segmente werden von der vertikalen Linie q geschnitten“, beantwortet werden k¨onnen. Dazu werden die Endpunkte nach ihren X- Koordinaten sortiert, wobei man hier von Punkten in allgemeiner Lage aus- geht. Die Folgen-Nummer der sortierten Endpunkte wird dabei als Rang bezeichnet; er ist in Abbildung 3 unter den jeweiligen Endpunkten an der X-Achse vermerkt. Die R¨ange der beiden Endpunkte repr¨asentieren nun ein Intervall der Form, wie sie in Segmentb¨aumen gespeichert werden k¨onnen.

Diese Intervalle werden nun definitionsgem¨aß in einen Segmentbaum f¨ur vier Intervalle eingef¨ugt. Das Ergebnis kann man in Abbildung 4 sehen.

M¨ochte man nun eine Anfrageqstellen, so muss man, wie bei der anfangs be- schriebenen Tabelle wissen, zwischen welchen R¨angen sich die X-Koordinate der Anfrage befindet. Dieses Problem l¨ost man, wie oben beschrieben, mit

(13)

einer bin¨aren Suche. Hat man die R¨ange ermittelt, so f¨allt auf, dass es stets auf einander folgende R¨ange (ein Elementar-Intervall), oder ein Rang ganz außen ist (die Anfrage liegt links oder rechts von allen Segmenten). Liegt der zweite Fall vor, so ist die Treffermenge leer, ansonsten geht man von der Wurzel aus bis zum ermittelten Elementar-Intervall, im Beispiel das In- tervall [5 : 6] und vereinigt die Segmentlisten der besuchten Knoten zur TreffermengeH={s1, s4}.

[0 : 1] [1 : 2] [2 : 3] [3 : 4] [4 : 5] [5 : 6] [6 : 7] [7 : 8]

[4 : 6] [6 : 8]

[0 : 2] [2 : 4]

[0 : 8]

[4 : 8]

[0 : 4]

s2

s2 s1

s1, s3 s1, s4

s3 s4

q

Abbildung 4: Der ausgef¨ullte Segmentbaum mit Aufspieß-Anfrage.

Anhand des obigen Beispiels sieht man, dass der Segmentbaum, bei einer Aufspieß-Anfrage, maximal einmal komplett von der Wurzel bis zum ange- fragten Blatt durchlaufen wird. Daraus folgt seine Laufzeit vonO(logn) bei einer Aufspieß-Anfrage. Bei Fragen oder weiterem Interesse, sei einem das Kapitel ¨uber Segmentb¨aume in Computational Geometry: Algorithms and Applications von de Berg et al.[3] nahe gelegt.

(14)

3 Der kinetische Segmentbaum

Der kinetische Segmentbaum, so wie er von de Berg, Comba und Guibas[2]

vorgestellt wird, beruht im wesentlichen auf dem oben vorgestellten, stati- schen Segmentbaum. Dieser wird jedoch durch zus¨atzliche Strukturen erg¨anzt, um die Laufzeit der hinzugef¨ugten Algorithmen zu verbessern, indem Zu- griffe auf bestimmte Elemente des Baumes vereinfacht werden.

3.1 Erweiterungen bez¨uglich des Segmentbaumes

1. Die Knoten des Segmentbaumes τ werden mit parent-pointer ausge- stattet, um in konstanter Zeit Zugriff auf den Vaterparent(node) eines Knotennodezu erhalten.

2. Es wird ein Array E[i] angelegt, welches einen Zeiger auf das Blatt des Segmentbaumes enth¨alt, welches das Elementar-Intervall [i:i+ 1]

repr¨asentiert.

3. Die Segmentlisten der KnotenS(node) werden als doppelt verkettete Listen implementiert. Dadurch k¨onnen Segmente in konstanter Zeit eingef¨ugt und mit Hilfs-Zeigern sogar in konstanter Zeit entfernt wer- den.

4. Es wird ein Array von FragmentlistenL[s] angelegt, in dem f¨ur jedes Segment s eine Fragmentliste existiert. Eine Fragmentliste speichert einen Zeiger auf jeden Knotennode, in dessen SegmentlisteS(node)s vorkommt. Zus¨atzlich wird ein Hilfs-Zeiger auf den Listeneintrag mit s in der Segmentliste des Knoten gespeichert. Dieser wird ben¨otigt, um Intervalle an den Enden von Segmenten in konstanter Zeit zu ent- fernen. Dabei liegt diese doppelt verkettete Liste geordnet vor. Ange- fangen vom Anfang der ListeL[s].front bis zum EndeL[s].back liegen die Knoten, in deren Segmentlisten s vor kommt, in der Reihenfolge vor, wie sie bei einemInorder-Durchlauf angetroffen werden. Auf die- se Weise k¨onnen die Fragmentlisten auch bei der Initialisierung des Segmentbaumes angelegt werden.

5. Ein ArrayR[0 :m−1] wird angelegt, so dass R[i] genau den Knoten enth¨alt, dessen Rang i ist. Dieses Array wird ben¨otigt, um die oben beschriebenen Aufspieß-Anfragen inO(logn) ausf¨uhren zu k¨onnen.

Weil der kinetische Segmentbaum eine kinetische Datenstruktur ist, be- sitzt dieser auch ein Attribut, Zertifikate und Ereignisse. Das Attribut, das erhalten wird, ist ein g¨ultiger Segmentbaum f¨ur n Liniensegmente in der Ebene mit sich bewegenden Endpunkten. Die Bewegung wird durch Funk- tionenfi : IR −→ IR2, fi(t) 7−→ (x, y), i 0,· · ·, m−1 beschrieben. Wobei die Position jedes Endpunktes durch eine eigene Funktionfi berechnet wird.

(15)

Der Parameter t kann dabei als Zeitpunkt aufgefasst werden, an dem die Positions-Funktion ausgewertet wird. Die Art der Bewegung ist dabei nicht explizit festgelegt. Es muss jedoch berechenbar sein, wann zwei Punkte ih- ren Rang wechseln. Die Zertifikate seien die R¨ange der Endpunkte, denn solange die R¨ange unver¨andert sind, muss auch nicht der Segmentbaum ak- tualisiert werden; da die Anzahl der Zertifikate proportional zur Anzahl der gespeicherten Liniensegmente ist, folgt dieKompaktheit. Als Ereignisse wer- den alle Situationen betrachtet, wo sich der Rang eines Punktes ¨andert. Wie man leicht sehen kann, passiert dies genau dann, wenn sich die Reihenfol- ge von zwei Punkten ¨andert. Es werden also stets genau zwei Zertifikate gleichzeitig durch ein Ereignis bedroht und daraus folgt, dass der kinetische Segmentbaumlokal ist. Des Weiteren m¨ussen, wenn sich die Reihenfolge von zwei Endpunkten vertauscht, drei neue Ereignisse berechnet und zwei alte verworfen werden. Entsprechend muss diepriority queue angepasst werden.

Lemma 3 Ein kinetischer Segmentbaum ist lokal und kompakt.

3.2 Ein Ereignis tritt ein

Wie schon erw¨ahnt tritt ein Ereignis ein, wenn zwei benachbarte Endpunk- teR[i], R[i+ 1] die R¨ange tauschen. Dem zur Folge m¨ussen die Zertifikate von beiden Punkten angepasst werden, damit das Attribut erhalten wird.

Seien ab jetzt sa =segment(R[i]) und sb =segment(R[i+ 1]) die zu den Endpunkten geh¨orenden Segmente. So k¨onnen als Ereignis vier F¨alle eintre- ten, wie man in Abbildung 5 sehen kann. Bei Fall vier ¨andern sich nur die R¨ange innerhalb eines Liniensegmentes, wodurch das Intervall an sich kon- stant bleibt und der Segmentbaum nicht ver¨andert werden muss. Bei Fall eins werden beide Segmente um das Intervall [i:i+ 1] reicher, im Fall zwei um das selbe Intervall ¨armer. Im Fall drei wird ein Segment erweitert, das andere gek¨urzt.

(16)

Fall 1 Fall 2

Fall 4

sa=sb sb

sa

sb

sa

i+ 1 i

i i+ 1 X i i+ 1 X

X X

i i+ 1 sb

sa Fall 3

Abbildung 5: Vier m¨ogliche Ereignisse.

3.3 Erweitern eines Segmentes

Hier ist der Fall, dass ein Segment um ein Elementar-Intervall [i : i+ 1]

erg¨anzt werden muss. Da dieses Elementar-Intervall immer am ¨außeren En- de eines Segmentes hinzugef¨ugt wird, beginnt man im Blattnode=E(i) des Segmentbaumes, welches dieses Intervall repr¨asentiert und wendet rekursiv Algorithmus 3.1 an, wobei s das jeweilige Segment sa, sb ist. Die Funkti- on sibling(node) bestimmt dabei mit Hilfe des parent-pointers den Bruder des Knoten in konstanter Zeit. Dies gilt f¨ur alle Knoten außer der Wurzel, da der Segmentbaum ein vollst¨andiger Bin¨arbaum ist. Weil der Algorith- mus h¨ochstens den Baum von einem Blatt bis zur Wurzel durchl¨auft, ist seine Laufzeit proportional zur H¨ohe des Segmentbaumes. Sie liegt also in O(logn). Diese Annahme stimmt jedoch nur dann, wenn die Frage, obsin der SegmentlisteS(node) ist, in konstanter Zeit beantwortet werden kann.

Dies ist allerdings nicht m¨oglich. Deshalb bedient sich der Algorithmus einer besonderen Eigenschaft, der betrachteten Knoten. Alle Knoten, die w¨ahrend des Erweiterns besucht werden und das Segmentsbereits in ihren Listen ha- ben, m¨ussen auch in der FragmentlisteL[s] enthalten sein. Da diese Knoten zugleich aber auch die ¨außersten Intervalle des Segmentes repr¨asentieren, sind sie entweder der erste L[s].front oder letzte L[s].back Eintrag in der Fragmentliste. Folglich l¨asst sich die obige Elementfrage ¨uber einen Umweg in konstanter Zeit beantworten. ¨Ahnlich verh¨alt es sich mit dem Entfernen von Segmenten aus den Segmentlisten. Naiv ist dies n¨amlich auch nicht in

(17)

konstanter Zeit m¨oglich. Hier bedient man sich ebenfalls der Fragmentli- sten, denn das Segment wird nur aus genau den Segmentlisten der Knoten entfernt, die außen in den Fragmentlisten gespeichert werden. Hier kommen nun die Hilfs-Zeiger in den Fragmentlisten zum Einsatz. Mit dessen Hilfe ist man in konstanter Zeit bei dem Segment in der Segmentliste, welches gel¨oscht werden soll. Das L¨oschen geschieht dann durch einfaches umbiegen der Zeiger.

Algorithm 3.1procedure expand(s: TSegment,node : TKSTNode) if node = root(tree) then

S(node).add(s);

else

other = sibling(node); // Bruderknoten vonnode if s∈ S(other) then

S(other).remove(s); // Segment aus Bruderknoten entfernen.

expand(s,parent(node));

else

S(node).add(s);

end if end if

3.4 Ein Beispiel f¨ur das Erweitern

Betrachtet man die Beispiel-Segmente aus Kapitel zwei und nimmt an, dass sich aufgrund der Bewegung der Endpunkte die Reihenfolge der Endpunkte mit den R¨angen 3 und 4 vertauschen, dann w¨urde folgendes passieren: Der Segmentbaum m¨usste aktualisiert werden, in dem die Segmente s2 und s4 jeweils um das Elementar-Intervall [3 : 4] erweitert werden. Hier wird dieser Vorgang exemplarisch nur f¨ur das Segments2betrachtet, die Verfahrenswei- se bei Segment s3 ist jedoch vergleichbar.

1. Das Einf¨ugen beginnt mit dem Aufruf von Algorithmus 3.1 mit den Pa- rameterns=s2 und node=E[3]. Der Algorithmus beginnt dadurch in dem Knoten node des Segmentbaumes, welcher das Elementar- Intervall [3 : 4] repr¨asentiert.

2. Es wird ¨uberpr¨uft, ob das Segments2 im Bruderknoten von node ge- speichert ist.

3. Da dies der Fall ist, wird das Segment s2 aus der Segmentliste des Bruderknotens entfernt und der Algorithmus ruft sich selbst mit den Parameterns=s2 undnode= parent(node) erneut auf. Das Vorgehen bis zu diesem Schritt wird in Abbildung 6 dargestellt.

(18)

[0 : 1] [1 : 2] [2 : 3] [3 : 4] [4 : 5] [5 : 6] [6 : 7] [7 : 8]

[4 : 6] [6 : 8]

[0 : 2] [2 : 4]

[0 : 8]

[4 : 8]

[0 : 4]

s2

s2

s1

s1, s3 s1, s4

s3 s4

E[3]1.

2.

3.

Abbildung 6: expand(s2,E[3]).

4. In Abbildung 7 sieht man nun, dass der Algorithmus in der n¨achst h¨oheren Ebene gleich verf¨ahrt.

5. Es wird abermals getestet, ob im Bruderknoten, der jetzt neuennode, das Segments2 gespeichert ist.

6. Da dies ebenfalls wieder der Fall ist, wird auch hier dieser Eintrag entfernt und der Algorithmus f¨ahrt in der n¨achsten Ebene des Baumes fort.

7. In diesem Schritt beginnt der Algorithmus mit dem Großvater des urspr¨unglichen Startknotens.

8. Ein weiteres mal wird der Bruder von node = parent(parent(E[3])) getestet, hier jedoch ist das Segment nicht in dessen Liste enthalten.

Der Algorithmus ist am Ziel.

9. Zuletzt wird s2 in die Segmentliste vonnode eingetragen und der Al- gorithmus terminiert. Diese drei letzten Schritte sieht man in Abbil- dung 8.

(19)

[0 : 1] [1 : 2] [2 : 3] [3 : 4] [4 : 5] [5 : 6] [6 : 7] [7 : 8]

[4 : 6] [6 : 8]

[0 : 2] [2 : 4]

[0 : 8]

[4 : 8]

[0 : 4]

s2

s1

s1, s3 s1, s4

s3 s4

4.

6. 5.

Abbildung 7: expand(s2, parent(E[3])).

[0 : 1] [1 : 2] [2 : 3] [3 : 4] [4 : 5] [5 : 6] [6 : 7] [7 : 8]

[4 : 6] [6 : 8]

[0 : 2] [2 : 4]

[0 : 8]

[4 : 8]

[0 : 4]

s1

s1, s3 s1, s4

s3 s4

7.

9. 8.

s2

Abbildung 8: expand(s2, parent(parent(E[3]))).

(20)

3.5 K¨urzen eines Segmentes

Will man ein Segment sum ein elementares Intervall k¨urzen, so geht man entgegen gesetzt vor. Man bestimmt den Knoten node aus der Fragment- liste L[s], der das zu entfernende Intervall enth¨alt. Da dies entweder der erste L[s].front oder der letzte Knoten L[s].back der Liste ist, kann man dies stets in konstanter Zeit tun. Hat man den Knoten bestimmt, so ent- fernt die rekursive Anwendung von Algorithmus 3.2 das Intervall [i:i+ 1]

aus dem Segment s. Auch dieser Algorithmus durchwandert den Segment- baum h¨ochstens einmal komplett von der Wurzel bis zu einem Blatt. Daraus folgt seineworst case Laufzeit vonO(logn). Auch hier muss man etwas ge- nauer hinschauen, denn die Operation S(node).remove(s) ist ja, wie oben beschrieben naiv nicht in konstanter Zeit umzusetzen. Das erste remove, das durch den Algorithmus ausgef¨uhrt wird, findet bei einem Knoten, der in der Fragmentliste außen gespeichert ist, statt. Wie oben beschrieben, l¨asst sich hier nun der Hilfs-Zeiger der Fragmentliste verwenden, um das Segment in konstanter Zeit aus der Segmentliste zu entfernen. Damit dies auch bei den folgenden, rekursiven Aufrufen des Algorithmus gew¨ahrleistet ist, muss bei den zwei Hinzuf¨uge-Operationen in die Kinderknoten die Fragmentliste in der richtigen Reihenfolge aktualisiert werden. So muss das Segment zu- erst in die Segmentliste des Knotens eingef¨ugt werden, dessen Beschriftung nicht das zu entfernende Elementar-Intervall enth¨alt. Wird das Segment in die Segmentliste eingef¨ugt, so wird gleichzeitig die Fragmentliste um den Knoten und den entsprechenden Hilfs-Zeiger erweitert.

Algorithm 3.2 procedure truncate(s : TSegment, node : TKSTNode, i : integer)

S(node).remove(s);

if is leaf(node) then exit;

else

left := leftChild(node);

right := leftChild(node);

if [i :i+ 1]interval(left) then S(right).add(s);

S(left).add(s);

truncate(s,left,i);

end if

if [i :i+ 1]interval(right)then S(left).add(s);

S(right).add(s);

truncate(s,right,i);

end if end if

(21)

3.6 Ein Beispiel f¨ur das K¨urzen

Man betrachte wieder die Liniensegmente aus Kapitel zwei und nehme an, dass die Endpunkte mit R¨angen vier und f¨unf die Reihenfolge tauschen.

In diesem Fall m¨ussten die Segmente s3 und s4 jeweils um das Elementar- Intervall [4 : 5] gek¨urzt werden. Auch hier wird wieder nur ein Segment betrachtet, in diesem Fall das Segments4. Im Gegensatz zu Algorithmus 3.1 wird der K¨urzen-Algorithmus nicht in einem Elementar-Intervall gestartet, sondern in dem Knoten, der sowohl das Elementar-Intervall in der Beschrif- tung, als auch das betrachtete Segment in der Segment-Liste enth¨alt. Dieser Knoten l¨asst sich, wie oben beschrieben, in konstanter Zeit mit Hilfe der Fragmentliste L[s2] des Segmentes bestimmen. In diesem Fall ist der ge- suchte Knoten L[s2].front. Algorithmus 3.2 wird also mit den Parametern s=s4,node=L[s2].front und i= 4 aufgerufen.

1. In Abbildung 9 sieht man, wie der Algorithmus 3.2 mit Hilfe der Frag- mentliste zum Knoten mit der Beschriftung [4 : 6] springt.

[0 : 1] [1 : 2] [2 : 3] [3 : 4] [4 : 5] [5 : 6] [6 : 7] [7 : 8]

[4 : 6] [6 : 8]

[0 : 2] [2 : 4]

[0 : 8]

[4 : 8]

[0 : 4]

s2

s2

s1

s1, s3 s1, s4

s3 s4

L[s2].front 1.

2.

Abbildung 9: Sprung in den Baum.

2. Das Segment s4 wird aus der Segmentliste des Knotens mit der Be- schriftung [4 : 6] entfernt.

3. Abbildung 10 zeigt nun, wie das Segment zuerst zur Segmentliste des Knotens mit der Beschriftung [5 : 6] hinzugef¨ugt wird, da dessen Be- schriftung nicht das zu entfernende Elementar-Intervall enth¨alt. Da- nach erst wird es zur Segmentliste des Knotens mit der Beschriftung [4 : 5] hinzugef¨ugt.

4. Der Algorithmus ruft sich selbst mit den Parametern s=s4, node= leftChild(node) und i= 4 auf.

(22)

[0 : 1] [1 : 2] [2 : 3] [3 : 4] [4 : 5] [5 : 6] [6 : 7] [7 : 8]

[4 : 6] [6 : 8]

[0 : 2] [2 : 4]

[0 : 8]

[4 : 8]

[0 : 4]

s2

s2

s1

s1, s3 s1

s4 s4

s3, s4

3.a.

b.

Abbildung 10: Erst rechts, dann links hinzuf¨ugen!.

[0 : 1] [1 : 2] [2 : 3] [3 : 4] [4 : 5] [5 : 6] [6 : 7] [7 : 8]

[4 : 6] [6 : 8]

[0 : 2] [2 : 4]

[0 : 8]

[4 : 8]

[0 : 4]

s2

s2

s1

s1, s3 s1

s4 s4

s3, s4

4.

5.

Abbildung 11: Der letzte Schritt.

5. Erneut wird das Segments4 aus der Segmentliste des aktuellen Kno- tensnode entfernt. Da in diesem Fall der Knoten ein Blatt ist, termi- niert der Algorithmus. Dies zeigt Abbildung 11.

(23)

3.7 Was ist sonst noch zu beachten?

In allen obigen F¨allen m¨ussen nun bis zu drei neue Ereignisse bestimmt und bis zu zwei ung¨ultige aus derpriority queue entfernt werden. Die beiden al- ten Ereignisse waren die Zeitpunkte, wann die beiden Knoten mit ihren alten Nachbarn die Pl¨atze getauscht h¨atten. Diese Ereignisse werden offensichtlich so nicht mehr auftreten k¨onnen und werden aus derpriority queue gel¨oscht.

Die neuen Ereignisse beruhen auf der Tatsache, dass nun die Knoten, die die R¨ange getauscht haben, je einen neuen Nachbarn besitzen, mit denen sie sp¨ater einmal die Pl¨atze tauschen k¨onnen. Nat¨urlich k¨onnen sie auch unter- einander erneut die R¨ange wechseln. Diese Ereignisse werden berechnet und gem¨aß ihres Eintretens in die priority queue einsortiert. Man muss jedoch auch bedenken, dass zum weiteren Funktionieren des kinetischen Segment- baumes auch seine zus¨atzlichen Strukturen aktualisiert werden m¨ussen. So muss beim Einf¨ugen eines Segmentes in die Segmentliste eines Knotens auch die Fragmentliste des Segmentes um den Knoten und den Hilfs-Zeiger er- weitert werden. Damit das Entfernen von Rand-Intervallen des Segmentes in konstanter Zeit erfolgen kann. Diese Aktualisierungen der Fragmentli- sten k¨onnen in konstanter Zeit erfolgen, da sie immer nur an den ¨außersten Enden ver¨andert werden. Das Array R[i] mit den, nach R¨angen sortierten, Endpunkten kann in konstanter Zeit aktualisiert werden. Dazu werden zwei Eintr¨age genau dann vertauscht, wenn ihre Endpunkte ihre X-Koordinate tauschen. Dies geschieht genau dann, wenn ein Ereignis statt findet. Alle anderen Strukturen m¨ussen nur w¨ahrend des Aufbaus des kinetischen Seg- mentbaumes einmalig initialisiert werden und bleiben danach konstant. Da die Aktualisierungen der zus¨atzlichen Strukturen nicht besonders kompli- ziert sind und stets inO(1) ablaufen, wurde auf eine explizierte Darstellung in den Algorithmen f¨ur das Erweitern und das K¨urzen von Linien-Segmenten verzichtet.

Lemma 4 Das Hinzuf¨ugen und Entfernen von Elementar-Intervallen ben¨otigt maximal O(logn) viel Zeit, folglich ist der kinetische Segmentbaum respon- siv.

(24)

4 Genauere Betrachtung der Antwortzeit

Nach Lemma 4 ben¨otigen die oben vorgestellten AlgorithmenO(h) viel Zeit, wobeih = logw die H¨ohe des vollst¨andigen Bin¨arbaumes τ ist. Wenn man die Algorithmen jedoch genauer betrachtet, so l¨asst sich die erwartete H¨ohe, die sie durchlaufen, nach oben absch¨atzen. Sie verlaufen nur innerhalb der Teilb¨aume, an dessen ¨außeren Rand sich das Elementar-Intervall befindet, das hinzugef¨ugt oder entfernt wird. SeiE(i) das Blatt mit dem Elementar- Intervall [i : i+ 1] und h(i) die H¨ohe des Teilbaumes von τ in dem E(i) ganz links oder ganz rechts liegt. Dann ist H(h) = 21hP2i=0h−1h(i) die er- wartete H¨ohe der Teilb¨aume, die der Algorithmus bei zuf¨alliger Wahl voni durchlaufen muss.

Lemma 5 H(h) eines vollst¨andigen Bin¨arbaumes ist inO(1).

Beweis. Die oben betrachtete, erwartete H¨ohe der Teilb¨aume l¨asst sich rekursiv definieren: F¨ur einen Baum der H¨ohe 0 gilt trivialerweiseH(0) = 0.

F¨ur einen Baum mit H¨oheh >0 gilt nun (vgl. Abbildung 12):

H(h) = 2·1

2H(h−1)2· 1

2h(h1) + 2· 1 2hh

Wobei der Term −2· 21h(h1) die beiden ¨außersten Wege innerhalb der Teilb¨aume bezeichnet. Diese werden nun beim Schritt h 1 h ersetzt durch die beiden Wege der L¨ange h bis zur neuen Wurzel. Daf¨ur steht der Term +2· 21hh. Die Br¨uche in beiden Termen beschreiben den Einfluss auf die erwartete H¨ohe. Daraus folgt nun:

h1 h H(h1) H(h1)

Abbildung 12: Erwartete H¨ohe eines vollst¨andigen Bin¨arbaumes.

H(h) = 2·1

2H(h−1)2· 1

2h(h1) + 2· 1 2hh

= H(h−1) 1

2h−1(h1) + 1 2h−1h

(25)

= H(h−1) + 1 2h−1

= H(h−2) + 1

2h−2 + 1 2h−1

= H(h−3) + 1

2h−3 + 1

2h−2 + 1 2h−1 ...

= 1

20 +. . .+ 1 2h−1

=

h−1X

i=0

1 2i

Diese Summe ist, wie man leicht sieht, f¨ur steigendehstreng monoton wach- send. F¨urh→ ∞, ergibt sich:

h→∞lim H(h) = lim

h→∞

h−1X

i=0

1 2i

= X i=0

1 2i

= 1

112

= 2

Daraus folgt, dasH(h) f¨ur beliebigeh≥0 von oben durch 2 beschr¨ankt ist.

2 Es sei erw¨ahnt, dass der zuletzt gelieferte Beweis nur dann gilt, wenn ein zuf¨alliges Elementar-Intervall gew¨ahlt wird. Da aber bei einem kinetischen Segmentbaum, aufgrund des Aufbaus, h¨aufig auch die Rand-Intervalle mit den gr¨oßten H¨ohen auftreten, bedient man sich eines kleinen Tricks: Die n Segmente mit den ermittelten R¨angen ihrer 2n Endpunkten werden nicht, wie oben beschrieben, in einen Segmentbaum mit etwa 2nBl¨attern, sondern in einen Segmentbaum mit doppelt so vielen Bl¨attern eingeordnet. Zuvor werden zus¨atzlich alle R¨ange um eine zuf¨allige Zahlr∈[0 : 2n] verschoben.

Dies soll der Charakteristik der zuf¨allig gew¨ahlten Elementar-Intervalle nahe kommen und zus¨atzlich die eben angesprochenen großen H¨ohen vermeiden.

Durch diesen Trick wird eine erwarteteAntwortzeitvonO(1) erreicht, wobei dieworst case response time bei O(logn) verbleibt.

Theorem 6 Der von de Berg, Comba und Guibas[2] vorgestellte kineti- sche Segmentbaum ist lokal, responsiv und kompakt. Aufgrund der Tatsa- che, dass es keine internen Ereignisse gibt, ist er zus¨atzlich effizient. Der Speicherplatzverbrauch und Aufbau bewegt sich in der selben Gr¨oßenordnung O(nlogn) wie beim klassischen Segmentbaum. Und die worst case Antwort- zeit liegt in O(logn), bei einer erwarteten Antwortzeit von O(1).

(26)

Literatur

[1] Basch, Guibas, and Hershberger. Data structures for mobile data. In SODA: ACM-SIAM Symposium on Discrete Algorithms (A Conference on Theoretical and Experimental Analysis of Discrete Algorithms), 1997.

[2] M. de Berg, J. Comba, and L. J. Guibas. A segment-tree based kinetic BSP. InSymposium on Computational Geometry, pages 134–140, 2001.

[3] M. de Berg, O. Schwarzkopf, M. van Kreveld, and M. Overmars. Segment trees. In Computational Geometry: Algorithms and Applications, pages 223–229, 2000.

[4] M. S. Paterson and F. F. Yao. Efficent binary space partitions for hidden surface removal and solid modeling. InDiscrete Computational Geome- try, pages 99–113, 1990.

Referenzen

ÄHNLICHE DOKUMENTE

Alle bislang durchgeführten Familien- studien zeigen, dass erstgradig Verwand- te von Patienten mit einer Bipolar-I-Stö- rung ein im Vergleich zur Allgemeinbe- völkerung

Zuordnung Studiengang Modus Studiensemester.. Informatik 2007

Endpunkt eine „virtuelle“ Kante zum Startpunkt eingefügt werden, um einen zyklischen Graph (laut Definition zyklische Zahl) zu erhalten. Zyklomatische Komplexität

Die Probanden erhielten nach jeder Zuordnung eines Stimulus eine positive oder negative Rückmeldung über die Richtigkeit ihrer Wahl. In zwei Durchgängen wurden

In der Generativen Phonologie gemäß (C HOMSKY und H ALLE 1968) wird die Beto- nung als ein phonologisches Merkmal von Vokalen betrachtet. Als einziges phonolo- gisches Merkmal ist

eine Erklärung darüber, ob der Studierende in diesem Studiengang eine Prüfungsleistung oder die Masterprüfung endgültig nicht bestanden hat oder sich zum Zeitpunkt

Studiengang/Teilstudiengang Pflicht-/ Wahlpflicht Fachsemester Bachelor Ein-Fach „Katholische Theologie“ Wahlpflicht 3.. Voraussetzungen für die Vergabe von

der Antrag auf Aussetzung; seine Annahme hat zur Folge, dass der Punkt auf einer kommenden Sitzung wieder aufgenommen werden kann4. Die Wiederaufnahme muss auf der Einladung