Sweep은 “쓸다”라는 의미를 가지고있는데, 스윕 라인 알고리즘은 빗자루로 먼지를 쓸어내듯이 특정 방향을 따라 스위핑하면서 점 또는 선을 확인하며 답을 찾아가는 알고리즘이다. 선분의 교차 여부, 구간 겹, 점의 분포등을 계산할 수 있기때문에 주로 시/공간의 겹침, 자원할당, 스케쥴링 문제를 다룰때 해결할 수 있는다. 나도 마찬가지로 회의실 예약 관련 Tool을 만들다 접하게되었다.
스윕 라인 알고리즘의 문제 해결과정은 대부분 이렇다:
- 모든 데이터를 특정 기준에따라 정렬한다.
- 스위핑 라인을 이동시키며 데이터를 하나씩 처리한다.
내 경우 회의실이 비는 시간을 파악하기 위해서 사용했는데, 이를 단순화한 예시로 스윕 라인 알고리즘을 알아보자.
3개의 회의실이 있고, 이미 예약된 회의가 있다.
이미 예약된 회의가 다음과 같을때, 2시 반에는 몇 개의 회의실을 사용할 수 있을까?
total_rooms = 3
meetings = [[1, 3], [2, 4], [3, 5]] # 1시~3시, 2시~4시, 3시~5시 예약
check_time = 2.5
# 2시 반에는 몇개의 회의실을 사용할 수 있는가?
먼저, 회의실 예약(meetings)를 시작시간과 종료 시간으로 나누어 배열로 만든다.
events = []
for start, end in meetings:
events.append(('start', start))
events.append(('end', end))
그리고 시간순으로 정렬한다.
events.sort(key=lambda x: x[1])
# [('start', 1), ('start', 2), ('end', 3), ('start', 3), ('end', 4), ('end', 5)]
이제 한 방향으로만 확인하면서 현재 사용중인 회의실 수를 체크할 수 있다.
active_rooms = 0 # 현재 사용 중인 회의실 수
for event_type, time in events:
# 확인할 시간이 현재 이벤트 시간보다 크면 멈춘다.
if time > check_time:
break
if event_type == 'start':
active_rooms += 1
else:
active_rooms -= 1
check_time
에 사용중인 회의실을 전체 회의실에서 빼면 특정 시간에 빈 회의실 수를 얻을 수 있다.
available_rooms = total_rooms - active_rooms
return available_rooms
이해를 돕기 위해 ‘start’, ‘end’를 쪼갰지만, 이벤트를 만들때 회의실 수 변화를 함께 처리하면 더 간단하다.
def find_available_rooms(meetings, total_rooms, check_time):
events = []
for start, end in meetings:
events.append((start, 1)) # 회의 시작
events.append((end, -1)) # 회의 끝
events.sort()
active_rooms = 0
for time, change in events:
if time > check_time:
break
active_rooms += change
available_rooms = total_rooms - active_rooms
return available_rooms
'프로그래밍 > Algorithm' 카테고리의 다른 글
알고리즘 실전 활용을 위한 요약 (1) | 2018.05.29 |
---|---|
[JAVA] 재귀함수를 이용한 미로 찾기 (1) | 2018.01.17 |
[C++] 이진 탐색 트리 구현하기 (Binary Search Tree) (0) | 2017.05.22 |
[C++] 이진 트리 구현하고 순회하기 (Binary Tree in C++) (2) | 2017.05.21 |
자료구조 : 큐(Queue) 이해하고, 구현하기 in C++ (4) | 2016.12.24 |