Kd-Tree 插入顺序
Posted
技术标签:
【中文标题】Kd-Tree 插入顺序【英文标题】:Kd-Tree Insertion Order 【发布时间】:2021-10-10 23:29:25 【问题描述】:我正在使用 KD-Tree 来优化对一组 2D 点 (x,y)
的范围搜索。
为了节省时间,我尝试使用 Java Topology Suite 的 KD-Tree。
但是,javadoc 声明:
请注意,KD-Tree 的结构取决于点的插入顺序。如果插入的点是连贯的(例如在一维或两个维度上单调),则树可能会变得不平衡。完美平衡的树只有 log2(N) 的深度,但不平衡的树可能更深。这对查询效率有严重影响
所以我的问题是:如何以最小化树高的方式将点插入 KD-tree?
【问题讨论】:
【参考方案1】:In 不会太担心。这有点像哈希映射,如果所有条目都必须发生相同的哈希码,则理论上它具有 O(n) 查找。实际上,除非哈希函数有问题,否则这种情况不太可能发生。
为避免不平衡,您应确保您的积分没有以任何方式排序。如果是,请考虑在插入之前对其进行洗牌。
另外,一些 kd-tree 实现有一个 rebalance() 函数,可以在插入(大部分)数据后调用。这将在内部重新平衡树。
最后,如果您真的想使用避免不平衡的特定插入顺序,您可以执行以下操作。请注意,这种方法不是最优的,它会避免最坏的情况,但通常不会产生完全平衡的树: 按 x 坐标对点进行排序,然后使用二分搜索插入它们。例如,如果您有 15 个点,则按“x”对它们进行排序以获得点 p0...p14 的排序列表。那么:
-
取范围 (p7) 中的中间点并将其插入。
为分割点的每一边创建一个新范围:p0-p6 和 p8-p15
从 1) 重新开始,分别使用两个范围
这会产生以下插入顺序:
-
回合:p7
圆形:p3 和 p11
圆形:p1、p5、p9、p13
圆形:p0、p2、p4、p6、p8、p10、p12、p14
为什么这不理想?
我们完全忽略了 y 坐标。这种方法只能避免 y 坐标的不平衡。 典型的 kd 树在 x 和 y 之间交替分裂。然而,我们不知道在给定的实现中哪个先出现,所以我们只能假设它总是在 x 上分裂。这不会立即造成伤害,但会妨碍更优化的插入。【讨论】:
以上是关于Kd-Tree 插入顺序的主要内容,如果未能解决你的问题,请参考以下文章