밴드 동아리 스케줄러 만들기
내가 만들고 싶은건 아니고 부탁받았다.
내용은 아래와 같다.
- 팀은 월 화 수 목 금
- 세션은 보컬 신디 베이스 기타 드럼
- 각 팀마다 세션에 들어가는 인원이 최소 한 명 이상은 있어야 함
- 팀의 특정 세션의 최소, 최대 인원수를 정하고 돌릴 수 있으면 좋겠음
- ex) 월요일팀 보컬 1~2 기타 1~3 베이스 2 신디 2~3 드럼 2
- 이름, 가능한 세션(복수선택 가능), 가능한요일(복수선택 가능), 희망하는 최대 팀 개수를 입력
- 팀을 짤 때 둘 이상의 세션에 한 사람만 들어가면 안됨
- ex) 보컬 A, 기타 A, 신디 B, 베이스 C, 드럼 D
- 희망하는 최대 팀 개수가 2 이상인 사람을 팀에 그보다 적게 넣어도 팀이 짜진다면 굳이 더 넣을 필요 없음
- 꼭 한 팀에 붙어야 되는 사람을 정할 수 있으면 좋겠음 (희망사항ㅎㅎ)
- ex) E랑 F는 꼭 같은 팀이어야 한다.
c++ 기반으로 작성할 예정이고 파일 입출력을 통해 동아리원들 정보를 받고 시간표를 출력한다.
자고 일어나서 만들자.
일어났다. 동아리원이 30명 정도이기 때문에 최소의 경우로 인당 단 하루 한개의 세션을 선택해도 경우의 수는 아래와 같다. $$25^{30}$$ 계산기피셜 자릿수만 42자리다. 모든 경우의 수를 다 대입해보는 것은 무리라고 생각했고 최적의 시간표를 만드는 방법을 찾아야 했다.
우선 개인별로 아래와 같은 하나의 시간표를 가진다.
예를 들어 A라는 사람은 화, 수, 목요일에 출석이 가능하고 기타와 베이스를 다룰줄 안다고 가정하자.
보컬:V 기타:G 베이스:B 신디:S 드럼:D
A의 시간표
| 월 | 화 | 수 | 목 | 금 | |
|---|---|---|---|---|---|
| V | |||||
| G | O | O | O | ||
| B | O | O | O | ||
| S | |||||
| D |
개인별로 저런 형태의 시간표를 가지고 이를 3차원 배열로 저장한다.
다음으로 모든 시간표들로부터 각 칸의 빈도수를 저장할 2차원 배열을 만든다.
빈도수
| 월 | 화 | 수 | 목 | 금 | |
|---|---|---|---|---|---|
| V | 3 | 2 | 3 | 1 | 1 |
| G | 1 | 1 | 1 | 1 | 1 |
| B | 3 | 2 | 3 | 1 | 1 |
| S | 1 | 1 | 1 | 1 | 2 |
| D | 1 | 1 | 1 | 1 | 2 |
숫자가 클 수록 상대적으로 널널한 시간대라고 볼 수 있다.
여기서 각 시간대별로 사용자가 미리 저장해둔 최소인원을 빼면 그 시간대에 움직임이 자유로운 가용인원 즉, 후에 가중치로 사용될 표가 생성된다.
시간대가 비어있어서 시간표 생성이 불가능하거나 최소인원보다 적게 인원이 집계된 경우와 같은 예외처리를 해준다.
모든 준비를 마치면 모든 사람의 시간표들을 체크하며 세로선당 가중치가 가장 작은 부분의 스케줄을 제외하고 모두 삭제한다.
이후 희망하는 최대 요일 수 만큼 남을 때 까지 가중치가 큰 순서대로 제외한다.
문제점을 발견했다. 쓰기 귀찮아서 사진으로 대체한다.
