【问题标题】:Expected running time of the binary space partition algorithm二值空间划分算法的预期运行时间
【发布时间】:2016-03-14 16:19:45
【问题描述】:

Computational Geometry: Algorithms and Applications by Mark de Berg 中可以找到以下binary space partitioning 算法:

BSP(Finite set of finite non-intersecting line segments S)
{
    if (n > 1)
    {
        Use the extension of the first segment in S as the splitting line L
        Let S+ and S- be the set of fragments above and below L, respectively
        Create a tree T with left subtree = BSP(S-) and right subtree BSP(S+)
        Store all segments which overlap with L in T
    }
    else
        Create a tree T and store S in T
    return T
}

如果分割线L将一个片段分成两半,则生成一个片段。您可能想查看another question of me where I give an example for this process

We can show 表示BSP 生成的片段的预期数量最多为n + 2n log(n),如果这些片段是随机打乱的(这样这些片段的每个可能的排列都有相同的出现概率)并且n 表示段数。

我们如何限制预期的递归调用次数?

de Berg 的书中,作者指出,递归调用的预期数量受生成片段的预期数量的限制。 为什么


显然,一条分割线L最多可以产生n - 1新片段。在最坏的情况下,所有这些新片段都位于L 的一侧。在这种情况下,S+S- 中的每一个都将包含n - 1 元素。因此,我们将有两个递归调用,输入大小为n - 1。这导致T(n) = n - 1 + 2 * T(n - 1) 的递归运行时间。 [n - 1 因为这是我们需要测试它们是否高于或低于L 的元素的数量。

我们可以展开递归,但我认为这会产生非常糟糕的估计。那么,我们需要怎么做呢?我们如何利用已知的预期生成片段数?

【问题讨论】:

    标签: algorithm 3d time-complexity computer-science computational-geometry


    【解决方案1】:

    对 S 非空的 BSP 的调用与生成的分片一一对应。每个调用最多进行一次递归调用,其中 S 为空,即不进行递归调用,因此调用的总数以生成的片段数的两倍为界。由此可见,这种说法在预期中成立。

    【讨论】:

    • 我很清楚调用树的叶子要么是空的(即S 是空的),要么包含一个独特的片段。 但是我不认为这棵树是完整的。请查看this example。如果它们被选为分割线,我已经扩展了黑色部分。它们按 3、6、4、5、2 的顺序选择。对应的调用图类似于 this。在“:”之后,我写下了调用中传递的段。 1+ 和 1- 代表由 3 诱导的分割线上方和下方的片段。
    • 如您所见,树并不完整。有些叶子在深度 2,有些在深度 3。
    • @0xbadf00d 我的意思是完整的 0 或 2 个孩子。 S 为空的调用是一个小问题;查看我的编辑。
    • 每次调用S nonempty 都会进行两次递归调用,但我不明白为什么递归调用的总数应该是生成片段数的两倍。我认为需要一些论证来表明该算法“取得了进展”。正如我在问题中所写,我们只知道每个递归调用的输入大小最多为n - 1。能否请您详细解释一下为什么您认为递归调用的数量应该是生成片段数量的两倍?
    • @0xbadf00d 您需要将s1 排除在递归调用之外,否则您不会取得进展。
    【解决方案2】:

    “我们如何限制递归调用的预期数量?”:你不能。算法描述解释说,这个预期数量受预期片段数量的限制,您无法直接控制。

    当段足够随机时,这个数字是 O(N Log(N)),这很好。但对于其他发行版,它可能会更高甚至更低。

    此外,您还担心最坏的情况,其复杂性可能是灾难性的(如 O(N²))。

    为了避免这种情况,您可能应该开发启发式方法来执行 L 线的选择,以使分割是平衡的并且不会产生太多片段。但你不能完全避免最坏的情况,只能让它极不可能发生。

    这种情况让人想起快速排序,它有 O(N Log(N)) 的预期行为,但 O(N²) 最坏的情况。后者是通过使用“三的中位数”启发式选择枢轴来驯服的。

    【讨论】:

      【解决方案3】:

      我们展示了每次输入算法的主体,都会消耗一个片段:

      • 我们可以忽略S 为空的情况,因为这可能会在算法中被“破解”,从而避免递归调用
      • 如果 S 包含单个元素,则消耗该元素(并且不会发生进一步的递归调用)
      • 如果 S 包含多个元素,则至少消耗S 的第一个元素,因为它被选为分割线l(并且不会发生进一步的递归调用);事实上,Sl 重叠的所有元素都被消耗掉了(但同样,这在这里无关紧要,因为我们对最坏情况的界限感兴趣)

      因此,递归调用的数量受生成的片段数量的限制。由于生成的片段的预期数量是O(n ln n),因此递归调用的预期数量也是O(n ln n)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多