Effektives Platzieren von Wächtern in Galerien

Werbung
Rheinische Friedrich-Wilhelms-Universität Bonn
Institut für Informatik I
Andri Bremm
Effektives Platzieren von
Wächtern in Galerien
5. Januar 2009
Seminararbeit im Sommersemester 2008
Zusammenfassung
Die Seminararbeit beschäftigt sich damit, wie man effektiv eine
minimale Anzahl von Wächtern in einem Polygon platziert, so dass
dieses komplett überwacht ist. Dazu werden zwei Ansätze betrachtet.
Im ersten Ansatz sind die Positionen der Wächte auf die Eckpunkte
des Polygons beschränkt und im zweiten Ansatz werden die Wächter
beliebig auf einem engen Raster innerhalb des Polygons plaziert. Außerdem wird die Erweiterung des Algorithmusses auf Polygone mit
Löchern und auf Gelände dargestellt.
Inhaltsverzeichnis
1 Einführung
2
2 Grundlegende Definitionen
2
3 Platzierung der Wächter auf den Eckpunkten
2
4 Exakter Algorithmus für eine feste Anzahl von Wächtern
4
5 Platzierung der Wächter auf einem
5.1 Bereichsanfrage auf einem Raster .
5.2 Erweiterter Suchbaum . . . . . . .
5.3 Verwendung der Datenstruktur . .
5.4 Der Algorithmus . . . . . . . . . .
Raster
. . . . .
. . . . .
. . . . .
. . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
6
7
8
11
14
6 Polygone mit Löchern
17
6.1 Sichtbarkeit in Polygonen mit Löchern . . . . . . . . . . . . . 17
1
1
Einführung
Als das Kunstgalerie-Problem bezeichnent man die Frage, wie groß die minimale Anzahl von Wächtern ist, die benötigt werden, um ein Museum zu
bewachen. Das Museum wird dabei durch ein einfaches Polygon P mit n
Ecken repräsentiert und die Wächter sind Punkte innerhalb des Polygons.
Wir sagen das sich zwei Punkte aus P sehen, wenn eine Gerade zwischen
den beiden Punkten auch in P liegt. Die Bestimmung der minimalen Anzahl von Wächtern ist NP-hart [5]. Um ein effektives platzieren der Wächter
zu ermöglichen, beschäftigen wir uns mit Algorithmen, die mit einer hohen
Wahrscheinlichkeit eine Lösung liefern. Sie wurden 2006 von Alon Efrat und
Sariel Har-Peled [3] vorgestellt.
2
Grundlegende Definitionen
Definition 1 Sei P ein einfaches Polygon. Für ein Punkt q ∈ P bezeichnet
Vis(q) das Sichtbarkeitspolygon von q in P. Vis(q) sind alle Punkte von P,
die von q aus gesehen werden bzw. alle Punke von P die q sehen.
Sein G = {g1 ...gk } eine Menge von k Punkten in P. Dann bezeichnet
V is(G) = V is(g1 ) ∪ V is(g2 ) ∪ ... ∪ V is(gk )
die Vereinigung der Sichtbarkeitspolygone von g1 ...gk .
Theorem 2 Das Sichtbarkeitspolygon Vis(G) ist durch O(nk + k 2 ) Kannten begrenzt. Diese Schranke ist eng im worstcase.
Vis(G) lässt sich effizient mit einem divide and conquer Algorithmus
berechnen. Für einen Punkt q ∈ P lässt sich Vis(q) in O(n) Zeit berechnen. Wenn wir mehr als einen Punkt haben, teilen wir die Menge G in
zwei Hälften mit je ca. k/2 vielen Punkten. Nachdem für beide Teilmengen
das Sichtbarkeitspolygon berechnet wurde, fügen wir sie mit einem SweepVerfahren zusammen. Die Laufzeit ergibt sich aus der benötigten Zeit für
das Berechnen der Sichtbarkeitspolygone der einelementigen Teilmengen und
der Zeit für das Zusammenfügen der Polygone. Insgesammt kommen wir so
auf eine Laufzeit von O((nk + k 2 )log k log n).
3
Platzierung der Wächter auf den Eckpunkten
Der im folgenden beschriebene Algorithmus findet mit hoher Warscheinlichkeit eine möglichst kleine Teilmenge der Eckpunkte des Polygons, so dass,
2
wenn wir auf diesen Punkten die Wächter platzieren, diese das ganze Polygon überwachen können.
Sei V die Menge der n Eckpunkte eines einfachen Polygons P . Alle Eckpunkte, die von einem Punkt q ∈ P gesehen werden bezeichnen wir mit
Vq .
Vq = V ∩ V is(q)
Die Menge aller Teilmengen von V , die von einem Punkt q ∈ P gesehen
werden bezeichnen wir mit V.
V = {Vq | q ∈ P }
Da wir wissen, dass die VC-dimension des Mengensystems Y = (P, {V is(q)|q ∈
P } beschränkt ist, muss auch die VC-dimension unseres kleineren Mengensystems X = (V, V) beschränkt sein.
Eine Menge von Wächtern auf den Eckpunkten von P zu finden, die ganz
P sehen, ist äquivalent dazu eine Menge U ⊆ V zu finden, die aus mindestens
einem Repräsentanten jede Menge aus V besteht. Also dass ∀X ∈ V gilt,
dass X ∩ U 6= ∅.
Algorithmus 3.1 bestimmt mit hoher Wahrscheinlichkeit eine Menge von
Wächtern, die P ganz überwachen. Er ist auf Seite 5 abgebildet. Der Algorithmus versucht anstelle einer optimalen Lösung O(k log k) viele Wächter
zu finden. Die Wächter dürfen nur auf den Eckpunkten des Polygons platziert werden und es gilt: k ≥ copt . Dabei ist copt die kleinstmögliche Anzahl
von Wächtern, mit der P ganz eingesehen werden kann. Wenn copt nicht
bekannt ist, wird k mit 1 initialisiert. Andernfalls kann k auf copt gesetzt
werden. Dann wird die Funktion ComputeGuards(P, k) aufgerufen.
Die Funktion ComputeGuards(P, k) berechnet mit hoher Wahrscheinlichkeit eine Menge von O(k log k) vielen Wächtern, die P überwachen, falls
k ≥ copt ist. Dazu speichert ComputeGuards(P, k) zu jedem Eckpunkt
von P ein Gewicht. Zu Beginn hat jeder Punkt ein Gewicht von 1. Dann
wird O(k log nk ) mal versucht eine geeignete Menge an Wächtern zu finden.
Dazu wählt man zufällig, aber abhäning von ihren Gewichten, O(k log k)
Eckpunkte von P aus. Für die gewählten Wächter prüft man ob sie ganz P
einsehen können. Wenn ja berichtet man die gefundene Menge, ansonsten
sucht man ein Punkt q in P der nicht gesehen wird. Dann verdoppelt man
das Gewicht von jedem Punkt den q sieht, wenn das k fache der Summe
all dieser Gewicht kleiner oder gleich der Hälfte der Gesamtsumme aller
Gewichte ist. Nachdem die Gewichte aktualisiert wurden, versucht man erneut eine geeignete Menge zu finden, unabhängig von den zuvor gewähten
Wächtern. Wird bei allen Versuchen keine geeignete Menge gefunden, wird
die leere Menge zurückgegeben.
Wenn die Funktion ComputeGuards(P, k) keine Menge von Wächtern gefunden hat, ist k wahrscheinlich zu klein gewesen. Daher wird k verdoppelt
3
und die Funktion ComputeGuards(P, k)) erneut aufgerufen. Das wird so oft
wiederholt, bis eine Menge von Wächtern gefunden wurde.
Was für eine Laufzeit hat der Algorithmus? Die Funktion ComputeGuards(P, k)
wird O(logcopt ) mal aufgerufen. Das ergibt sich daraus, dass k nach jedem
Aufruf verdoppelt wird solange bis k ≥ copt ist.
Die Funktion ComputeGuards(P, k) macht O(k log( nk ) Iterationen. Eine Iteration hat einen Aufwand von O(nk log n log k), für den hauptsächlich das
Prüfen, ob die Wächter der gewählten Menge ganz P sehen, verantwortlich
ist.
Damit kommt man für einen Aufruf von ComputeGuards(P, k) auf Kosten von insgesamt O(k log ( nk ) ∗ O(nk log n log k) = O(nk 2 log n log nk log k).
Diese Kosten summieren wir über die O(log copt ) Aufrufe auf.
O
P
log copt
i=1
n(2i )2 log n log
O nc2opt log n log
n
copt
n
(2i )
log (2i ) =
log copt
Theorem 3 Für ein einfaches Polygon P mit n Eckpunkten kann man in
n
O(nc2opt log n log copt
log copt ) erwarteter Zeit, eine Menge S von O(copt log copt )
vielen Wächtern, auf den Eckpunkten von P, berechnen. Dabei ist copt die
Kardinalität der kleinsten Menge an Wächtern, die ganz P sehen.
4
Exakter Algorithmus für eine feste Anzahl von
Wächtern
Theorem 4 Man kann die kleinste Menge von Wächtern, die ein gegebenes
eifaches Polygon mit n Ecken komplett einsenen können in O((nk)3(2k+1) )
Zeit berechnen, wobei k die Kardinalität einer solchen optimalen Menge ist.
Beweis. Die ist eine einfache Konsequenz aus bekannten Techniken der
reell-algebraische Geometrie.
Angenommen, wir wollen zunächst nur feststellen ob es eine Menge von
k Wächtern gibt, die P ganz sehen. Das ist äquivalent dazu, für folgender
prädikatenlogischer Aussage zu entscheiden, ob sie wahr ist.
∃ x1 , y1 , x2 , y2 , ..., xk , yk ∀ u, v |
[InP (u, v) ⇒ (V isib(x1 , y1 ; u, v) ∨ V isib(x2 , y2 ; u, v) ∨ ... ∨ V isib(xk , yk ; u, v))]
Das Prädikat InP (u, v) ist wahr, wenn (u, v) ∈ P . V isib(x, y; u, v) ist wahr,
wenn (x, y), (u, v) ∈ P und sie sich gegenseitig sehen können.
Die prädikatenlogische Aussage formuliert, dass es k Punkte gibt und für
jeden beliebigen Punkt gilt, wenn er in dem Polygon liegt, so wird er von
mindestens einem der k Punkte gesehen.
4
Algorithmus 3.1 Bestimmung der Wächter
// P ist das einfache Polygon für das die Wächter bestimmt werden.
// V ist die Menge der Eckpunkte von P .
// Falls copt unbekannt ist, wird k mit 1 initialisiert.
k := 1;
repeat
S := ComputeGuards(P, k)
if S 6= ∅ then
Berichtet die Wächter S
else
// k ist wahrscheinlich zu klein
k := k + k
end if
until Eine Menge von Wächtern gefunden wurde.
ComputeGuards(P, k){
Jedem Punkt aus V wird ein Gewicht von 1 zugeordnet.
for i = 1 to O(k log( nk )) do
bestimme eine Menge S ⊆ V , indem man O(k logk) Punkte zufällig
und unabhänging wählt, aber entsprechend ihren Gewichten
if Die Punkte von S sehen ganz P then
return S
else
suche einen Punkt q ∈ P der nicht von S sichtbar ist
berechne Vis(q)
W := Summe der Gewichte aus V ∩ V is(q)
if 2kW ≤ Summe aller Gewichte in V then
verdopple die Gewichte aller Punkte aus V ∩ V is(q)
end if
end if
end for
return ∅
}
5
InP (u, v) ist eine Boolean combination“ aus O(n) linearen Ungleichheiten.
”
V isib(x, y; u, v) ist eine Boolean combination“ aus O(n) quadratischen Un”
gleichheiten. Daher schließn alle Prädkate nur O(nk) Polygone des 2. Grades
ein und haben nur ein Wechsel der Quantoren. Durch das Ergebnis von Basu, Pollack und Roy [1], ist die Entscheidung, ob die Aussage wahr ist, in
O((nk)3(2k+1) ) Zeit möglich. Das Optimum für k zu finden, ist durch eine
lineare Suche in asymtotisch der gleichen Zeit möglich.
2
5
Platzierung der Wächter auf einem Raster
In diesem Kapitel erweitern wir Algorithmus 3.1, bei dem die Position
der Wächter auf die Eckpunkte des Polygons beschränkt waren. Unser Ziel
ist es, eine möglichst gute Lösung für das Kunstgalerie-Problem zu finden.
Dazu werden wir ein enges Raster definieren und über das Polygon legen.
Die Einschränkung der Positionierung der Wächter erweitern wir von den
Eckpunkten auf alle Raterpunkte innerhalb des Polygons. Intuitiv ist eine
solche, möglichst klein gehaltene Menge, auch eine gute approximation für
die Kardinalität einer optimalen Menge von Wächtern, die beliebig in den
Polygon platziert wurde.
Der Algorithmus in diesem Kapitel unterscheidet sich vom Algorithmus
3.1 nur in der Art, wie die Gewichte für die einzelnen Rasterpunkte gespeichert und gepflegt werden und der Methode, die die Menge der Wächter
bestimmt. Der grobe Ablauf des Algorithmus bleibt gleich.
Gegeben ist ein einfaches Polygon P , mit einer Menge V von n Eckpunkten und einem Durchmesser d ≤ 1. Wir definieren ein Raster Γ mit einem
Punkteabstand von > 0 in Axenrichtung, dessen Punkte alle innerhalb von
P liegen.
Γ = P ∩ {(i, j)|i, j ∈ ZZ)}
Der Algorithmus findet eine Menge von O(copt log copt ) vielen Wächtern
G ⊆ Γ, wobei copt die Kardinalität der kleinsten Menge von Punkten aus
Γ ist, die ganz P sehen. Insgesamt benötigt Algorithmus 5.1 eine Laufzeit
von
O nc2opt log copt log(ncopt ) log 2 ∆
wobei ∆ = d ist.
Die Hauptidee von diesem Algorithmus ist es, das Pflegen der Gewichte nicht mehr einzeln, wie bei Algorithmus 3.1 zu machen. Statt dessen
werden wir die Eigenschaften der Gewichteverteilung nutzen, um die Gewichte gebietweise zu pflegen. Wenn wir uns errinnern, wurden immer alle
Gewichte der Punkte verdoppelt, die im Sichtbarkeitspolygon eines nicht
gesehenen Punktes liegen. Im Verlauf des Algorithmus tauchen viele dieser
Sichtbarkeitspolygone auf. Wenn wir uns eine Zusammenstellung aus allen
6
Sichtbarkeitspolygonen und dem Polygon P vorstellen, ist klar, dass alle
Punkte in einer Zelle dieser Zusammenstellung das gleiche Gewicht haben.
Denn zu Beginn waren die Gewichte aller Punkte gleich und sie wurden nur
pro Sichtbarkeitspolygon verändert.
Für eine Menge M = {p1 , ..., pk } von k Punkten bezeichnet A die Zusammenstellung von k Sichtbarkeitspolygonen.
A = A(M ) = ∂V is(p1 ) ∪ ... ∪ ∂V is(qk )
Die Komplexität einer solchen Zusammenstellung A ist in O(nk 2 ). Die Zone
von ∂V is(q) in A bezeichnet alle Punkte von allen Kanten aus A, die zu
einer Zelle gehören, die durch das Einfügen von V is(q) geschnitten wird.
Die Komplexität einer Zone von ∂V is(q) in A ist in O(nkα(k)), wobei
α(n) die inverse Ackermann-Funktion ist. Die inverse Ackermann-Funktion
ist eine extrem langsam wachsende Funktion.
Bevor wir uns in Abschnitt 5.2 auf Seite 8 eine geeignete Datenstruktur
anschauen, die eine solche Zusammenstellung speichern kann und alle von
uns benötigten Funktionen unterstützt, betrachten wir noch zwei Erkenntnisse im Umgang mit einem Raster.
5.1
Bereichsanfrage auf einem Raster
Wenn wir eine Zusammenstellung gespeichert haben und ihr ein weiteres
Sichtbarkeitspolygon hinzufügen wollen, müssen wir die Anzahl der Raterpunkte in den beiden verbleibenden Teilen der Zelle bestimmen.
7
Lemma 5 Sei T ein Dreieck und Γ ein Raster in T. Dann kann man die
konvexe Hülle CH(Γ∩T) und die Anzahl der Rasterpunkte innerhalb von T
mit einer Laufzeit von O(log∆) bestimmen. Dabei ist ∆ der Quotient des
Durchmessers von T und der Rastergröße.
Beweis. Nach S. Kahan und J. Snoeyink [4] kann man, die Konvexe Hülle
eines Rasters, unter einer Linie der Länge M, in O(log M ) berechen. Wir
wenden das auf die drei Seiten von T an und erhalten so CH(Γ∩T) in
O(log ∆). Mit Pick’s Theorem [7] bekommen wir die Anzahl der Punkte in
CH(Γ∩T).
2
Bei unserem Algorithmus müssen wir die Wächter zufällig wählen. Angenommen wir haben uns bereits für eine Zelle entschieden, dann müssen
wir aus dieser Zelle zufällig einen Rasterpunkt auswählen, wobei jeder Rasterpunkt die gleiche Wahrscheinlichkeit haben soll, ausgewählt zu werden.
Lemma 6 Seien T, Γ und ∆ wie in Lemma 5. Dann kann man zufällig
einen Punkt aus T ∩ Γ auswählen, wobei jeder Rasterpunkt mit der gleichen
Wahrscheinlichkeit gezogen wird. Die Laufzeit dazu liegt in O(log 2 ∆).
Beweis. Die Idee ist es, das Dreieck T solange vertikal zu teilen, bis wir
nur noch eine Reihe von Rasterpunkten übrighaben. Dazu legen wir eine
Bounding-Box B0 um das Dreieck T. In der i-ten Iteration haben wir die
Bounding-Box Bi−1 und teilen diese vertikal mit einer Linie li in eine linke
und eine rechte Hälfe BiL und BiR , so dass li auf keinem Rasterpunkt liegt.
Nach Lemma 5 können wir die Anzahl der Punke in einer Hälfte in O(log∆)
Zeit berechnen. Sei wi die Anzahl der Rasterpunkte in der linken Hälfte.
w0 bezeichnet die Anzahl der Rasterpunkte in T. Damit alle Punkte mit
gleicher Wahrscheinlichkeit gewählt werden, entscheiden wir uns mit einer
i
Wahrscheinlichkeit von p = wwi−1
für die linke Seite und mit einer Wahrscheinlichkeit q = 1 − p für die rechte Seite. Falls wir uns für die rechte Seite
entscheiden setzen wir wi = wi−1 −wi . Wir führen dies solange durch, bis nur
noch eine einzelne Reihe von Rasterpunkten in unserer Bounding-Box übrig
ist. Von dieser Linie wählen wir dann zufällig einen Punkt. Wir benötigen
O(log∆) Iterationen, da es ∆ viele vertikale Reihen mit Rasterpunkten gibt
und jede Iteration benötigt O(log∆) um die Anzal der Rasterpunkte in einer Hälfte zu berechnen. So kommen wir insgesamt auf eine Laufzeit von
O(log 2 ∆).
2
5.2
Erweiterter Suchbaum
Wir hatten uns überlegt, dass wir eine Zusammenstellung von Sichtbarkeitspolygonen dazu benutzen können, um die Gewichte der Rasterpunkte
so zu speichern, dass wir sie mit einem akzeptablen Aufwand pflegen können.
Beim Speichern der Zusammenstellung ist es wichtig, dass wir zufällig aber
8
abhänging von ihren Gewichten einen Rasterpunkt wählen können. Außerdem müssen wir Sichtbarkeitspolygone der Zusammenstellung hinzufügen
können, die Summe der Gewichte der Rasterpunkte in einem Sichtbarkeitspolygon berechnen und sie danach evt. verdoppeln können.
Zum Speichern der Zusammenstellung werden wir mehrere erweiterte Suchbäume
verwenden. Wie wir die Suchbäume benutzen ist nach Lemma 7 beschrieben.
Lemma 7 Sei S = {(x1 , w1 ), ..., (xm , wm )} eine Menge mit m Punkten auf
einer Linie, zum Beispiel auf einer Kante eines Polygons. Jedem Punkt xi
ist ein Gewicht wi zugeordnet. Dann gibt es einen erweiterten Suchbaum T ,
der für jede der folgenden Operationen nur O(log m) Zeit benötigt.
• einf ügen(xi , wi ) - Fügt einen neuen Punkt xi mit dem Gewicht wi in
S ein.
• ändern(xi , wi ) - Ändert das Gewicht von Punkt xi in wi .
• wählen() - Wählt einen Punkt xi zufällig aus S, mit der Wahrscheinlichkeit Pnwi w .
j=1
j
• intervalSumme(x, y) - Berechnet die Summe der Gewichte der Punkte
S ∩ [x, y].
• intervalV erdoppeln(x, y) - Verdoppelt das Gewicht von jedem Punkt
in dem Intervall S ∩ [x, y].
Beweis. Wir verwenden einen sortierten und balancierten Baum T . Die
Höhe des Baumes ist in O(log m), da er balanciert ist und weil er sortiert
ist, können wir einen Punkt xi finden, indem wir einmal von der Wurzel zum
Blatt hinuntersteiten, was natürlich in Zeit O(log m) geht. Wir bezeichnen
mit π(ν, µ) den Pfad von dem Knoten ν zum Knoten µ, wobei ν ein Vorfahre
von µ ist.
Jedes Blatt repräsentiert genau einen Punkt xi aus der Menge S. Das Blatt,
welches den Punkt xi speichert, werden wir im Folgenden auch xi nennen.
Jeder interne Knoten µ speichert zusätzlich ein Multiplikationsfaktor Mµ
und ein Gewicht σµ . Der Multiplikationsfaktor Mµ ist zu Beginn 1 und er
wird dazu verwendet, die Gewichte des ganzen Teilbaums zu verdoppeln.
Jeder Knoten µ kennt auch das Gewicht seines Teilbaumes, das vorallem
durch σµ repräsentiert wird.
Wir aktualisieren die Multiplikationsfaktoren Mµ so, dass immer folgendes
gilt:
Y
wi =
Mξ
ξ ∈ π(root(T ), xi )
Das Gewicht σµ ist definiert als:
σµ =
X
Y
xi Blatt im T eilbaum von µ
9
ξ ∈ π(µ, xi )
Mξ
So lässt sich das Gewicht des Teilbaums unter den Knoten µ schnell
durch die Multiplikationsfaktoren auf dem Pfad von der Wurzel bis zum
Knoten µ und dem Gewicht σµ berechen.
Y
Gewicht des T eilbaums unter µ = σµ ·
Mξ
(1)
ξ ∈ π(root(T ), parent(µ))
Jetzt zeigen wir, dass die Operation wählen in Zeit O(log m) geht. Angenommen, wir haben uns bereits dafür entschieden, dass der Punkt xi den wir
auswählen wollen, im Teilbaum Tµ unter dem Knoten µ liegt. Dann müssen
wir jetzt entscheiden, ob wir ein Blatt aus dem linken Teilbaum Tlef t(µ)
wählen oder nicht. Damit die Auswahl zufällig aber gleichmäsig nach den
Gewichten verteilt geschieht, müssen wir die Wahrscheinlichkeit für die Wahl
des linken Teilbaums anhand der Gewichte berechnen. Die Wahrscheinlichkeit ergibt sie wie folgt:
P
Gewicht der Blätter von Tlef t(µ)
P
=
Gewicht der Blätter in Tµ
Q
σlef t(µ) ξ
Q
σµ ξ
∈ π(root(T ), lef t(µ)) Mξ
∈ π(root(T ), µ) Mξ
=
σlef t(µ) Mlef t(µ)
σµ
Da alle benötigten Werte zur verfügung stehen reicht es, den Baum einmal hinabzusteigen, um zufällig einen Punkt zu wählen. Damit ist die Laufzeit O(log m)
Um die Laufzeit für intervalSumme(x, y) und intervalV erdoppeln(xy)
zu beweisen, definieren wir die Menge X . Sei X die Menge aller Knoten µ,
von denen alle Blätter im Intervall [x, y] liegen, aber für deren Vaterknoten
diese Eigenschaft nicht gilt. Es ist klar, dass wir alle Knoten der Menge X
in O(log m) besuchen können.
Für die Operation intervalV erdoppeln(xy) reicht es, wenn wir für jeden
Knoten µ ∈ X den Multiplikationsfaktor Mµ verdoppeln. Da jedes Blatt im
Intervall [x, y] unter genau einem Knoten aus X liegt, haben wir dadurch
alle Werte der Blätter in diesem Intervall verdoppelt. Da wir die Knoten
alle in Zeit O(log m) besuchen können, geht die gesamte Operation auch in
O(log m) Zeit.
Für die Operation intervalSumme(x, y) benutzen wir wieder die Menge
X . Wir müssen die Summe der Gewichte aller Blätter in Intervall [x, y]
berechnen. Da jedes Blatt unter genau einem Knoten in X liegt reicht es,
wenn wir für jeden Knoten µ ∈ X mit der Gleichung (1) das Gewicht seines
Teibaums ausrechnen und die so erhaltenen Gewichte summieren. Da wir alle
Knoten in X in Zeit O(log m) besuchen können und da alle für die Gleichung
10
(1) benötigten Werte ohne zusätzlichen Aufwand zur Verfügung stehen, lässt
sich die Operation intervalSumme(x, y) in O(log m) Zeit ausführen.
Es bleibt die Laufzeit für die Operationen einf ügen(xi , wi ) und ändern(xi , wi )
zu beweisen. Um den Knoten xi einzugügen, wird er ganz normal in den
Suchbaum eingefügt und der Baum anschließend balanciert. Das geht natürlich
in O(log m). Die folgenden Schritte sind für beide Operationen gleich. Sei
µ der Knoten in dem xi gespeichert ist. Dann müssen wir den Multiplikationsfaktor diese Knotens aktualisieren. Wir setzen ihn wie folgt:
wi
Mµ = Q
ξ ∈ π(root(T ), parent(µ)) Mξ
Damit hat unser Blatt den richtigen Wert. Aber daduch das sich in
diesem Blatt der Wert geändert hat stimmen die σµ́ der Knoten µ́ auf dem
Weg von der Wurzel zum Blatt µ nicht mehr. Daher aktualisieren wir alle
Knoten µ́ ∈ π(root(T ), µ) von unten nach oben. Insgesammt müssen wir
dazu den Baum nur einmal runter und wieder rauf laufen, also benötigen
wir auch hier nur O(log m) Zeit.
2
5.3
Verwendung der Datenstruktur
Als nächstes beantworten wir die Frage, wie man die Zusammenstellung A
und die Gewichte mit Hilfe der vorgestellten Datenstruktur speichert. Die
Zusammenstellung wird während des Algorithmus in jeder Iteration um ein
Sichtbarkeitspolygon erweitert. Mit Ai bezeichnen wir die Zusammenstellung, die in der i-ten Iteration durch das Hinzufügen eines Sichtbarkeitspolygons entsteht.
Die Fläche des Polygons wird durch die Kanten der Sichtbarkeitspolygone in kleinere Flächen geteilt. Eine zusammenhängende Fläche in P nennen
wir eine Zelle. Der Einfachheithalber nehmen wir an, das jede Zelle ein Dreieck ist. Falls dem nicht so ist, berechnen und speichern wir für diese Zelle
eine Triangulation. Dies beeinträchtigt die Gesamtlaufzeit des Algorithmus
nicht.
Wenn wir die Zusammenstellung Ai betrachten, sehen wir, dass jede der
11
Kanten der Zusammenstellung auf einer Kante eines der Sichtbarkeitspolygone V is(qj ) mit j = 1, ..., i liegt. Wobei qj jeweils der Punkt ist, für den wir
in der i-ten Iteration V is(qj ) der Zusammenstellung Ai−1 hinzugefügt haben. Die Kanten der Sichtbarkeitspolygone nennen wir Lange-Kanten. Jede
Lange-Kante ersetzen wir durch zwei Kopien von ihr. Diese Kanten nennen
wir Polygon-Kanten. Die zwei Kopien benötigen wir, damit jede jeweils nur
Zellen der Zusammenstellung auf einer Seite begrenzt.
Zum Speichern der Zusammenstellung werden wir für jede Polygon-Kante
einen erweiterten Suchbaum anlegen. Unser Suchbaum speichert Punkte auf
einer Linie und dazu jeweils ein Gewicht. Punkte sind in der Zusammenstellung alle Schnittpunkte von Geraden. Jeder Schnittpunkt wird insgesamt 8
mal gespeichert. Das liegt daran, dass jeder Schnittpunkt zu vier PolygonKanten gehört. Und für jede Polygon-Kante speichern wir den Schnittpunkt
zweimal, jeweils für die linke und rechte angrenzende Zelle. Dies machen
wir, da die Rasterpunkte in den beiden Zellen verschiedene Gewichte haben
können.
Ein Beispiel dazu gibt das folgende Bild. Für eine Lange-Kante sind alle
Schnittpunkte durch große grünen Punkt dargestellt. Und für einen Schnittpunkt ist rechts unten die Aufteilung eines Schnittpunktes in die 8 zu speichernden Punkte angedeutet. Man sieht auch, dass pro Polygon-Kante genau
ein Punkt zu genau einer Zelle gehört. Das ist wichtig zum Speichern der
Gewichte.
Das Gewicht, das zu einem Punkt gespeichert wird, der zur Zelle c gehört,
wc
. Wobei wc das Gesamtgewicht der Punkte in der Zelle c ist und mc
ist 2m
c
die Anzahl der Eckpunkte die die Zelle c hat.
Zusätzlich zu jedem Suchbaum jeder Polygon-Kante speichern wir einen erweiterten Suchbaum T̃ . In diesem Suchbaum speichern wir für jede PolygonKante ei einen repräsentativen Punkt xi zusammen mit dem Gesamtgewicht
12
der Kante ei . Das Gesamtgewicht der Kante ei ist gleich der Summe der Gewichte aller im Suchbaum zu ei gespeicherten Punkte.
Zu Beginn des Algorithmus initialisieren wir unsere Datenstruktur, indem wir die Zusammenstellung A0 , also das Polygon P, speichern. Wir legen
zu jeder Kante von P ein Suchbaum an, in dem wir den Start- und Endpunkt
der Kante speichern. Da wir bis jetzt nur eine Zelle haben, hat jeder Punkt
das gleiche Gewicht. Es ergibt sich aus der Anzahl der Rasterpunkte in P
geteilt durch das zweifache der Kantenzahl. In den Suchbaum T̃ speichern
wir z.B. zu jeder Kante von P den Startpunkt zusammen mit dem Gewicht
der zugehörigen Kante.
Für den Algorithmus benötigen wir die Möglichkeit zufällig einen Rasterpunkt zu wählen. Die Wahl muss aber abhängig von den Gewichten der
Rasterpunkte sein. Diese Aktion ist durch unsere Datenstruktur möglich.
Um einen Rasterpunkt zu bekommen, rufen wir als erstes die Operation
wählen() für den Baum T̃ auf. Dadurch haben wir eine Polygon-Kante e
erhalten. Als zweites rufen jetzt die Operation wählen() für den Baum T
der Kante e auf. So erhalten wir eine Zelle. Die beiden Operationen haben
sichergestellt, dass unsere Wahl zufällig aber abhänging von den Gewichten
ist. Als drittes müssen wir jetzt nur noch zufällig einen der Punkte der Zelle
auswählen. Da alle Punkte der Zelle das gleiche Gewicht haben, reicht uns
diesmal eine rein zufällige Wahl.
Jetzt wissen wir, wie wir unsere Wächer wählen können. Wenn wir den
von den Wächtern eingesehenen Bereich von P ausgerechnet haben und einen
Punkt qj ausserhalb dieses Bereiches aber noch in P gewählt haben, müssen
wir den Rand von V is(qj ) unserer Zusammenstellung hinzufügen. Dazu gehen wir wie folgt vor:
Als erstes müssen wir eine Zelle c in Ai−1 finden, die einen Punkt von
∂V is(qi ) enthält, der auch ein Punkt von P ist. Um c einfach zu finden,
speichern wir uns zu jedem Punkt von P in welcher Zelle er liegt. Dann
finden wir c, indem wir prüfen, welcher Punkt von p den Punkt qi sieht. Als
nächstes folgen wir von Punkt p aus dem ∂V is(qi ) durch die Zusammenstellung Ai−1 . Jede Zelle, die wir beim Verfolgen des Randes schneiden, teilen
wir in zwei Hälften. Für die beiden Hälften berechnen wir, wieviel Punkte
es in den beiden neuen Zellen gibt. Für jeden Punkt xi , der zu der geteilten Zelle gespeichert war, aktualisieren wir das Gewicht durch den Aufruf
der Operation ändern(xi , wi ), wobei wi das neue Gewicht ist. Ausserdem
müssen wir die Anzahl der Punkte der beiden Zellen aktualisieren.
Auf dem folgenden Bild ist an einem Beispiel dargestellt, wie ein ∂V is(qi )
in eine Zusammenstellung eingefügt wird. Links ist die Zusammenstellung
Ai−1 zu sehen. In der Mitte sind die neuen Kanten vom ∂V is(qi ) zu sehen.
13
V is(qi ) ist grau hinterlegt. Rechts sieht man die Zusammenstellung Ai . In ihr
sind alle Kanten grau hinterlegt, die beim Einfügen von ∂V is(qi ) aktualisiert
werden mussten. Die zum Berechnen des Gewichts und zum Verdoppeln des
Gewichts aufgerufenen Funktionen werden für alle grau hinterlegten Kanten, jeweils mit den Koordinaten der beiden äußersten schwarzen Punkte,
aufgerufen.
Auf dem Bild war bereits die nächste Aktion angedeutet. Nachdem man
∂V is(qi ) der Zusammenstellung hinzugefügt hat, wird im Algorithmus überprüft,
ob das Gewicht der Rasterpunkte innerhalb von V is(qi ) um einen bestimmten Faktor kleiner ist, als das Gesamtgewicht des Polygons. Um das Gewicht
von V is(qi ) zu berechnen, rufen wir für jede Kante, die V is(qi ) scheidet oder
begrenzt, die Operation intervalSumme(x, y) auf. Dabei sind x und y die
beiden Schnittpunkte der Kante mit ∂V is(qi ). Das Gesmtgewicht des Polygons erhalten wir mit dem Suchbaum T̃ , indem wir die Summe der Gewichte
aller im Suchbaum gespeicherten Punkte bilden.
Falls die Überprüfung positiv verläuft, müssen wir die Gewichte aller Rasterpunkte in V is(qi ) verdoppel. Dazu rufen wir auf den gleichen Kanten und
mit den gleichen Punkten wie zuvor die Operation intervalV erdoppeln(x, y)
auf.
5.4
Der Algorithmus
Betrachten wir den Algorithmus 5.1 als Ganzes. Er ist auf der Seite 5
abgebildet.Der grobe Ablauf des Algorithmuses ist gleich wie der des Algorithmus 3.1. In der äußeren Schleife wird die Funktion ComputeGuards(P,
k) aufgerufen. Die Funktion ComputeGuards(P, k) versucht für das Polygon
P eine Menge von O(k log k) vielen Wächtern zu finden. Die Positionen der
14
Wächter sind dabei auf das Raster Γ beschränkt.
Als erstes initialisiert die Funktion ComputeGuards(P, k) die Datenstruktur für den Algorithmus. Dazu gehören n Suchbäume für die n Kanten von
P und ein zusätzlicher Suchbaum in dem ein Punkt für jede der n Kanten
gespeichert wird. Damit ist die Zusammenstellung A0 gegeben.
Als nächstes beginnt die innere Schleife. In ihr wird zunächst eine Menge
G ⊆ Γ von Wächtern bestimmt, wie im vorherigen Kapitel beschrieben.
Wenn die Menge G ganz P sieht ist der Algorithmus zuende.
Sieht die Menge G nicht das ganze Polygon P, wählt man zufällig einen
Punkt q aus einem Teil des Polygons der nicht gesehen wird. Für diesen Punkt fügt man das Sichtbarkeitspolygon Vis(q) der Zusammenstellung
Ai−1 hinzu, was ebenfalls im vorherigen Kapitel beschrieben ist. Die Variable i gibt hierbei an, um welche Iteration es sich handelt. Falls das k-fache
des Gewichts des Sichtbarkeitspolygons kleiner oder gleich dem Gewicht des
gesamten Polygons ist, wird das Gewicht des Sichtbarkeitspolygons verdoppelt.
Falls die Schleife O(k log nk ) durchläufe macht, ohne das eine Menge G gefunden wurde, die P ganz sieht, gibt die Funktion die leere Menge zurück.
Daraufhin wird in der äußeren Schleife das k verdoppelt und die Funktion
ComputeGuards(P, k) erneut aufgerufen.
Die äußere Schleife des Algorithmus 5.1 macht eine exponentielle Suche
nach copt , wodurch die Funktion ComputeGuards(P, k) insgesamt O(log copt )
mal aufgerufen wird. Ein Aufruf von ComputeGuards(P, k) macht O(k log nk )
Iterationen. Die i-th Iteration hat einen Aufwand von O(niα(n) log n (log i+
log 2 ∆)).
Damit kommt man für den Algorithmus insgesamt auf eine Laufzeit von
O(nc2opt log n log(ncopt ) log 2 ∆).
15
Algorithmus 5.1 Bestimmung der Wächter auf einem Raster
// P ist das einfache Polygon, für das die Wächter bestimmt werden.
// Falls copt unbekannt ist, wird k mit 1 initialisiert.
k := 1;
repeat
G := ComputeGuards(P, k);
if G 6= ∅ then
Berichtet die Wächter G;
else
k := k + k ; // da k zu klein war.
end if
until Eine Menge von Wächtern gefunden wurde.
ComputeGuards(P, k){
Initialisierung der Datenstruktur;
for i = 1 to O(k log( nk )) do
Bestimme eine Menge G ⊆ Γ wie in Abschnitt 5.3 beschrieben;
if Die Punkte von G sehen ganz P then
return G;
else
Suche einen Punkt q ∈ P der nicht von G sichtbar ist;
Füge V is(q) in die Zusammenstellung Ai−1 ein;
if 2k Gewicht von V is(q) ≤ Gewichte von P then
Verdopple die Gewichte der Rasterpunkte in V is(q);
end if
end if
end for
return ∅
}
16
6
Polygone mit Löchern
Die in den vorherigen Kapiteln vorgestellten Algorithmen können leicht erweitert werden, so dass sie Sichtbarkeitsprobleme in komplizierteren Gallerien oder mit anderen Modellen für die Sichtbarkeit lösen.
In den vorgestellten Algorithmen konnten die Wächter unendlich weit sehen und hatten einen Blickwinkel von 360◦ . Wenn die Wächter Menschen
währen, so müsste man die Sichtweite und den Blickwinkel einschränken,
um eine realistische Lösung zu finden. Wenn wir unsere Algorithmen auf ein
solches eingeschränktes Sichbarkeitsmodell ändern wollen, müssen wir lediglich die Berechnung der Sichtbarkeitspolygone ändern. Im Folgenden ist die
Erweiterung der Algorithmen für Polygone mit Löchern beschrieben. Dabei
wird wieder das Standardmodell für die Sichtbarkeit angenommen.
6.1
Sichtbarkeit in Polygonen mit Löchern
Wir betrachten ein Polygon P mit n Ecken und h Löchern. Durch die Löcher
wächst die Komplexität der Zusammenstellung aus den Rändern von k Sichtbarkeitspolygonen auf O(nk 2 h) erhöht. Bei Polygonen ohne Löcher war sie
O(nk 2 ). Der Rand eines Sichtbarkeitspolygons besteht aus n+h Kanten, die
nicht auf dem Rand des Polygons liegen. Zwei verschiedene Sichtbarkeitspolygone schneiden sich maximal in 2h Punkten. k viele Sichtbarkeispolygone
schneiden sich demnach in maximal (k+1)kh, also O(k 2 h) vielen Punkten.
So kommen wir insgesamt auf die angegebene Komplexität.
In [6] wurde gezeigt, dass die VC-dimension dieses Problems in θ(1 + log h)
ist. Durch das Anwenden der Erkentnisse aus [2] sehen wir, dass sich der
Approximationsfaktor auf O(log h log(copt log h)) erhöht. Fügen wir das
zusammen und erweitern wir den Algorithmus aus Abschnitt 5, so kommen
wir zu folgendem Ergebnis.
Theorem 8 Sei P ein Polygon mit n Ecken und h Löchern.
Es ist möglich, eine Menge G von O(copt log n log(copt log n)) Eckpunkten
von P zu finden, die ganz P sehen, wobei copt die Kardinalität der optimalen
Lösung ist. Die erwartete Laufzeit ist O(nhc3opt polylog n).
Sei Γ ein Raster in P. Dann kann man eine Menge G von O(copt log h log(copt log n))
Punkten aus Γ finden die ganz P sehen. Die erwartete Laufzeit ist O(nhc3opt polylog n log 2 ∆),
wobei ∆ die Differenz aus dem Durchmesser von P und der Rastergröße ist.
17
Literatur
[1] S. Basu, R. Pollack, and M.-F.Roy. On the combinatorial and algebraic
complexity of quantifier elimination. J. ACM, 43:1002–1045, 1996.
[2] H. Brönnimann and M. T. Goodrich. Almost optimal set covers in finite
vc-dimension. Discrete Comput. Geom. 14, pages 263–279, 1995.
[3] A. Efrat and S. Har-Peled. Guarding galleries and terrains. 2006.
[4] S. Kahan and J. Snoeyink. On the bit complexity of minimum link paths:
Superquadratic algorithms for problems solvable in linear time. In Proc.
12th Annu. ACM Sympos. Comput. Geom., pages 151–158, 1996.
[5] J. O’Rourke. Art gallery theorems and algorithms. The International
Series of Monographs on Computer Science. Oxford University Press,
New York, NY, 1987.
[6] P. Valtr. Guarding galleries where no point sees a small area. Israel J.
Math, pages 1–16, 1998.
[7] D. Varberg. Pick’s theorem revisited. The American. Math. Monthly
92., pages 584–587, 1985.
18
Herunterladen