中文版背景:最少圆覆盖
在二维欧几里得平面上,给出n个点的坐标(x, y),和一个圆的半径大小r,求至少多少个这样半径的圆可以覆盖所有的点?(n <=20, |x|, |y| <= 180, 给定的每组(x, y)间的距离不会小于等于0.1)
英文版背景:Minimum Geometric Disk Cover Problem (MGDC):
Given a set P of n points in the Euclidean plane, the minimum geometric disk cover (MGDC) problem is to identify a minimally sized set of congruent disks with prescribed radius r that cover all the points in P.
输入:
一共有t组, 每组数据中第一行是点的数量n, 接下来第2到第n+1行,每行两个数据表示n个点的坐标,第n+2行是圆的半径大小
输出:
输出t行,每行一个数字,表示该组数据需要的最少的圆的数量
以下为一组样例:
input:
2 2 17.2345 20.5678 15.34 28.342 3.5 2 -180 -180 -1 -1 254
output:
2 1
解法1:暴力动态精度分配近似算法(实现简单)
题目显然是np-hard问题,我们使用近似算法来逼近正确答案,由于数据范围很小只有20,因此遍历点比遍历地图要更优的多,我们规定在1s内完成该算法,因此该程序最多进行约1kw次运算,由于浮点运算有精度的要求,我们不能同时兼顾精度和时间,因此我们根据给出的数据范围动态地安排精度, 我们设精度为d_eps, 即dynamic eps
伪代码:
遍历所有的点
该点的坐标为(x, y)
在(x - r, y - r)到(x + r, y + r)的矩形范围内以d_eps为间隔生成
个圆心
在这些圆中找到一个能覆盖点最多的圆(最优圆)
选择使用这个圆并移除所有被该圆覆盖的点
继续遍历没有被移除的点
时间复杂度
遍历所有的点复杂度为O(n), 生成圆心复杂度为, 找到其中的最优圆复杂度为O(n), 因此总复杂度为
, 我们令上面的多项式值为1kw,即可计算出预设的动态精度的值
,该操作使得该算法在极限数据的情况下,理论运算时间恒为1s左右,实际运行中由于剪枝过程使得运算时间大大减少,若要牺牲时间换取更高的精度,则可以将1kw更换成5kw等更大的数
算法优化
按照矩形生成圆心在一定程度上非常地浪费空间,只是实现方法容易。
还有一种更好的方法可以在提高算法精度的同时,不以牺牲时间为代价。
想法如下:
在选取一个点的时候,以该点为圆心,r为