问题描述:
在平面上有n个点,其中任何三个点都不在一条直线上,问如何寻找一个点集,使得这些点构成的多边形刚好能把所有点都包进。
基本思想:
我们采用分治算法。首先算出这n个点的横坐标中位数,记为x0,画出直线x=x0,将整个平面分成两部分。我们要做的就是分别求两部分的凸包,最后再合并即可。利用分治和递归的结合,该问题就迎刃而解了。
难点解析:
本问题最难的部分在于两个凸包的合并过程。为此,我小小的翻了一下墙,在YouTube上学习了MIT的思想,现在和大家分享一下。假设直线左侧的凸包外围点按照顺时针分别记为a1,a2,…,ai,右侧凸包的外围点按照顺时针分别记为b1,b2,…,bj(如图所示)
我们先将a1,b1连起来,在中线上的交点记为o1
接着,右侧点顺时针移动一个点,变成a1,b2,交点为o2,但是我们发现o2比o1位置更低,因此右侧点还是回到b1,接着左侧点逆时针移动到a4,连接a4,b1,发现交点o3更高了
如法炮制,右侧点顺时针移动,发现交点又变低,于是左侧点逆时针移动,也变低了,因此我们就可以确认,a4,b1就是合并后凸包的上边沿了。同理,下边沿也按照相同的操作完成。
最后合并时,只要沿a4或a3逆时针移动一圈,保留有用的点就可以了。
由于我也是第一次接触这样的做法,因此还未完全实现这种算法合理性的证明和代码的实现,还请大家见谅哈