평면 위에 점들의 집합이 주어졌을 때, Convex Hull 알고리즘은 이 모든 점을 포함하는 도형(점들로 이루어진)을 계산한다. 이 알고리즘은 다양한 차원의 점 집합에도 적용할 수 있지만, 여기서는 평면 위의 점들에 대해 다룬다. 기본적으로 이 알고리즘은 모든 점을 포함하는 선들을 계산한다. 이 문제에 대한 다양한 해결책을 비교할 때, 각 알고리즘의 시간 복잡도를 Big-O 표기법으로 설명할 수 있다.
Convex Hull 알고리즘은 여러 종류가 있지만, 여기서 소개할 해결책은 Quickhull이라는 알고리즘이다. 이 알고리즘은 W. Eddy(1977년)와 A. Bykat(1978년)의 연구에서 각각 독립적으로 개발되었다. Quickhull의 기대 시간 복잡도는 O(n log n)이지만, 최악의 경우 시간 복잡도는 O(n^2)이 될 수 있다. 평균적인 조건에서는 알고리즘이 꽤 효율적이지만, 높은 대칭성을 가진 경우나 원의 둘레에 점들이 위치한 경우에는 시간 복잡도가 기하급수적으로 증가할 수 있다.
Quickhull 알고리즘은 다음과 같이 동작한다:
우리의 함수는 다음과 같이 정의된다:
findHull(points: [CGPoint], p1: CGPoint, p2: CGPoint)
findHull(S1, A, B)
findHull(S2, B, A)
이 함수는 다음과 같은 작업을 수행한다:
points
가 비어 있으면, 직선의 오른쪽에 추가할 점이 없으므로 반환한다.p1
에서 p2
로 직선을 그린다.points
에서 이 직선과의 거리가 가장 먼 점을 찾는다. (maxPoint
)maxPoint
를 p1
바로 뒤에 볼록 껍질에 추가한다.p1
에서 maxPoint
로 직선을 그린다. (line1
)maxPoint
에서 p2
로 직선을 그린다. (line2
) (이제 이 선들은 삼각형을 형성한다)points
에서 line1
의 오른쪽에 있는 점들을 배열 s1
로 그룹화한다.line2
의 오른쪽에 있는 모든 점들은 배열 s2
로 그룹화한다. line1
과 line2
의 오른쪽에 동시에 있는 점은 없다. 그렇지 않으면 maxPoint
가 p1
과 p2
사이의 초기 직선과의 거리가 가장 먼 점이 될 수 없다.findHull(_, _, _)
를 다시 호출하여 더 많은 볼록 껍질 점을 찾는다.findHull(s1, p1, maxPoint)
findHull(s2, maxPoint, p2)
이 과정을 반복하면 결국 볼록 껍질을 구성하는 점들의 배열이 남게 된다.
Swift Algorithm Club을 위해 Jaap Wijnen이 작성함.