【问题标题】:Kd-Tree Insertion OrderKd-Tree 插入顺序
【发布时间】:2021-10-10 23:29:25
【问题描述】:

我正在使用 KD-Tree 来优化对一组 2D 点 (x,y) 的范围搜索。 为了节省时间,我尝试使用 Java Topology Suite 的 KD-Tree。 但是,javadoc 声明:

请注意,KD-Tree 的结构取决于点的插入顺序。如果插入的点是连贯的(例如在一维或两个维度上单调),则树可能会变得不平衡。完美平衡的树只有 log2(N) 的深度,但不平衡的树可能更深。这对查询效率有严重影响

所以我的问题是:如何以最小化树高的方式将点插入 KD-tree

【问题讨论】:

    标签: java kdtree


    【解决方案1】:

    In 不会太担心。这有点像哈希映射,如果所有条目都必须发生相同的哈希码,则理论上它具有 O(n) 查找。实际上,除非哈希函数有问题,否则这种情况不太可能发生。

    为避免不平衡,您应确保您的积分没有以任何方式排序。如果是,请考虑在插入之前对其进行洗牌。

    另外,一些 kd-tree 实现有一个 rebalance() 函数,可以在插入(大部分)数据后调用。这将在内部重新平衡树。

    最后,如果您真的想使用避免不平衡的特定插入顺序,您可以执行以下操作。请注意,这种方法不是最优的,它会避免最坏的情况,但通常不会产生完全平衡的树: 按 x 坐标对点进行排序,然后使用二分搜索插入它们。例如,如果您有 15 个点,则按“x”对它们进行排序以获得点 p0...p14 的排序列表。那么:

    1. 取范围 (p7) 中的中间点并将其插入。
    2. 为分割点的每一边创建一个新范围:p0-p6 和 p8-p15
    3. 从 1) 重新开始,分别使用两个范围

    这会产生以下插入顺序:

    1. 回合:p7
    2. 圆形:p3 和 p11
    3. 圆形:p1、p5、p9、p13
    4. 圆形:p0、p2、p4、p6、p8、p10、p12、p14

    为什么这不理想?

    • 我们完全忽略了 y 坐标。这种方法只能避免 y 坐标的不平衡。
    • 典型的 kd 树在 x 和 y 之间交替分裂。然而,我们不知道在给定的实现中哪个先出现,所以我们只能假设它总是在 x 上分裂。这不会立即造成伤害,但会妨碍更优化的插入。

    【讨论】:

      猜你喜欢
      • 2014-01-27
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 2015-11-20
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 2014-10-16
      相关资源
      最近更新 更多