【问题标题】:Spatial Index for Rectangles With Fast Insert快速插入矩形的空间索引
【发布时间】:2010-04-02 22:52:39
【问题描述】:

我正在寻找一种为矩形提供索引的数据结构。我需要插入算法尽可能快,因为矩形将在屏幕上移动(考虑用鼠标将矩形拖动到新位置)。

我研究过 R-Trees、R+Trees、kD-Trees、Quad-Trees 和 B-Trees,但据我了解,插入通常很慢。我更喜欢以亚线性时间复杂度进行插入,所以也许有人可以证明我对列出的数据结构中的任何一个都错了。

我应该能够查询数据结构,以了解哪些矩形在点 (x, y) 或哪些矩形与矩形相交 (x, y, width, height)。

编辑:我之所以这么快插入,是因为如果您想在屏幕上移动一个矩形,则必须将它们删除然后重新插入。

谢谢!

【问题讨论】:

  • 也许我遗漏了一些东西,但是你怎么能在亚线性时间内插入呢?仅仅读取每个矩形的坐标已经是 O(n) 操作了。
  • 如果“屏幕”的所有对象都有索引(kd、quad、r/trees),则插入必须是
  • 如果矩形可以移动的速度有限制,那么询问是否有办法分摊重建过程并不是不合理的。
  • 嗯,它们并不总是在移动。假设您用鼠标在屏幕上拖动一个对象。这是“运动”发生的一个很好的例子。

标签: algorithm indexing data-structures spatial-index


【解决方案1】:

我会使用多尺度网格方法(相当于某种形式的四叉树)。

我假设您使用的是整数坐标(即像素)并且有足够的空间来容纳所有像素。

有一个矩形列表数组,每个像素一个。然后,将 2×2 分箱,然后再做一次。一次又一次,一次又一次,直到你有一个像素覆盖一切。

现在,关键是您将矩形插入到与矩形大小完美匹配的水平。这将类似于 (pixel size) ~= min(height,width)/2。现在,对于每个矩形,您只需要在列表中进行少量插入操作(您可以在上面用一个常数将其绑定,例如选择 4 到 16 像素之间的东西)。

如果您想在 x,y 处查找所有矩形,您可以查看最小像素列表,然后查看包含它的 2x2 合并像素列表,然后查看 4x4 等;你应该有 log2(# of pixel) 步骤来查看。 (对于较大的像素,您必须检查 (x,y) 是否真的在矩形中;您希望大约一半的像素在边界上成功,并且所有像素都在矩形内成功,所以您会期望不比直接查找像素多 2 倍的工作量。)

现在,插入呢?这非常便宜——O(1) 就可以将自己排在列表的前面。

删除呢?那更贵;您必须查看并修复您输入的每个像素的每个列表。这大约是 O(n) 在空间中该位置重叠的矩形数量大致相同。如果您有大量的矩形,那么您应该使用其他一些数据结构来保存它们(散列集、RB 树等)。

(请注意,如果你的最小矩形必须大于一个像素,你不需要真正形成多尺度结构一直到像素级;只要向下直到最小的矩形不会绝望地迷失在里面你的分箱像素。)

【讨论】:

    【解决方案2】:

    您提到的数据结构很复杂:尤其是 B-Trees 应该很快(插入成本随着存在的项目数量的对数增长)但不会加快您的交集查询。

    忽略这一点 - 并希望最好 - 空间数据结构分为两部分。第一部分告诉您如何从数据中构建树形结构。第二部分告诉您如何跟踪每个节点上描述存储在该节点下的项目的信息,以及如何使用它来加快查询速度。

    您通常可以在不使用关于应该如何构建树的(昂贵的)想法的情况下扼杀关于在每个节点处跟踪信息的想法。例如,您可以通过位交织点的坐标为每个矩形创建一个键,然后使用完全普通的树结构(例如 B 树或 AVL 树或红黑树)来存储它,同时仍然在每个节点上保留信息。在实践中,这可能会足够加快您的查询速度——尽管在您实施并在真实数据上进行测试之前,您无法判断这一点。大多数方案中的树构建指令的目的是提供性能保证。

    两个后记:

    1) 我喜欢 Patricia 树 - 它们相当容易实现,并且添加或删除条目不会过多地干扰树结构,因此您不会有太多工作来更新存储在节点上的信息。

    2) 上次我查看窗口系统时,它根本不关心这些聪明的东西——它只是保留了一个线性项目列表,并在需要时一直搜索它:那是足够快。

    【讨论】:

      【解决方案3】:

      这可能是一个扩展的评论,而不是一个答案。

      我对你真正想要什么感到有点困惑。我猜你想要一个数据结构来支持快速回答诸如“给定矩形的 ID,返回其当前坐标”之类的问题。是对的吗 ?

      或者你想回答'什么矩形在位置 (x,y)' ?在这种情况下,尺寸与显示器的高度和宽度匹配的数组可能就足够了,数组中的每个元素都是该像素上矩形的(可能很短)列表。

      但是你说你需要一个尽可能快的插入算法来处理不断移动的矩形。如果你在屏幕上只有 10 个矩形,你可以简单地拥有一个包含每个矩形坐标的 10 元素数组。更新它们的位置将不需要任何插入数据结构。

      有多少个矩形?它们的创建速度有多快?并摧毁?你想如何处理重叠?矩形只是一个边界,还是包括内部?

      【讨论】:

        猜你喜欢
        • 2015-10-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-24
        • 2017-01-11
        • 2013-12-25
        相关资源
        最近更新 更多