Algorithm 覆盖n个点的最小圆数
当n个点位于一条直线上时,覆盖所有n个点所需的半径为r的最小圆数是多少 我知道有人问了一个类似的问题 在这里之前。 我的尝试:我试图在线性时间内解决它, 我想到了这个算法:Algorithm 覆盖n个点的最小圆数,algorithm,math,graph,Algorithm,Math,Graph,当n个点位于一条直线上时,覆盖所有n个点所需的半径为r的最小圆数是多少 我知道有人问了一个类似的问题 在这里之前。 我的尝试:我试图在线性时间内解决它, 我想到了这个算法: 将求解第一个点的第一个圆放置到位 通过检查这两个点之间的距离是否小于2*r,求解最小圈数中的第二个点。并在所有n点的过程中继续。 我认为这是贪婪算法,但它是最优的和线性的吗 我能想到的最简单的方法是,将你的点放在一个数组中 迭代每个点,加上它与前一点之间的距离,直到累计距离大于2r 添加到全局计数器1。重置距离,重复 在伪
我能想到的最简单的方法是,将你的点放在一个数组中 迭代每个点,加上它与前一点之间的距离,直到累计距离大于2r 添加到全局计数器1。重置距离,重复 在伪代码中:
count = 1
last_point = point_list[0]
distance = 0
for(point in point_list)
distance += norm(point - last_point)
if(distance >= 2r)
count++
distance = 0
last_point = point
证明
基本情况:
它适用于n=1,这很简单
感应情况:
假设它适用于n到k种情况
假设线中引入了一个新点
情况1,该点位于最后一个计算圆的内部。然后在循环的下一次迭代中,if语句中的条件不满足,计数不增加,算法返回正确的答案
情况2,该点位于最后一个计算圆的内部之外。
然后,由于对其他k元素的覆盖是最小的,因此不可能重新排列圆以覆盖新的点。因此,我们必须引入一个新的循环
在这种情况下,如果满足if的条件,则计数增加1。我们再次返回正确的数字
我们已经证明了归纳的情况
冗长的证明
您必须接受latex符号,因为堆栈溢出不会格式化latex
假设我们有一组点$p$。假设$d=max(| p|i-p|j |)$,其中$p|i,p|j\以p$表示。如果$d<2r$,则半径r的某些磁盘$C$的$P\C$子集
给定一个新点$q\notin p$,如果$max(| | q-p | | | | | | | |)<2r$,其中$p\在p$中,则$\存在一个磁盘$D$,这样${q}\cup\子集D$
否则,如果$max(| | q-p | |)>2r$,则不存在这样的磁盘,否则磁盘中会有2个点的距离大于2r,这是荒谬的
这是引理1
假设我们有一组这样的集合$S$,即S中的$S\意味着S={x | | | | x-y |2r\text{if}y\在S}$。对于所有的$s\ in s$,如果$x\ in s$,那么$x\ in L$,其中$L$是某一行。同样假设如果${x\在s1\在S}$中,而$y\在s2\在S$中,那么$| | x|U 1-x|U 2 | |>=2r$
由于点位于a上,根据定义,$\exists x_0$和$\vec{d}$($\vec{d}$为单位向量),因此点可以相对于其到$x_0$的距离排序,WLOG假设$x_0$是$S$中的一个点,这样$\vec{d}\cdot(x-x_0)\geq 0$,其中$x\在S$中
这意味着,对于s\中的每个集合$s\u i \存在D\u i$,因此通过构造,$s\u i\子集D\u i$和$D\u i\cap D\u j=\empty$if$i\neq j$。并且磁盘${D_i}$排列有序
设s$中的$s{max}\为集合,使得所有这些$x$的$\vec{d}\cdot(x{max}-x_0)\geq\vec{d}\cdot(x_i-x_0)$中的$\x{max}\在s_max$中,x\在s$中。或者在简单的英语中,$s_max$是包含距离$x_0$最远的点的集合
假设现在将一个新点$q$添加到直线中,使其到$x_0$的距离大于$x_max$
根据引理1,要么圆的总数保持不变,要么增加1,如果$max(| q-x | | | |)>=2r$,则只增加1,其中$x\在s|{max}$
这是引理2
然后参考上一节中描述的算法。
当连续点序列的跨度小于$2r$时,$\D$存在一个包含这些点的磁盘(根据前面的参数)。如果在序列中找到一个新点,使其到最远点的距离超过$2r$,则需要一个额外的圆(同样由引理1)
引理2假设,要知道是否需要一个新的圆,我们只需要关注最后一组点,前提是我们按顺序访问了这些点(以及这些点集)。如果一个新点在最后一个集合中最远点的距离内小于2r,则不需要新的圆,否则需要一个新的圆(引理1),因此我们关注这个新点(及其相关集合)
我们会一直这样做,直到访问完所有点为止
我们已经成功地证明了该算法是最小的
(我们不需要关心圆在哪里:^))我认为我不能在线性时间上做,而是O(n*logn) 因为它们在同一条线上,所以我会将其中一个设置为参考点(
0
),并根据它们到参考点的距离将它们添加到一个数组中。现在二维位置转换为一维
然后对它们进行排序(O(n*logn)
)。然后通过将圆的最左侧位置放在当前点的顶部来迭代这些点
例如,在排序后,点的位置是-3-2,0,1,2,10
,也就是说r=1
第一个圆圈从-3到-1
,第二个圆圈从0到2
,最后一个圆圈从10到12
。因此将使用3个圆
请注意,此算法不假定数字和距离为整数。为了简单起见,我使用了整数。你的问题与前面的问题有什么不同?@PresidentJamesK.Polk这些点被放置在一条直线上。如果这些点不是按顺序排序的,并且你希望最终结果看起来像一组重叠的圆(O(n))和间隙(O(n),那么你似乎不可能在线性时间内解决这个问题)当您从未排序的输入构建组时,您需要以某种方式跟踪这些组。伊恩:有人告诉过你这在线性时间内是可能的吗