预期的二进制空间分区算法

时间:2016-03-14 16:19:46

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

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]。

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

3 个答案:

答案 0 :(得分:0)

使用S非空的BSP调用与生成的片段一一对应。每次调用最多使用S empty进行一次递归调用,这不会产生递归调用,因此调用的总数受到生成的片段数量的两倍的限制。因此,这一陈述符合预期。

答案 1 :(得分:0)

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

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

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

为了避免这种情况,您应该开发启发式算法来执行行L的选择,使得拆分是平衡的并且不会生成太多碎片。但你不能完全避免最坏的情况,只是极不可能。

这种情况提醒快速排序,具有O(N Log(N))预期行为,但O(N²)最坏情况。后者通过使用“三个中值”启发式来选择枢轴来驯服。

答案 2 :(得分:0)

我们证明,每次输入算法的主体时,都会消耗一个片段:

  • 我们可以忽略var message = MyUnsafeObjectAccess.Foobar; Deployment.Current.Dispatcher.BeginInvoke(() => MessageBox.Show(message)); // safe 为空的情况,因为这可能会在算法中被“黑客攻击”,从而避免递归调用
  • 如果S包含单个元素,则会使用此元素(并且不会再发生递归调用)
  • 如果S包含多个元素,则至少消耗S的第一个元素,导致它被选为分割线S(并且不会发生进一步的递归调用);事实上,lS重叠的所有元素都被消耗了(但同样,这与我们无关,因为我们对最坏情况的约束感兴趣)

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