Algorithmus für disjunktes Segmentsichtbarkeitsproblem


7

Bedenken Sie, wir haben n disjunkte Segmente und ein Punkt PDas ist in keinem Segment. Ich möchte einen findenO(nlogn) Algorithmus, um zu überprüfen, von welchen Segmenten aus sichtbar ist P. Ein Segment ist sichtbar vonP wenn es einen Punkt hat, der von sichtbar ist P.

Meine Idee ist es, eine Sweep-Halblinie mit einem Endpunkt zu verwenden P, sortiere Punkte im Uhrzeigersinn nach Grad und beginne von einem Endpunkt auf dem nächsten sichtbaren Segment (das ich nicht zu finden weiß), drehe und erkenne jeweils ein sichtbares und einige mögliche unsichtbare Segmente. Ich kann nur daran denkenO(n2)bisher. Kann mir jemand einen vorschlagenO(nlogn) Algorithmus.

Antworten:


3

Wolg könnten wir annehmen P ist der Ursprungspunkt (0,0).

  1. Listen Sie die Endpunkte aller Segmente auf und stellen Sie sie in Polarkoordinaten dar (θ,ρ)[0,2π)×[0,) und sortieren Sie sie nach ihrem Grad.
  2. Stellen Sie sich vor, es gibt einen Strahl von P Wir zeigen nach rechts und fegen es eine Runde lang (indem wir seine Richtung allmählich ändern α von 0 bis 2π). LassenR(α) bezeichnet den Strahl von P in Richtung α. Wir fragen uns, was die Segmente sindR(α) Treffer, und was ist ihre Reihenfolge auf R(α).
  3. Finden Sie heraus, welche Segmente getroffen wurden R(0)und sortieren Sie sie nach ihrer Reihenfolge auf R(0). Speichern Sie sie in einem ausgeglichenen binären Suchbaum (z. B. rot-schwarzer Baum).
  4. Durchlaufen Sie die Punkte, die wir in Schritt 1 gefunden (und sortiert) haben: Jeder Punkt (θ,ρ) zeigt an, dass ein Segment den Strahl treffen / stoppen würde R(α) wann α steigern zu θ. Aktualisieren Sie den binären Suchbaum entsprechend.
  5. Die Elemente, die einst die kleinsten im binären Suchbaum waren, sind die Segmente, von denen aus sie sichtbar sind P.

Es ist einfach zu überprüfen, ob die Laufzeit des obigen Algorithmus ist O(nlogn).


Danke für die Lösung. Ich habe Zweifel am 3. und 4. Schritt. Wie schaffen wir es, über alle Punkte zu iterieren und den Schnittpunkt mit zu überprüfen?R(α)ist in O(nlogn)?
VahidM

Für den dritten Schritt können Sie Segmente auflisten, um zu überprüfen, ob sie treffen R(0), (das dauert O(n)Zeit); die sortieren sie nach ihren Schnittpunkten aufR(0), (das dauert O(nlogn)Zeit).
Tianren Liu

@VahidM Für den 4. Schritt. Wir durchlaufen nicht alle Punkte, um herauszufinden, mit wem sich überschneidetR(α). ZB annehmen(θ,ρ)ist ein Endpunkt eines Segments. Informell lassen wirθ+ (θ) bezeichnet einen Grad, der etwas größer (kleiner) als ist θ. Dann kennen wir die SegmenteR(θ+) Schnittpunkte mit sind fast die gleichen wie die Segmente R(θ)schneidet mit. Sie unterscheiden sich nur in dem Segment, auf das sie sich beziehen(θ,ρ). Wir kennen also die getroffenen SegmenteR(θ)könnten wir es in ändern O(logn) Zeit, damit es die Menge der getroffenen Segmente wird R(θ+).
Tianren Liu

1

Wir können einen radialen Linien-Sweep durchführen, um das Problem zu lösen -

Sortieren Sie die Endpunkte der Liniensegmente nach dem Winkel, in dem die Linie verbunden ist P und der Endpunkt Q machen, brechen Krawatten wrt Abstand von P. Wenn wir nun radial (im Uhrzeigersinn) fegen, behalten wir zwei Arten von Ereignissen bei: "Öffnen" und "Schließen", die dem Öffnen und Schließen eines neuen Liniensegments entsprechen. Verfolgen Sie, wie viele Liniensegmente zu einem bestimmten Zeitpunkt "aktiv" sind ("aktiv" bedeutet, dass wir auf den Endpunkt gestoßen sind, der dem "offenen" Ereignis des Liniensegments entspricht, aber nicht auf den anderen Endpunkt im noch fegen). Wenn wir zu irgendeinem Zeitpunkt genau ein 'aktives' Liniensegment haben, ist dieses Segment von sichtbarP.

Wir sollten darauf achten, dass wir zu Beginn des Sweeps immer bei einem „offenen“ Event beginnen.

Es wird____geben 2nSolche Ereignisse und das Verfolgen der Anzahl aktiver Segmente können in konstanter Zeit pro Segment durchgeführt werden (über eine Hash-Tabelle oder eine Logarithmus-Zeit unter Verwendung einer ausgeglichenen BST). Daher ist der dominierende Schritt in diesem Algorithmus die Sortierung, die dauertO(n) Zeit nach Bedarf.

Wie bei allen Problemen mit der rechnerischen Geometrie kann es einige Eckfälle geben, die ich übersehen habe, aber die allgemeine Vorstellung, dass wenn zu einem bestimmten Zeitpunkt während des radialen Liniendurchlaufs genau ein aktives Liniensegment vorhanden ist, es von sichtbar ist P ist der springende Punkt, um dieses Problem zu lösen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.