R*树重叠计算

R* Tree overlap computation

本文关键字:计算 重叠      更新时间:2023-10-16

我正在阅读R* Tree的实现,我注意到它们计算重叠的方式与论文中定义的不同。

在本文中,重叠定义如下:

对于给定的节点/rect k,计算kk的每一个兄弟节点(不包括k)相交的面积之和。

如果在k上加上r项,则节点k的重叠是这个值的增量。

像这样:

childOverlapEnlargement(Node child, item r)
{
    childEnlarged = child.union(r);
    sum = 0;
    for(each sibling s of child which isn't node)
    {
        sum += area(childEnlarged.intersect(s)) - area(child.intersect(s));
    }
    return sum;
}

在另一种实现中,它们根据给定节点与所插入项的交集区域进行排序。像这样:

childOverlapEnlargement(Node node, item r)
{
    return area(node.intersect(r));
}

显然,他们的实现在计算上比论文的定义要少。然而,我找不到任何明显的逻辑,为什么这两个计算应该是相等的。

我的问题是:

  1. 两个计算总是以相同的子树被选择结束吗?为什么?
  2. 如果它们确实导致不同的子树被选中,结果是否更好或接近论文的定义?还是这个选择是错误的?
重新阅读他们的实现,我意识到他们并没有比较两个兄弟节点的交集,而是比较每个潜在的叶子节点和被插入的元素的交集。奇怪的是,它们会选择与插入项重叠最少的兄弟项。难道你不想插入到与要插入的项重叠最多的节点上吗?

也许您正在查看的实现有错误或不正确。人无完人。

注意R*-树试图最小化重叠扩展,而不是重叠本身。

一些重叠可能是不可避免的。如果已经存在重叠,则不能期望在插入其他矩形时减少重叠。但是你至少可以试着不增加重叠的数量。

至于性能方面的考虑,请检查是否需要实际计算相交矩形。试着用函数intersectionSize()代替计算area(intersection())。这个确实起作用。例如,如果A.maxX = 1B.minX = 2,我可以立即给出相交的大小为0,而不用考虑任何其他维度。

避免急切地预先计算你可能需要的所有交叉点等。相反,只计算那些你真正需要的。配置您的代码,并查看是否可以优化关键代码路径。那里通常有一些唾手可得的果实。