Optimization Story: Penjadwalan Perawat di Rumah Sakit
Beberapa waktu yang lalu, saya sempat menuliskan bagaimana linear programming bisa digunakan untuk menyelesaikan permasalahan penjadwalan tenaga kesehatan dengan optimal. Namun jika rekan-rekan membaca tulisan saya tersebut, final result yang ada adalah hanyalah konfigurasi banyaknya tenaga kesehatan yang bekerja di hari-hari tersebut.
Belum ada detail jadwal siapa masuk ke hari apa di shift ke berapa.
Kali ini saya akan mencoba menyelesaikan permasalahan penjadwalan yang relatif lebih rumit dibandingkan dengan permasalahan yang kemarin.
Nurse Schedulling
Latar Belakang
Di suatu rumah sakit, ada satu lantai berisi kamar rawat inap kelas VIP dengan total ada 30 orang perawat yang ditugaskan di sana. Para perawat bekerja dengan sistem shift dengan peraturan sebagai berikut:
- Terdapat
3
shift kerja yaitu:- day shift (8.00 - 16.00),
- evening shift (16.00 - 24.00), dan
- night shift (24.00 - 8.00)
- Pada setiap shift dibutuhkan minimal 5 orang perawat.
Selain itu, terdapat beberapa aturan kerja yang harus dipenuhi, yakni:
- Setiap perawat dalam satu hari hanya boleh ditugaskan ke dalam satu shift.
- Jika seorang perawat ditugaskan pada shift malam, maka dia tidak dapat ditugaskan di shift pagi di hari berikutnya.
- Jika seorang perawat ditugaskan dalam
4
hari berturut-turut, maka hari ke-5
harus diberi libur. - Jika seorang perawat ditugaskan pada suatu shift di weekend, maka dia tidak dapat ditugaskan di weekend berikutnya.
- Workload (banyaknya penugasan) setiap perawat harus sama.
Masalah
Bagaimana menentukan jadwal yang optimal?
Model Matematika
Membangun Model Matematika
Time Frame
Untuk memudahkan membuat model matematika nurse schedulling, saya akan mendefinisikan terlebih dahulu time frame yang hendak digunakan. Apakah akan dibuat jadwal selama seminggu, sebulan, atau periode tertentu.
Untuk itu, saya akan melihat aturan kerja ke-4, yakni:
Jika seorang perawat ditugaskan pada suatu shift di weekend, maka dia tidak dapat ditugaskan di weekend berikutnya.
Dari kasus di atas, setidaknya time frame penjadwalan tersingkat
yang bisa buat adalah dalam waktu 2
minggu.
Parameter
Dari penjelasan-penjelasan di atas, saya akan mendefinisikan beberapa hal, yakni:
- adalah himpunan hari dalam time frame
2
minggu. Saya tuliskan1
sebagai Senin. Weekend terjadi pada . - adalah himpunan shift kerja harian perawat.
- adalah himpunan banyaknya perawat yang dibutuhkan.
Decision Variable
Saya definisikan:
Constraints
Sekarang kita akan menuliskan constraints dalam bahasa matematika.
Aturan Dasar
Pada setiap shift dibutuhkan minimal 5 orang perawat.
Constraint I
Setiap perawat dalam satu hari hanya boleh ditugaskan ke dalam satu shift.
Ekspresi matematika di atas memastikan bahwa seorang perawat hanya bisa ditugaskan dalam satu shift per hari atau tidak ditugaskan sama sekali.
Constraint II
Jika seorang perawat ditugaskan pada shift malam, maka dia tidak dapat ditugaskan di shift pagi.
Ekspresi matematika di atas memastikan bahwa seorang perawat yang bertugas night shift pada hari tidak boleh bertugas pada shift pagi esok harinya () atau perawat tersebut tidak ditugaskan sama sekali.
Constraint III
Jika seorang perawat ditugaskan dalam 4
hari berturut-turut, maka hari
ke-5
harus diberi libur.
Jadi seorang perawat bisa saja bertugas di berbagai shift selama 4
hari berturut-turut tapi tidak diperbolehkan untuk bertugas di hari
ke-5
.
Constraint IV
Jika seorang perawat ditugaskan pada suatu shift di weekend, maka dia tidak dapat ditugaskan di weekend berikutnya.
Saya telah menuliskan weekend terjadi saat .
Bagi saya, constraint IV merupakan constraint yang tersulit untuk dituliskan model matematikanya. Oleh karena itu, saya akan gunakan induksi sebagai berikut:
Tanggal 6
Jika seorang perawat bertugas di hari 6
(shift apapun), dia tidak
boleh bertugas di hari 13
dan 14
. Tapi jika dia tidak bertugas di
hari 6
, maka dia diperbolehkan bertugas di hari 13
dan atau
14
. Akibatnya:
- Jika maka
- Jika maka karena perawat tersebut bisa
bertugas di tanggal
13
dan atau14
.
Maka model matematika pada constraint tanggal 6
adalah sebagai
berikut:
Tanggal 7
Dengan prinsip yang sama dengan tanggal 6
, saya bisa dapatkan model
matematika pada constraint tanggal 7
adalah sebagai berikut:
Constraint V
Workload (banyaknya penugasan) setiap perawat harus sama.
Pertama-tama, mari kita hitung. Berapa banyak shift yang ideal per perawat.
Yakni:
Jadi diharapkan setiap perawat mendapatkan banyak shift yang sama,
yakni sebanyak 7
shifts.
Maka model matematika dari constraint ini adalah:
Objective Function
Tujuan utama dari masalah schedulling ini adalah meminimalisir banyaknya perawat yang ditugaskan per hari per shift sehingga tetap memenuhi constraints yang ada.
Solver R
Penulisan Model Matematika di R
Berikut adalah penulisan model matematika di R:
# memanggil libraries
library(dplyr)
library(ompr)
library(ompr.roi)
library(ROI.plugin.glpk)
# membuat model
model =
MIPModel() %>%
# add variables
# non negative integers
add_variable(x[n,h,s],
n = 1:n_per,
h = 1:14,
s = 1:3,
type = "binary",
lb = 0) %>%
# set obj function
set_objective(sum_expr(x[n,h,s],
n = 1:n_per,
h = 1:14,
s = 1:3),
"min") %>%
# Syarat Minimal per Shift
add_constraint(sum_expr(x[n,h,s],
n = 1:n_per) >= min_per,
h = 1:14,
s = 1:3) %>%
# add constraints
# constraint I
add_constraint(x[n,h,1] + x[n,h,2] + x[n,h,3] <= 1,
n = 1:n_per,
h = 1:14) %>%
# constraint II
add_constraint(x[n,h,3] + x[n,h+1,1] <= 1,
n = 1:n_per,
h = 1:13) %>%
# constraint III
add_constraint(x[n,h,1] + x[n,h+1,1] + x[n,h+2,1] + x[n,h+3,1] + x[n,h+4,1] +
x[n,h,2] + x[n,h+1,2] + x[n,h+2,2] + x[n,h+3,2] + x[n,h+4,2] +
x[n,h,3] + x[n,h+1,3] + x[n,h+2,3] + x[n,h+3,3] + x[n,h+4,3] <= 4,
n = 1:n_per,
h = 1:9) %>%
# constraint IV tanggal 6
add_constraint(2*(x[n,6,1] + x[n,6,2] + x[n,6,3]) +
sum_expr(x[n,13,s],
s = 1:3) +
sum_expr(x[n,14,s],
s = 1:3) <= 2,
n = 1:n_per) %>%
# constraint IV tanggal 7
add_constraint(2*(x[n,7,1] + x[n,7,2] + x[n,7,3]) +
sum_expr(x[n,13,s],
s = 1:3) +
sum_expr(x[n,14,s],
s = 1:3) <= 2,
n = 1:n_per) %>%
# contraint V
add_constraint(sum_expr(x[n,h,s],
h = 1:14,
s = 1:3) == ideal,
n = 1:n_per)
model
## Mixed integer linear optimization problem
## Variables:
## Continuous: 0
## Integer: 0
## Binary: 1260
## Model sense: minimize
## Constraints: 1212
Solving
Kemudian saya solve dengan R:
result = solve_model(model, with_ROI(solver = "glpk", verbose = TRUE))
## <SOLVER MSG> ----
## GLPK Simplex Optimizer, v4.65
## 1212 rows, 1260 columns, 9150 non-zeros
## 0: obj = 0.000000000e+00 inf = 4.200e+02 (72)
## 416: obj = 2.100000000e+02 inf = 0.000e+00 (0) 1
## OPTIMAL LP SOLUTION FOUND
## GLPK Integer Optimizer, v4.65
## 1212 rows, 1260 columns, 9150 non-zeros
## 1260 integer variables, all of which are binary
## Integer optimization begins...
## Long-step dual simplex will be used
## + 416: mip = not found yet >= -inf (1; 0)
## + 630: >>>>> 2.100000000e+02 >= 2.100000000e+02 0.0% (37; 0)
## + 630: mip = 2.100000000e+02 >= tree is empty 0.0% (0; 73)
## INTEGER OPTIMAL SOLUTION FOUND
## <!SOLVER MSG> ----
Solusi Optimal
Jadwal Optimal
Berikut adalah jadwal optimal dalam kasus ini:
## Jadwal Perawat: Angka Pada Tanggal Menunjukkan id Perawat
tanggal | Pagi | Siang | Malam |
---|---|---|---|
1 | 1,2,3,4,5 | 7,8,9,10,29 | 16,17,18,19,20 |
2 | 2,3,4,5,30 | 11,12,13,14,15 | 18,19,20,21,22 |
3 | 1,3,4,5,30 | 11,12,13,14,15 | 6,21,22,23,26 |
4 | 2,4,5,27,28 | 11,12,13,14,15 | 6,21,22,23,25 |
5 | 1,3,9,10,27 | 11,12,13,14,15 | 21,22,23,24,25 |
6 | 2,3,4,5,7 | 6,16,17,18,19 | 8,20,27,28,29 |
7 | 2,3,4,5,6 | 8,16,17,18,19 | 7,20,27,28,29 |
8 | 1,2,3,4,5 | 12,13,14,15,26 | 21,22,23,24,25 |
9 | 1,6,7,8,9 | 11,16,17,28,29 | 23,24,25,26,27 |
10 | 2,7,8,10,30 | 16,17,18,19,20 | 24,25,26,28,29 |
11 | 6,7,8,9,10 | 16,17,18,19,20 | 26,27,28,29,30 |
12 | 7,8,9,10,24 | 16,17,18,19,20 | 6,27,28,29,30 |
13 | 9,10,13,15,26 | 21,22,23,24,25 | 1,11,12,14,30 |
14 | 9,10,13,15,26 | 21,22,23,24,25 | 1,11,12,14,30 |
Sedangkan ini adalah rekapan banyaknya shift yang ditugaskan kepada masing-masing perawat:
## Rekapan Berapa Kali Perawat Bertugas
id_perawat | Pagi | Siang | Malam |
---|---|---|---|
1 | 5 | - | 2 |
2 | 7 | - | - |
3 | 7 | - | - |
4 | 7 | - | - |
5 | 7 | - | - |
6 | 3 | 1 | 3 |
7 | 5 | 1 | 1 |
8 | 4 | 2 | 1 |
9 | 6 | 1 | - |
10 | 6 | 1 | - |
11 | - | 5 | 2 |
12 | - | 5 | 2 |
13 | 2 | 5 | - |
14 | - | 5 | 2 |
15 | 2 | 5 | - |
16 | - | 6 | 1 |
17 | - | 6 | 1 |
18 | - | 5 | 2 |
19 | - | 5 | 2 |
20 | - | 3 | 4 |
21 | - | 2 | 5 |
22 | - | 2 | 5 |
23 | - | 2 | 5 |
24 | 1 | 2 | 4 |
25 | - | 2 | 5 |
26 | 2 | 1 | 4 |
27 | 2 | - | 5 |
28 | 1 | 1 | 5 |
29 | - | 2 | 5 |
30 | 3 | - | 4 |
Dari rekapan di atas, semua perawat mendapatkan jatah shift yang sama.
Discussion
Mungkin rekan-rekan berpikir bahwa dari 14
hari yang ada, kenapa
masing-masing perawat mendapatkan workload hanya 7
hari saja?
Saya sudah mencoba menaikkan batas ideal
menjadi 10
shifts per
perawat namun jadwal yang dihasilkan justru terlihat buruk. Beberapa
shift ditemukan terjadi penumpukan perawat sehingga terkesan tidak
efektif untuk dilakukan. Artinya, dari aturan-aturan existing yang ada
secara tidak langsung membatasi workload dari perawat.
if you find this article helpful, support this blog by clicking the
ads.