📅  最后修改于: 2023-12-03 15:36:49.799000             🧑  作者: Mango
凸包(convex hull)是由一组点构成的最小凸多边形,包含所有给定点。凸包是许多计算几何问题的基础。
凸包问题可以用许多算法来解决,而其中贾维斯算法和包装算法是比较常见、易于实现的算法之一。
贾维斯算法(也被称为公式法或左转法)是一种简单但低效的算法。它的基本思想是从点集中选中最左端的点,然后每次向左转去连接下一个点,直到构建出整个凸包。时间复杂度为 O(nh),其中 n 是给定点集的大小,h 是凸包中的点数。
伪代码如下:
定义函数jarvis(points):
p = 最左边的点
result = {}
i = 0
repeat:
result.add(p)
endpoint = points[0]
for j from 1 to n:
if (points[j] == p) or (endpoint == p) or (cross_product(p, endpoint, points[j]) > 0):
endpoint = points[j]
p = endpoint
i = i+1
until endpoint == result[0]
return result
其中,cross_product(p, q, r)表示向量pq和pr之间的叉积。如果向量pr在向量pq的左边,则叉积结果为正;在右边则为负。
贾维斯算法的优点是实现简单、易于理解。但是,它的时间复杂度较高,特别是当点集中有很多共线点时。
包装算法(Graham's Scan Algorithm)是一种改进的凸包算法,它的时间复杂度为O(nlogn)。
其基本思想是:首先找到一个最低点(即y坐标最小的点),然后将点集按照到该点的极角升序排序(如果极角相同,则按照距离目标点近的优先),最后依次将点加入凸包中。
伪代码如下:
定义函数graham_scan(points):
# 找到最低点
first_point = lowest_point(points)
# 将点集按照极角排序
sorted_points = sort_by_polar_angle(points, first_point)
# 依次将点加入凸包中
hull = []
for p in sorted_points:
while len(hull) > 1 and orientation(hull[-2], hull[-1], p) <= 0:
hull.pop()
hull.append(p)
return hull
其中,orientation(p, q, r)表示向量pq和pr之间的方向。如果向量pr在向量pq的左边,则方向结果为正;在右边则为负。
包装算法的优点是时间复杂度较低,适用于处理大型数据集。