Wenn Sie Probleme mit der räumlichen Indizierung haben, empfehle ich, mit einem räumlichen Hash oder meinem persönlichen Favoriten zu beginnen: dem einfachen alten Raster.
... und verstehen Sie zuerst seine Schwächen, bevor Sie zu Baumstrukturen übergehen, die spärliche Darstellungen ermöglichen.
Eine der offensichtlichen Schwächen besteht darin, dass Sie möglicherweise Speicher für viele leere Zellen verschwenden (obwohl ein anständig implementiertes Raster nicht mehr als 32 Bit pro Zelle erfordern sollte, es sei denn, Sie müssen tatsächlich Milliarden von Knoten einfügen). Ein weiterer Grund ist, dass Sie, wenn Sie mittelgroße Elemente haben, die größer als die Größe einer Zelle sind und häufig beispielsweise Dutzende von Zellen umfassen, viel Speicher verschwenden können, indem Sie diese mittelgroßen Elemente in weit mehr Zellen als ideal einfügen. Wenn Sie räumliche Abfragen durchführen, müssen Sie möglicherweise mehr Zellen überprüfen, manchmal weit mehr als ideal.
Das Einzige, was Sie mit einem Raster tun müssen, um es so optimal wie möglich gegen eine bestimmte Eingabe zu machen, ist cell size
, dass Sie nicht zu viel darüber nachdenken und herumspielen müssen, und deshalb ist es meine bevorzugte Datenstruktur für räumliche Indizierungsprobleme, bis ich Gründe finde, es nicht zu verwenden. Es ist einfach zu implementieren und erfordert nicht, dass Sie mit mehr als einer einzelnen Laufzeit-Eingabe herumspielen.
Sie können viel aus einem einfachen alten Raster herausholen, und ich habe tatsächlich viele Quad-Tree- und KD-Tree-Implementierungen geschlagen, die in kommerzieller Software verwendet werden, indem ich sie durch ein einfaches altes Raster ersetzte (obwohl sie nicht unbedingt die am besten implementierten waren , aber die Autoren verbrachten viel mehr Zeit als die 20 Minuten, die ich damit verbracht habe, ein Gitter aufzupeitschen. Hier ist eine kurze Kleinigkeit, die ich zusammengestellt habe, um eine Frage an anderer Stelle mithilfe eines Rasters zur Kollisionserkennung zu beantworten (nicht einmal wirklich optimiert, nur ein paar Stunden Arbeit, und ich musste die meiste Zeit damit verbringen, zu lernen, wie die Wegfindung funktioniert, um die Frage zu beantworten und es war auch mein erstes Mal, dass ich eine solche Kollisionserkennung implementierte):
Eine weitere Schwäche von Gittern (aber sie sind allgemeine Schwächen für viele räumliche Indexierungsstrukturen) besteht darin, dass beim Einfügen vieler übereinstimmender oder überlappender Elemente, wie z. B. vieler Punkte mit derselben Position, diese in genau dieselbe Zelle (n) eingefügt werden ) und verschlechtern die Leistung beim Durchlaufen dieser Zelle. Wenn Sie viele massive Elemente einfügen , die weitaus größer als die Zellengröße sind, möchten sie in eine Schiffsladung von Zellen eingefügt werden, viel Speicherplatz verbrauchen und die für räumliche Abfragen auf der ganzen Linie erforderliche Zeit verkürzen .
Diese beiden oben genannten unmittelbaren Probleme mit zusammenfallenden und massiven Elementen sind jedoch tatsächlich für alle räumlichen Indexierungsstrukturen problematisch . Das einfache alte Gitter behandelt diese pathologischen Fälle tatsächlich ein wenig besser als viele andere, da es zumindest Zellen nicht immer wieder rekursiv unterteilen möchte.
Wenn Sie mit dem Raster beginnen und sich auf einen Quad- oder KD-Baum zuarbeiten, ist das Hauptproblem, das Sie lösen möchten, das Problem, dass Elemente in zu viele Zellen eingefügt werden, zu viele Zellen haben und / oder zu viele Zellen mit dieser Art der dichten Darstellung überprüfen müssen.
Aber wenn Sie sich einen Quad-Tree als Optimierung über ein Gitter vorstellenFür bestimmte Anwendungsfälle ist es dann hilfreich, immer noch an die Idee einer "minimalen Zellengröße" zu denken, um die Tiefe der rekursiven Unterteilung der Quad-Tree-Knoten zu begrenzen. Wenn Sie dies tun, wird das Worst-Case-Szenario des Quad-Baums immer noch in das dichte Gitter an den Blättern zerfallen, nur weniger effizient als das Gitter, da es logarithmische Zeit benötigt, um sich von der Wurzel zur Gitterzelle zu arbeiten konstante Zeit. Wenn Sie jedoch an diese minimale Zellengröße denken, wird das Endlosschleifen- / Rekursionsszenario vermieden. Für massive Elemente gibt es auch einige alternative Varianten wie lose Quad-Bäume, die sich nicht unbedingt gleichmäßig teilen und AABBs für überlappende untergeordnete Knoten haben könnten. BVHs sind auch als räumliche Indexierungsstrukturen interessant, die ihre Knoten nicht gleichmäßig unterteilen. Für übereinstimmende Elemente gegen Baumstrukturen, Die Hauptsache ist, der Unterteilung nur eine Grenze aufzuerlegen (oder, wie andere vorgeschlagen haben, sie einfach abzulehnen oder einen Weg zu finden, sie so zu behandeln, als würden sie nicht zur eindeutigen Anzahl von Elementen in einem Blatt beitragen, wenn bestimmt wird, wann das Blatt ist sollte unterteilen). Ein Kd-Baum kann auch nützlich sein, wenn Sie Eingaben mit vielen übereinstimmenden Elementen erwarten, da Sie nur eine Dimension berücksichtigen müssen, wenn Sie bestimmen, ob ein Knoten im Median aufgeteilt werden soll.