728x90
복습하기 위해 학부 수업 내용을 필기한 내용입니다.
이해를 제대로 하지 못하고 정리한 경우 틀린 내용이 있을 수 있습니다.
그러한 부분에 대해서는 알려주시면 정말 감사하겠습니다.
▶프로그램 입출력 조건
- xy 좌표계에 속한 점의 list(points)를 입력으로 받는 함수 정의
- points는 tuple (x, y)의 리스트임 (예: [(3,2), (4,-1), (0,0), (-2,2)])
- points에 속한 점은 모두 좌표가 서로 다름
- def grahamScan(points):
- 위 함수는 Graham’s Scan을 사용해 convex hull에 속한 점의 좌표를 구한 후 입력과 같은 형식으로 반환
- 최초로 convex hull에 포함하는 점 p는 y 값이 가장 작은 점 중 x 값이 가장 큰 점
- 이후에 convex hull에 포함하는 점은 p로부터 반시계 방향으로 거쳐가는 차례로 포함되어야 함
- Hint: convex hull에 포함하는 점은 stack에 push, pop 하면 편리함 (optional)
728x90
import math
def grahamScan(points):
def ccw(i, j, k):
area2 = (j[0] - i[0]) * (k[1] - i[1]) - (j[1] - i[1]) * (k[0] - i[0])
if area2 > 0:
return True
else:
return False
answer = []
p = []
points.sort(key=lambda x: (x[1], -x[0]))
answer.append(points[0])
p.append([0, points[0]])
for i in range(1, len(points)):
a = math.atan2(points[i][1] - points[0][1], points[i][0] - points[0][0])
p.append([a, points[i]])
p.sort(key=lambda x: x[0])
for i in range(1, len(points)):
point = p[i][1]
if i == 1:
answer.append(point)
else:
jj = answer.pop()
ii = answer.pop()
while True:
if ccw(ii, jj, point):
answer.append(ii)
answer.append(jj)
answer.append(point)
break
else:
jj = ii
ii = answer.pop()
return answer
if __name__ == "__main__":
print(grahamScan([(0, 0), (-2, -1), (-1, 1), (1, -1), (3, -1), (-3, -1)]))
print(grahamScan([(4, 2), (3, -1), (2, -2), (1, 0), (0, 2), (0, -2), (-1, 1),
(-2, -1), (-2, -3), (-3, 3), (-4, 0), (-4, -2), (-4, -4)]))
print(grahamScan([(4, 2), (3, -1), (2, -2), (1, 0), (0, 2), (0, -2), (-1, 1),
(-2, -1), (-2, -3), (-3, 3), (-4, 0), (-4, -2), (-4, -4), (0, -3)]))
728x90
'컴퓨터공학 > 알고리즘2' 카테고리의 다른 글
[알고리즘2] Collinear Point 구현 - 실습 (0) | 2022.10.21 |
---|---|
[알고리즘2] Sorting (Merge Sort, Quick Sort) (0) | 2022.10.21 |
[알고리즘2] Sorting (Shell Sort, Shuffle Sort, Convex Hull) (0) | 2022.10.13 |
[알고리즘2] Percolation with Union Find(WQU) - 실습 (0) | 2022.10.11 |
[알고리즘2] Union Find (1) | 2022.10.11 |