【发布时间】:2012-08-12 16:00:14
【问题描述】:
给定欧几里得空间中的点,是否有一种快速算法来计算一个任意超平面“下”的点数?快意味着时间复杂度低于 O(n)
对点进行预处理或排序的时间还可以
而且,即使不是高维,我也想知道是否存在可以在二维空间中使用的一种
【问题讨论】:
标签: algorithm geometry partitioning space
给定欧几里得空间中的点,是否有一种快速算法来计算一个任意超平面“下”的点数?快意味着时间复杂度低于 O(n)
对点进行预处理或排序的时间还可以
而且,即使不是高维,我也想知道是否存在可以在二维空间中使用的一种
【问题讨论】:
标签: algorithm geometry partitioning space
如果您愿意对这些点进行预处理,那么您必须至少访问每个点一次,即 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.);
我不相信它可以做得更快。
【讨论】:
设置点值时,使用该点设置的检查条件。然后增加或不增加计数器。 O(n)
【讨论】:
我通过使用分治法和二进制搜索找到了 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)
【讨论】: