Algorithm 快速插入矩形的空间索引

Algorithm 快速插入矩形的空间索引,algorithm,indexing,data-structures,spatial-index,Algorithm,Indexing,Data Structures,Spatial Index,我正在寻找一种为矩形提供索引的数据结构。我需要尽可能快的插入算法,因为矩形将在屏幕上移动(想想用鼠标拖动矩形到新位置) 我已经研究了R-树、R+树、kD-树、四叉树和B-树,但从我的理解来看,插入通常很慢。我更喜欢具有次线性时间复杂度的插入,这样也许有人可以证明我对列出的任何一种数据结构都是错误的 我应该能够查询数据结构中哪些矩形位于点(x,y)或哪些矩形与矩形相交(x,y,宽度,高度) 编辑:我之所以希望插入速度如此之快,是因为如果你想在屏幕上移动一个矩形,它们必须被删除,然后重新插入 谢谢

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

我已经研究了R-树、R+树、kD-树、四叉树和B-树,但从我的理解来看,插入通常很慢。我更喜欢具有次线性时间复杂度的插入,这样也许有人可以证明我对列出的任何一种数据结构都是错误的

我应该能够查询数据结构中哪些矩形位于点(x,y)或哪些矩形与矩形相交(x,y,宽度,高度)

编辑:我之所以希望插入速度如此之快,是因为如果你想在屏幕上移动一个矩形,它们必须被删除,然后重新插入


谢谢

这可能是一个延伸的评论,而不是一个答案

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

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

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


有多少个矩形?它们的创建速度有多快?被摧毁了?您希望如何处理重叠?矩形只是边界还是包括内部?

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

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

有一个矩形列表数组,每个像素一个。然后,两个接两个地装箱,然后再做一次。一次又一次,直到你有一个像素覆盖了一切

现在,关键是在与矩形大小匹配的级别插入矩形。这将类似于(像素大小)~=min(高度、宽度)/2。现在,对于每个矩形,您只需在列表中插入少量内容(您可以在上面用常量绑定它,例如,选择4到16像素之间的内容)

如果要查找x、y处的所有矩形,请先查找最小像素列表,然后查找包含该像素的2x2装箱像素列表,然后查找4x4等。;你应该有log2(像素)的步骤来查看。(对于较大的像素,您必须检查(x,y)是否真的在矩形中;您预计其中大约一半在边框上成功,所有在矩形内成功,因此您预计的工作量不会比直接查找像素多2倍。)

现在,插入怎么样?这是非常便宜的——O(1)将自己放在列表的前面

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


(请注意,如果最小矩形必须大于一个像素,则无需实际形成多尺度结构直至像素级;只需向下移动,直到最小矩形不会在已装箱的像素中丢失为止。)

您提到的数据结构非常复杂:特别是B-树应该很快(插入的成本随着当前项目数的对数增长),但不会加快交叉点查询的速度

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

您通常可以省去在每个节点上跟踪信息的想法,而不使用关于树应该如何构建的(昂贵的)想法。例如,您可以通过位交错其点的坐标为每个矩形创建一个关键点,然后使用一个非常普通的树结构(如B树、AVL树或红黑树)来存储它,同时仍保留每个节点上的信息。在实践中,这可能会大大加快查询速度——尽管在实际数据上实现和测试之前,您无法判断这一点。大多数方案中树构建说明的目的是提供性能保证

两篇后记:

1) 我喜欢Patricia树,因为它们相当容易实现,添加或删除条目不会对树结构造成太大的干扰,因此您不需要做太多的工作来更新存储在节点上的信息


2) 上次我看一个窗口系统时,它一点也不在乎这些聪明的东西——它只是保留了一个线性的项目列表,并在需要的时候一直搜索:这已经足够快了。

也许我遗漏了一些东西,但你怎么能在次线性时间内进行插入呢?仅仅读取每个矩形的坐标已经是一个O(n)操作。如果“屏幕”中的所有对象都已被索引(kd、quad、r/树),则insert必须小于O(n),因为