最小圆覆盖问题

最小圆覆盖问题-一个很经典的问题。
题目大概是,平面上n个点,求一个半径最小的圆,能够覆盖所有的点。
首先,我们可以从一个空集R开始,不断把平面上的点加入到R中,同时维护R的外接圆最小,就可以得到一个简单的解法。
另外一种想法是,先任意选取两个点,以这两个点的连线为直径作圆。再以此判断剩余的点,看它们是否都在圆内(或圆上),如果都在,说明这个圆已经找到。如果没有都在:假设我们用的最开始的两个点为p[1],p[2],并且找到的第一个不在圆内(或圆上)的点为p[i],于是我们用这个点p[i]去寻找覆盖p[1]到p[i-1]的最小覆盖圆。
要想求过确定点p[i]的从p[1]到p[i-1]的最小覆盖圆,我们可以先用p[1]和p[i]做圆,再从2到i-1判断是否有点不在这个圆上,如果都在,则说明已经找到覆盖1到i-1的圆。如果没有都在:假设我们找到第一个不在这个圆上的点为p[j],于是我们用两个已知点p[j]与p[i]去找覆盖1到j-1的最小覆盖圆。

而对于两个已知点p[j]与p[i]求最小覆盖圆,只要从1到j-1中,第k个点求过p[k],p[j],p[i]三个点的圆,再判断k+1到j-1是否都在圆上,若都在,说明找到圆;若有不在的,则再用新的点p[k]更新圆即可。

于是,这个问题就被转化为若干个子问题来求解了。

由于三个点确定一个圆,我们的过程大致上做的是从没有确定点,到有一个确定点,再到有两个确定点,再到有三个确定点来求圆的工作。

关于正确性的证明以及复杂度的计算这里就不介绍了,可以去看完整的算法介绍:http://wenku.baidu.com/view/162699d63186bceb19e8bbe6.html

相关问题1:
海面上有一些船需要与陆地进行通信,需要在海岸线上布置一些基站。现将问题抽象为,在x周上方,给出N条船的坐标p1,p2,…,pn,pi=(xi,yi),xi>=0,yi<=d, 1<=i<=N,在x轴安防的基站可以覆盖半径为d的区域内所有点,问在x轴上至少要安放几个点才可以将x轴上方的点都覆盖起来。试设计一个算法求解该问题

设计思路:
首先将所有的点按横坐标从小到大进行排序。当点集不空的时候,每次取出最左边的点,将该点视做圆周上的点,以该点到x轴上距离为d的点作为圆心,以d作为半径,画出一个圆,然后去除掉包含在该圆内的点。然后继续选出一个最左的点,重复以上操作,直至点集为空,表示所有点都被覆盖,此时得出的圆的个数就是所求答案.

相关问题2:
给定平面上n个点的坐标,求能够覆盖所有这些点的最小矩形面积。
首先我们思考这样一个问题,给定平面上的n个矩形(坐标为整数,矩形与矩形之间可能有重叠的部分),求其覆盖的总面积。平常的想法就是开一个与二维坐标规模相当的二维Boolean数组模拟矩形的“覆盖”(把矩形所在的位置填上True)。可惜这个想法在这里有些问题,因为这个题目中坐标范围相当大(坐标范围为-10^8到10^8之间的整数)。但我们发现,矩形的数量n<=100远远小于坐标范围。每个矩形会在横纵坐标上各“使用”两个值(矩形的上下、左右边界), 100个矩形的坐标也不过用了横(纵)坐标中-10^8到10^8之间的200个值。也就是说,实际有用的值其实只有这么几个。这些值将作为新的坐标值重新划分整个平面,省去中间的若干坐标值没有影响。我们可以将坐标范围“离散化”到1到200之间的数,于是一个200*200的二维数组就足够了。实现方法正如本文开头所说的“排序后处理”。对横坐标(或纵坐标)进行一次排序并映射为1到2n的整数,同时记录新坐标的每两个相邻坐标之间在离散化前实际的距离是多少(在离散化以后,实际上整个图形空间变小了,这样便于计算,但是对于每条线一定要有对应于原图的映射,这样才能计算出正确的面积,如下图离散后的图形中每个格对应的实际长宽都不同,实际面积也有不同)。
这里写图片描述
上述思想是离散化的一个实例,可以看出离散化大大降低了空间开销,在某些难以处理的问题上可以有效降低算法时间复杂度,值得学习与借鉴。

猜你喜欢

转载自blog.csdn.net/IqqIqqIqqIqq/article/details/80227154