1.问题
给定大量离散点的集合Q,求一个最小的凸多边形,使得Q中的点在该多边形内或者边上
2.应用背景
图形处理中用于形状识别:字形识别、碰撞检测等
3.分治算法
3.1 过程
3.1.1 第一步
- 连接最上面的点和最下面的点,把整个图像划分为两个图像,然后求Deal(Lleft),求Deal(Lright)
- Deal这个函数要怎么设计呢?对于一个图像,比如左边的
找到与d最远的点P,连接最上面的点、最下面的点和P点构成一个三角形,(假设这两个边为 a,b) ,在三角形内部的点直接删掉 - 再划分子问题
以三角形两个边划分,再分为两个区域,即两个子问题- 比如说其中一个子问题(左下角的那个子问题),a就相当于上一步问题的d,于是可以接着用Deal这个函数
3.2 分治算法理解
- 这个算法是怎么把问题规模变小的呢?
- 首先是算法的第一步,把整个原始问题转化为Left和Right,比如说原始问题有10个点,分割完之后左边有3个,右边有5个,还有2个点在分割线上,这样左边这个问题的规模就变成3,右边问题规模就变成5
- 重要的是上面第二步中,在这一步划分三角形且判断点是否在三角形内部之后,在根据三角形的两条边得到的两个新的子问题,介绍算法时那个图中线段a,b形成的两个新的子问题,问题规模也会变小
- 每一次画完三角形之后,都判断点有没有在三角形内部,如果在三角形内部,就删掉这个点,这样加上构成三角形的另外1个点,之后的子问题中就可以少考虑一些点
3.3 Deal的伪码
注意:这里的伪码只是Deal这个函数的伪码,不包括前面把整个图形分为两个子集Left和Right的伪码
3.4 算法分析
-
初始用d划分
- O(n)
- (一开始平面上共有n个点,每一个点都要比较一下是在d左边还是右边)
-
假设Deal递归调用的问题规模为n,设这个复杂度为 W(n),
- 找凸包顶点P为O(n),且画三角形
- 这里没考虑画三角形的时间复杂度,因为画三角形的时间复杂度为常数
- 根据点的位置划分子问题复杂度为O(n)
- 在这一步中要对左平面的点分析哪些点在三角形内部,哪些点不在内部
- 找凸包顶点P为O(n),且画三角形
-
最差时间复杂度的情况为:每次划分三角形内部都没有点可以删除,且每次划分除了在分割线上的两个点,其他全部的点都只在一边,另一边没有点,这样虽然只会有一个子问题,但子问题的规模只减少了1
- 此时 W(n) = W(n-1) + O(n)
- W(3) = O(1)
-
此时W(n) = O(n2)
总的T(n) = O(n) + W(n) = O(n2)