平面上有n个点,如何近似找到覆盖这些点中某些k的圆的最小半径?数字n应该小于10 ^ 4.
维基百科上的案例k == n有lots of information,但我在一般情况下一无所获。
答案 0 :(得分:3)
这是一种算法,在给定半径r > 0
和近似常数c > 0
的情况下,返回一个半径为(1+c) r
的圆,至少包含k
个点或声明没有半径为r
的圆圈,严格限制至少k
个点。运行时间为O(n (1 + k^-1 c^-2 log c^-1))
,当与二分搜索结合使用以获得足够粗略的估计时,应该比tmyklebu的算法更快。 (要初始化搜索,可以及时O(n^2)
获得2
- r
的近似值,方法是循环遍历点并运行quickselect以查找k
最接近的另一点。)
将点(x, y)
放在标有(floor(x/(2r)), floor(y/(2r)))
的方框中,对点进行分区。每个半径为r
的圆都有一个重叠最多四个箱的内部。如果存在半径为r
且至少包含k
个点的圆圈,则存在i, j
,以使这些二进制位(i, j), (i, j+1), (i+1, j), (i+1, j+1)
至少保持k
个点。
对于每个子问题,将每个参与点(x, y)
放在一个较小的方箱(floor(x/w), floor(y/w))
中,其中w = cr/(3sqrt(1/2))
的宽度足够小。现在准备一个O(c^-1)
到O(c^-1)
矩阵,其中每个条目告诉相应的bin中包含多少个点。将此矩阵在二维中进行卷积,使用零一矩阵表示完全包含在半径 - (1+c)r
圆中的箱。后一种矩阵可能看起来像
01110
11111
11111
11111
01110.
现在,我们知道网格上的每个中心都有一个数字,该数字的下限是半径为r
的圆所包含的点的数量,以及半径为(1+c) r
的圆所包含的点数的上限。
答案 1 :(得分:2)
给定候选半径r
,您可以通过获取每对r
点并查看有多少点,找到半径为(p1, p2)
的圆圈可包含的最大点数点数由半径为r的两个圆圈中的每个圆圈包含,边界上有p1
和p2
。
了解这一点,您可以二分搜索最小的r
,以便某个半径r
的圆包含k
个或更多的点。
答案 2 :(得分:-2)
有一种想法是你可以将所有点的平均值作为中心,然后增大半径直到你覆盖了k点。在相当统一的分布下,这可能会做得很好,但是对于“块状”数据会失败。例如,如果这些点位于彼此远离的两个紧密簇中并且k足够小以至于只需要其中一个,那么这将非常失败。如果存在这种聚集的可能性,请考虑使用聚类算法来识别本地聚类,然后如果其中一个包含足够的点,则使用该聚类上的算法。