근무표를 만드는 두 방식, 룰베이스와 AI
병원 담당자분들을 만나면 자주 듣는 질문이 있습니다. "다른 근무표 프로그램도 AI라고 하던데, 뭐가 다른 건가요?"
소개서만 봐서는 구분이 어렵습니다. 근무표를 자동으로 만들어 준다는 설명도, AI라는 표현도 대개 비슷하게 적혀 있으니까요. 하지만 안에서 근무표를 만드는 방식은 크게 두 갈래로 나뉩니다. 사람이 정해 준 순서대로 칸을 채우는 룰베이스, 그리고 조건을 받아서 근무표 전체를 놓고 가장 나은 배치를 찾아내는 AI입니다.
두 방식은 조건을 새로 넣을 때, 나이트를 고르게 나눌 때, 계산 시간을 들일 때, 그리고 병동 규모가 커질 때 각각 다르게 움직입니다. 아래에서 하나씩 살펴보겠습니다.
룰베이스는 정해진 순서대로 칸을 채웁니다
나이트를 먼저 배치하고, 나이트 다음 날은 오프로 막고, 오프 신청을 넣고, 남은 칸을 데이와 이브닝으로 채웁니다. 이 순서가 코드에 고정되어 있습니다. 규칙마다 순위가 매겨져 있어 위에서부터 차례로 적용되고, 순위가 낮은 규칙은 앞 규칙이 채우고 남긴 자리 안에서만 움직입니다.
잘 만든 룰베이스는 여기에 보정 단계를 붙입니다. 다 채운 뒤 두 사람의 근무를 맞바꿔 보면서 더 나아지면 채택하는 방식이 대표적입니다. 배정이 막히면 몇 칸 되돌아가 다시 시도하는 되돌리기를 넣기도 합니다.
그래서 룰베이스와 AI의 차이는 좋은 결과를 낼 수 있느냐 없느냐가 아닙니다. 그 결과를 내기 위해 사람이 무엇을 얼마나 설계해야 하느냐입니다.
AI는 조건과 벌점으로 문제를 적고 배치를 탐색합니다
AI 방식에는 순서를 알려 주지 않습니다. 대신 두 종류의 조건을 적습니다.
반드시 지켜야 하는 조건은 어기는 순간 그 근무표를 답에서 제외합니다. 하루에 두 근무를 설 수 없다는 것, 그날 필요한 인원을 채워야 한다는 것이 여기 들어갑니다. 지키면 좋은 조건은 어길 때마다 벌점을 매깁니다. 나이트 뒤 오프가 한 날에 몰리는 것, 한 조에 신규만 모이는 것이 여기 해당합니다.
이렇게 적어 두면 프로그램은 만들 수 있는 근무표 가운데 벌점 합이 가장 낮은 것을 찾습니다. 이때 근무표를 하나씩 만들어 보고 점수를 매기는 것이 아닙니다. 조건에 어긋나는 배치가 나오면 그 배치에서 뻗어 나가는 경우의 수를 통째로 잘라 냅니다. 3월 7일에 A간호사를 나이트에 넣는 순간 조건이 깨진다면, A간호사가 그날 나이트인 모든 근무표를 한꺼번에 후보에서 지웁니다. 근무표를 한 장씩 세는 대신 가능성의 덩어리를 지워 나가는 방식이라, 경우의 수가 천문학적이어도 답에 닿습니다.
벌점을 아주 크게 주면 사실상 반드시 지키는 조건처럼 다룰 수도 있습니다. 듀티메이커에서 특정 날짜에 근무가 불가능한 사람이 그런 경우인데, 이렇게 두면 거의 지켜지면서도 정말 답이 없는 상황에서는 판 전체가 깨지는 대신 결과가 나옵니다.
| 항목 | 룰베이스 | AI |
|---|---|---|
| 문제를 적는 방법 | 채우는 절차와 규칙 순위 | 조건과 벌점 |
| 새 조건 추가 | 기존 규칙과의 순위 재설계 | 조건 목록에 한 줄 |
| 전체 균형 조건 | 배정 후 보정 단계 필요 | 목적함수에 직접 표현 |
| 앞선 배치 되돌리기 | 되돌리기 단계를 따로 구현 | 탐색 과정에 내장 |
| 계산 시간을 더 들이면 | 재시도 횟수만 늘어남 | 벌점 낮은 배치를 계속 탐색 |
| 결과의 품질 근거 | 없음 | 현재 답과 이론상 최선의 차이 |
새 조건 추가: 룰베이스는 규칙 사이의 순위를, AI는 벌점 하나를 정합니다
병동에서 주당 오프 두 개를 보장해 달라고 요청했다고 해 보겠습니다. 오프를 두 개 넣으려고 근무를 옮기면 그날 인원이 모자랍니다. 인원을 맞추려고 다른 사람을 넣으면 그 사람의 연속 근무가 길어집니다. 연속 근무를 막으려고 또 옮기면 이번에는 한 조에 숙련도가 한쪽으로 몰립니다.
룰베이스에서는 이 연쇄를 개발자가 전부 따라가면서 규칙의 순위를 다시 잡습니다. 규칙이 n개일 때 순위를 정할 때 고려해야 하는 규칙 쌍은 n의 제곱에 비례해 늘어납니다. 규칙 다섯 개일 때 열 쌍이던 것이 열 개가 되면 마흔다섯 쌍입니다. 여기에 "이 규칙은 주말에만 우선한다" 같은 예외가 붙기 시작하면 사람이 머릿속에 담아 둘 수 있는 범위를 금세 넘어갑니다.
AI 방식에서는 조건 목록에 항목 하나를 추가하고 벌점을 얼마로 둘지 정합니다. 규칙끼리 어떻게 부딪히는지는 탐색이 정리합니다. 다만 벌점 값 자체는 사람이 정해야 하고, 숙련도 쏠림과 연속 근무 중 무엇을 몇 배 더 심각하게 볼지에는 정답이 없어서 돌려 보고 조정하는 과정을 거칩니다. 사람이 판단할 몫이 사라지는 것은 아니고, 판단해야 하는 항목의 개수가 규칙 쌍에서 조건 하나로 줄어듭니다.
나이트 균등 배분: 룰베이스는 보정으로 맞추고, AI는 조건으로 적습니다
나이트 개수를 사람들 사이에 고르게 맞춰 달라는 요청은 흔합니다. 이 조건은 칸 하나를 채우는 규칙으로 옮기기 어렵습니다. 3월 7일 나이트에 누구를 넣을지 정하는 시점에는 그 사람이 그달 나이트를 최종 몇 개 갖게 될지 알 수 없기 때문입니다.
룰베이스에서도 방법은 있습니다. 총 나이트 수를 인원으로 나눠 목표 개수를 미리 정해 두고, 다 채운 뒤 개수가 많은 사람과 적은 사람의 근무를 맞바꾸는 보정을 돌리면 상당히 고르게 만들 수 있습니다. 실제로 그렇게 만든 프로그램도 있습니다.
문제는 그 보정을 유지하는 비용입니다. 맞바꾸기 하나하나가 다른 조건을 깨뜨릴 수 있어서, 어떤 맞바꾸기가 허용되는지를 사람이 조건마다 정의해 두어야 합니다. 연속 근무를 넘기지 않는지, 근무 사이 휴게가 남는지, 숙련도가 쏠리지 않는지를 맞바꾸기마다 확인해야 하고, 조건이 하나 늘면 이 확인 목록도 함께 늘어납니다. 게다가 두 사람을 맞바꾸는 것만으로는 좋아지지 않고 세 사람을 돌려야 풀리는 배치가 있는데, 이런 자리에서는 보정이 멈춥니다.
AI 방식에서는 균등함을 조건으로 적습니다. 나이트가 가장 많은 사람과 가장 적은 사람의 차이를 벌점으로 매기거나, 목표 개수에서 벗어난 만큼 벌점을 매기는 식입니다. 그러면 균등함이 연속 근무나 숙련도와 같은 자리에 놓여서, 셋을 한꺼번에 저울질한 결과가 나옵니다. 맞바꾸기 규칙을 따로 만들 필요가 없고, 세 사람을 돌려야 풀리는 배치도 탐색 안에서 함께 다뤄집니다.
계산 시간: 룰베이스는 다시 시도하고, AI는 탐색을 이어 갑니다
룰베이스에서 시간을 더 쓰는 방법은 다시 만들어 보는 것입니다. 시작 조건을 바꿔 여러 번 돌리고 그중 점수가 가장 좋은 것을 고르면, 횟수가 늘수록 결과가 나아집니다. 맞바꾸기 보정을 더 오래 돌리는 것도 같은 효과를 냅니다.
다만 여러 번 만들어 보는 방식은 매번 처음부터 다시 시작하므로 앞 시도에서 알아낸 것이 다음 시도에 쌓이지 않습니다. 백 번 돌려 가장 좋은 것을 골라도, 그것이 얼마나 좋은 답인지는 알 수 없습니다.
AI 방식은 탐색을 이어 갑니다. 조건에 어긋나는 영역을 지워 나가면서 후보를 좁히기 때문에 시간이 지날수록 남은 후보의 질이 올라갑니다. 그리고 지금 찾은 답의 벌점과, 이론상 더 낮출 수 없는 한계선을 함께 계산합니다. 둘의 차이가 줄어들수록 지금 답이 최선에 가깝다는 뜻이고, 차이가 0이면 이보다 나은 근무표는 없다는 것이 증명됩니다. 시간을 끊으면 그때까지 찾은 가장 좋은 답을 내놓습니다.
병동이 커질수록 두 방식의 차이가 벌어지는 이유
인원과 조건이 늘면 두 가지가 동시에 일어납니다.
첫째, 조건을 모두 만족하는 근무표가 희귀해집니다. 간호사 서른 명에 한 달 서른 날이면 만들 수 있는 배치는 천문학적인 수인데, 조건을 하나 붙일 때마다 그중 살아남는 배치의 비율이 줄어듭니다. 순서대로 채우는 방식은 이 희귀한 답을 겨냥해서 가는 것이 아니라 규칙이 이끄는 대로 한 칸씩 나아가는 것이라, 답이 희귀해질수록 그 길에서 벗어날 확률이 올라갑니다.
둘째, 앞의 선택이 뒤를 막는 사건이 잦아집니다. 규칙이 적을 때는 앞에서 무엇을 골라도 뒤에 여유가 남습니다. 조건이 쌓이면 3월 7일의 선택 하나가 3월 20일에 가서 아무도 넣을 수 없는 칸을 만들어 냅니다. 룰베이스에서는 이때 되돌리기나 보정을 돌려야 하는데, 되돌아갈 지점을 찾는 일 자체가 조건이 늘수록 어려워집니다. 어느 칸이 원인이었는지 알려 주는 장치가 없기 때문입니다.
AI 방식에서는 이 두 가지가 같은 방식으로 처리됩니다. 조건이 늘어난다는 것은 잘라 낼 수 있는 영역이 늘어난다는 뜻이기도 해서, 조건이 많을수록 오히려 후보가 빠르게 좁혀지는 경우도 있습니다. 앞의 선택이 뒤를 막는 상황은 애초에 한 칸씩 확정해 나가지 않으므로 생기지 않습니다.
정리하면, 규모가 커질 때 룰베이스는 사람이 설계하고 유지해야 할 양이 늘어나고 AI 방식은 계산기가 처리할 양이 늘어납니다. 늘어나는 쪽이 사람인지 계산인지가 두 방식의 차이입니다.
AI 방식이 남긴 과제와 점검 화면
AI 방식에는 대가가 있습니다. 근무표 전체를 놓고 찾아낸 결과라 특정 칸 하나만 떼어 내면 그 칸의 근거를 규칙 하나로 짚기 어렵습니다. 룰베이스라면 "나이트 다음 날이라서요" 한마디로 끝나는 질문에 답할 수가 없습니다.
그래서 확인하는 방법을 따로 만들었습니다.
근무표를 다 만들고 나면 점검 화면이 열리고, 어떤 조건이 어디에서 지켜지지 않았는지 한자리에 모아 보여 줍니다. 규칙을 하나씩 따라가며 확인하는 대신 걸린 자리만 보고 고치시면 됩니다. 마음에 드는 부분은 그대로 고정해 두고 나머지만 다시 만들 수도 있습니다.
설명을 규칙에서 가져오는 대신 결과에서 가져오는 방식인데, 규칙으로 설명하는 것을 완전히 대신하지는 못합니다. 지금도 손보고 있는 부분입니다.
조건이 많은 병동일수록 AI 방식의 차이가 드러납니다
조건이 서너 개인 병동이라면 두 방식의 결과가 크게 다르지 않습니다. 룰베이스로도 충분히 좋은 근무표가 나옵니다.
조건이 열 개, 스무 개로 늘고 인원이 수십 명이 되면 이야기가 달라집니다. 룰베이스에서는 규칙 사이의 순위와 맞바꾸기 허용 목록이 함께 불어나 사람이 감당할 범위를 넘어가고, 그 부담은 병동이 새 조건을 요청할 때마다 걸리는 시간으로 돌아옵니다. AI 방식에서는 조건이 늘어도 목록에 한 줄이 더해지고, 균등함이나 공정함처럼 근무표 전체를 봐야 판단되는 요구까지 같은 자리에서 함께 저울질됩니다.
듀티메이커가 AI 방식을 쓰는 이유입니다.