【问题标题】:Fast algorithm to find out the number of points under hyperplane快速算法找出超平面下的点数
【发布时间】:2012-08-12 16:00:14
【问题描述】:

给定欧几里得空间中的点,是否有一种快速算法来计算一个任意超平面“下”的点数?快意味着时间复杂度低于 O(n)

对点进行预处理或排序的时间还可以

而且,即使不是高维,我也想知道是否存在可以在二维空间中使用的一种

【问题讨论】:

    标签: algorithm geometry partitioning space


    【解决方案1】:

    如果您愿意对这些点进行预处理,那么您必须至少访问每个点一次,即 O(n)。如果您考虑将点在哪一侧的测试作为预处理的一部分,那么您将得到一个 O(0) 算法(使用 O(n) 预处理)。所以我认为这个问题没有任何意义。

    尽管如此,我会尝试给出一个有用的答案,即使这不是 OP 所要求的。

    选择一个超平面单元法线和根点。如果平面以参数形式给出

    (P - O).N == 0

    那么你已经有了这些,只要确保法线是单元化的。

    如果以解析形式给出:Sum(i = 1 to n: a[i] x[i]) + d = 0,那么向量 A = (a1, ... a[n] ) 是平面的法线,N = A/||A||是单位平面法线。平面上的一点O(为原点)为d N。

    您可以通过将每个点 P 投影到 N 上来测试每个点 P 在哪一侧添加检查参数的符号:

    令 V = P - O。V 是从所选原点 O 到 P 的向量。

    设 s N 为projection of V onto N。如果 s 为负数,则 P 在超平面“下方”。

    如果你对这个主题不熟悉,你应该去矢量投影的链接,但我会在这里用我的符号进行总结。或者,您可以相信我的话,直接跳到最后的公式。

    如果 alpha 是 V 和 N 之间的角度,那么根据余弦的定义,我们有 cos(alpha) = s||N||/||V|| = s/||V||因为 N 是单位法线。但是我们也从向量代数中知道 cos(alpha) = ||V||(V.N),其中“.”是标量积(又名点积或欧几里得内积)。

    将这两个表达式等同于 cos(alpha) 我们有

    s = (V.V)(V.N)

    (使用 ||V||^2 == V.V 这个事实)。

    所以你的处理工作是计算 N 和 O,你的测试是:

    bool is_under = (dot(V, V)*dot(V, N) < 0.);
    

    我不相信它可以做得更快。

    【讨论】:

      【解决方案2】:

      设置点值时,使用该点设置的检查条件。然后增加或不增加计数器。 O(n)

      【讨论】:

        【解决方案3】:

        我通过使用分治法和二进制搜索找到了 O(logN) 的二维算法,预处理时间复杂度为 O(N log N),内存复杂度为 O(N log N)

        基本思想是点可以分为左N/2点和右N/2点,线下的点数(2D维度)是线下的左点数之和以及线下正确点的数量。我将把整个点分成“左”和“右”的无限线称为“分界线”。分割线看起来像'x = k'

        如果每个'left points'和'right points'都按y轴顺序排序,那么具体点的个数——右下角的点——可以通过二分查找“点数”快速找到其y值小于线与分界线交点的y值。

        因此时间复杂度为

        T(N) = 2T(N/2) + O(log N)

        最后时间复杂度是O(log N)

        【讨论】:

        • @DeepYellow 如果点按 x 顺序排序,则除左 N/2 点和右 N/2 点需要 O(1) 顺序。
        • 哦.. T(N) = 2T(N/2) + O(log N) 表示 T(N) = O(N),而不是 O(log N).. 我应该找到另一种方式。
        猜你喜欢
        • 2010-09-12
        • 2012-02-25
        • 1970-01-01
        • 2014-02-20
        • 2013-08-30
        • 1970-01-01
        • 2015-10-31
        • 1970-01-01
        相关资源
        最近更新 更多