我正在阅读this implementation of the R* Tree,我注意到他们计算的重叠与paper定义重叠的方式不同。
在论文中,重叠定义如下:
对于给定节点/ rect k ,计算 k 与 k 的每个兄弟之间的交集区域总和(不包括的ķ)。
重叠放大则是此值的增量,如果项目 r 添加到 k ,则节点 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));
}
显然,他们的实现在计算上没有纸张定义那么密集。但是,我找不到任何明显的逻辑,为什么两个计算应该相等。
所以我的问题是:
编辑:重新阅读他们的实现,我意识到他们没有比较两个兄弟姐妹的交集,而是每个潜在叶子和插入项目的交集。奇怪的是,他们挑选的兄弟姐妹与插入的物品重叠最少。您不想插入与插入项目最重叠的节点吗?
答案 0 :(得分:1)
也许您正在查看的实现存在错误或不正确。没有人是完美的。
请注意,R * -tree尝试最小化重叠放大,而不是重叠。
有些重叠可能是不可避免的。如果已经存在重叠,则在插入其他矩形时,您不能指望它会减少。但你可以尝试至少不增加重叠量。
至于性能考虑因素,请检查是否需要实际计算交叉矩形。尝试而不是计算area(intersection())
来执行函数intersectionSize()
。这个确实有所作为。例如,如果A.maxX = 1
和B.minX = 2
我可以立即给出交点大小0,而不查看任何其他维度。
避免急切地预先计算您可能需要的所有交叉路口等。相反,只计算您实际需要的那些。 配置文件您的代码,看看您是否可以优化关键代码路径。那里通常有一些低垂的水果。