Masalah Penjadwalan Sederhana
Masalah Penjadwalan Sederhana¶
Contoh masalah penjadwalan sederhana
Jadwal Perawat¶
Misalkan ada suatu Rumah Sakit kecil yang memiliki kondisi sebagai berikut
- Suatu Rumah Sakit memiliki 3 orang Perawat (Annisa, Balqis, Cantika).
- RS buka selama 24 jam, setiap jam harus ada seorang perawat yang berjaga.
- Pembagian jaga dibagi menjadi 3 shift yaitu Pagi, Siang, Malam.
- RS buka hanya 3 hari, yaitu Senin, Selasa, Rabu.
Karena beberapa kondisi pembagian jaga sebagai berikut
- Annisa jaga sebanyak 3 kali dalam sepekan
- Balqis jaga 2 kali dalam sepekan
- Cantika jaga 4 kali dalam sepekan
Kendala matematis dari masalah jadwal di atas adalah sebagai berikut :
- Untuk setiap shift, hanya ada 1 perawat yang berjaga
- Setiap Perawat tidak diperbolehkan jaga 2 kali secara berurutan
Untuk setiap perawat, berjaga sesuai penugasan
- Annisa jaga sebanyak 3 kali dalam sepekan
- Balqis jaga sebanyak 2 kali dalam sepekan
- Cantika jaga sebanyak 4 kali dalam sepekan
Tambahan kendala lain
- Balqis hanya boleh jaga pada shift pagi.
- Annisa hanya boleh berjaga 1 kali dalam sehari
Model Matematika Penjadwalan Perawat¶
Definisikan variabel keputusan:¶
$x_{p,h,s}$ yang menyatakan Perawat ke-$p$ berjaga pada Hari ke-$h$ Shift ke-$s$
$p=\{1,2,3\}$ Perawat ke-1 : Annisa, ke-2 : Balqis, ke-3 : Cantika
$h=\{1,2,3\}$ Hari ke-1 : Senin, ke-2 : Selasa, ke-3 : Rabu
$s=\{1,2,3\}$ Shift ke-1 : Pagi, ke-2 : Siang, ke-3 : Malam
$x_{p,h,s}=\begin{cases}1, \text{ apabila Perawat ke-}p\text{ berjaga pada hari ke-}h\text{ shift ke-}s \\0, \text{ apabila Perawat ke-}p\text{ TIDAK berjaga pada hari ke-}h\text{ shift ke-}s\end{cases}$
$np$ : banyaknya Perawat
$nh$ : banyaknya Hari
$ns$ : banyaknya Sesi
$P$ : Himpunan Perawat
$H$ : Himpunan Hari
$S$ : Himpunan Shift
Fungsi Objektif¶
Minimumkan : $x_{1,1,1}+x_{1,1,2}+x_{1,1,3}+x_{1,2,1}+x_{1,2,2}+x_{1,2,3}+x_{1,3,1}+x_{1,3,2}+x_{1,3,3}+x_{2,1,1}+x_{2,1,2}+x_{2,1,3}+x_{2,2,1}+x_{2,2,2}+x_{2,2,3}+x_{2,3,1}+x_{2,3,2}+x_{2,3,3}+x_{3,1,1}+x_{3,1,2}+x_{3,1,3}+x_{3,2,1}+x_{3,2,2}+x_{3,2,3}+x_{3,3,1}+x_{3,3,2}+x_{3,3,3}$
Atau disingkat menjadi :
Minimumkan :
$\displaystyle f(\mathbb{x})=\sum_{p=1}^{np} \sum_{h=1}^{hc} \sum_{s=1}^{ns} x_{p,h,s}$
Kendala 0¶
- Banyaknya shift jaga yang harus diisi adalah 3 hari kali 3 shift = 9 shift. Semua perawat bisa mengisi di shift manapun.
$x_{1,1,1}+x_{1,1,2}+x_{1,1,3}+x_{1,2,1}+x_{1,2,2}+x_{1,2,3}+x_{1,3,1}+x_{1,3,2}+x_{1,3,3}+x_{2,1,1}+x_{2,1,2}+x_{2,1,3}+x_{2,2,1}+x_{2,2,2}+x_{2,2,3}+x_{2,3,1}+x_{2,3,2}+x_{2,3,3}+x_{3,1,1}+x_{3,1,2}+x_{3,1,3}+x_{3,2,1}+x_{3,2,2}+x_{3,2,3}+x_{3,3,1}+x_{3,3,2}+x_{3,3,3}=9$
Atau disingkat menjadi : $\displaystyle \sum_{p=1}^{np} \sum_{h=1}^{hc} \sum_{s=1}^{ns} x_{p,h,s}=9$
Kendala 1¶
Untuk setiap shift, hanya ada 1 perawat yang berjaga
- Senin-Pagi hanya 1 orang yang berjaga : $x_{1,1,1}+x_{2,1,1}+x_{3,1,1}=1$
- Senin-Siang hanya 1 orang yang berjaga : $x_{1,1,2}+x_{2,1,2}+x_{3,1,2}=1$
- Senin-Malam hanya 1 orang yang berjaga : $x_{1,1,3}+x_{2,1,3}+x_{3,1,3}=1$
- Selasa-Pagi hanya 1 orang yang berjaga : $x_{1,2,1}+x_{2,2,1}+x_{3,2,1}=1$
- Selasa-Siang hanya 1 orang yang berjaga : $x_{1,2,2}+x_{2,2,2}+x_{3,2,2}=1$
- Selasa-Malam hanya 1 orang yang berjaga : $x_{1,2,3}+x_{2,2,3}+x_{3,2,3}=1$
- Rabu-Pagi hanya 1 orang yang berjaga : $x_{1,3,1}+x_{2,3,1}+x_{3,3,1}=1$
- Rabu-Siang hanya 1 orang yang berjaga : $x_{1,3,2}+x_{2,3,2}+x_{3,3,2}=1$
- Rabu-Malam hanya 1 orang yang berjaga : $x_{1,3,3}+x_{2,3,3}+x_{3,3,3}=1$
Bisa kita tuliskan menjadi : $$\displaystyle \forall h\in H, \forall s\in S : \sum_{p=1}^{np} x_{p,h,s}=1$$
Kendala 2¶
- Setiap perawat tidak diperbolehkan jaga 2 kali secara berurutan
- Annisa tidak boleh jaga berurutan Senin Pagi dan Senin Siang : $x_{1,1,1}+x_{1,1,2}\leq 1$
- Annisa tidak boleh jaga berurutan Senin Siang dan Senin Malam : $x_{1,1,2}+x_{1,1,3}\leq 1$
- Annisa tidak boleh jaga berurutan Senin Malam dan Selasa Pagi : $x_{1,1,3}+x_{1,2,1}\leq 1$
- Annisa tidak boleh jaga berurutan Selasa Pagi dan Selasa Siang : $x_{1,2,1}+x_{1,2,2}\leq 1$
- Annisa tidak boleh jaga berurutan Selasa Siang dan Selasa Malam : $x_{1,2,2}+x_{1,2,3}\leq 1$
- Annisa tidak boleh jaga berurutan Selasa Malam dan Rabu Pagi : $x_{1,2,3}+x_{1,3,1}\leq 1$
- Annisa tidak boleh jaga berurutan Rabu Pagi dan Rabu Siang : $x_{1,3,1}+x_{1,3,2}\leq 1$
- Annisa tidak boleh jaga berurutan Rabu Siang dan Rabu Malam : $x_{1,3,2}+x_{1,3,3}\leq 1$
- Balqis tidak boleh jaga berurutan Senin Pagi dan Senin Siang : $x_{2,1,1}+x_{2,1,2}\leq 1$
- Balqis tidak boleh jaga berurutan Senin Siang dan Senin Malam : $x_{2,1,2}+x_{2,1,3}\leq 1$
- Balqis tidak boleh jaga berurutan Senin Malam dan Selasa Pagi : $x_{2,1,3}+x_{2,2,1}\leq 1$
- Balqis tidak boleh jaga berurutan Selasa Pagi dan Selasa Siang : $x_{2,2,1}+x_{2,2,2}\leq 1$
- Balqis tidak boleh jaga berurutan Selasa Siang dan Selasa Malam : $x_{2,2,2}+x_{2,2,3}\leq 1$
- Balqis tidak boleh jaga berurutan Selasa Malam dan Rabu Pagi : $x_{2,2,3}+x_{2,3,1}\leq 1$
- Balqis tidak boleh jaga berurutan Rabu Pagi dan Rabu Siang : $x_{2,3,1}+x_{2,3,2}\leq 1$
- Balqis tidak boleh jaga berurutan Rabu Siang dan Rabu Malam : $x_{2,3,2}+x_{2,3,3}\leq 1$
- Cantika tidak boleh jaga berurutan Senin Pagi dan Senin Siang : $x_{3,1,1}+x_{3,1,2}\leq 1$
- Cantika tidak boleh jaga berurutan Senin Siang dan Senin Malam : $x_{3,1,2}+x_{3,1,3}\leq 1$
- Cantika tidak boleh jaga berurutan Senin Malam dan Selasa Pagi : $x_{3,1,3}+x_{3,2,1}\leq 1$
- Cantika tidak boleh jaga berurutan Selasa Pagi dan Selasa Siang : $x_{3,2,1}+x_{3,2,2}\leq 1$
- Cantika tidak boleh jaga berurutan Selasa Siang dan Selasa Malam : $x_{3,2,2}+x_{3,2,3}\leq 1$
- Cantika tidak boleh jaga berurutan Selasa Malam dan Rabu Pagi : $x_{3,2,3}+x_{3,3,1}\leq 1$
- Cantika tidak boleh jaga berurutan Rabu Pagi dan Rabu Siang : $x_{3,3,1}+x_{3,3,2}\leq 1$
- Cantika tidak boleh jaga berurutan Rabu Siang dan Rabu Malam : $x_{3,3,2}+x_{3,3,3}\leq 1$
Bisa dituliskan menjadi - $\displaystyle \forall p\in P, \forall h\in H, s\in\{1,2\}\ :\ \ x_{p,h,s}+x_{p,h,s+1} \leq 1$ | Pagi-Siang. Siang-Malam
- $\displaystyle \forall p\in P, h\in\{1,2\}, s=3\ :\ \ x_{p,h,s}+x_{p,h+1,s-2} \leq 1$ | Malam-Pagi
Kendala 3,4,5¶
Untuk setiap perawat, berjaga sesuai penugasan.
- Annisa ditugaskan jaga sebanyak 3 kali dalam sepekan. Annisa adalah perawat ke-1 ($p=1$, $T_1=3$)
- $x_{1,1,1}+x_{1,1,2}+x_{1,1,3}+x_{1,2,1}+x_{1,2,2}+x_{1,2,3}+x_{1,3,1}+x_{1,3,2}+x_{1,3,3}=3$
- Bisa ditulis menjadi : $\displaystyle \sum_{h=1}^{nh} \sum_{s=1}^{ns} x_{1,h,s}=3$
- Balqis ditugaskan jaga sebanyak 2 kali dalam sepekan. Balqis adalah perawat ke-2 ($p=2$, $T_2=2$)
- $x_{2,1,1}+x_{2,1,2}+x_{2,1,3}+x_{2,2,1}+x_{2,2,2}+x_{2,2,3}+x_{2,3,1}+x_{2,3,2}+x_{2,3,3}=2$
- Bisa ditulis menjadi : $\displaystyle \sum_{h=1}^{nh} \sum_{s=1}^{ns} x_{2,h,s}=2$
- Cantika ditugaskan jaga sebanyak 4 kali dalam sepekan. Cantika adalah perawat ke-1 ($p=3$, $T_2=4$)
- $x_{3,1,1}+x_{3,1,2}+x_{3,1,3}+x_{3,2,1}+x_{3,2,2}+x_{3,2,3}+x_{3,3,1}+x_{3,3,2}+x_{3,3,3}=4$
- Bisa ditulis menjadi : $\displaystyle \sum_{h=1}^{nh} \sum_{s=1}^{ns} x_{3,h,s}=4$
Bisa dituliskan menjadi : $$\forall p\in P : \displaystyle \sum_{h=1}^{nh} \sum_{s=1}^{ns} x_{p,h,s}=T_p$$
Kendala 6 dan 7¶
Kendala tambahan lain
- Balqis hanya boleh jaga pada shift pagi.
- Senin-Pagi + Selasa-Pagi + Rabu-Pagi : $x_{2,1,1}+x_{2,2,1}+x_{2,3,1}=2$
- Bisa ditulis menjadi : $\displaystyle \sum_{h=1}^{nh} x_{2,h,1}=2$
- Annisa hanya boleh berjaga 1 kali dalam sehari
- Senin : $x_{1,1,1}+x_{1,1,2}+x_{1,1,3}=1$
- Selasa : $x_{1,2,1}+x_{1,2,2}+x_{1,2,3}=1$
- Rabu : $x_{1,3,1}+x_{1,3,2}+x_{1,3,3}=3$
- Bisa ditulis menjadi $\displaystyle \forall h, \sum_{s=1}^{ns} x_{1,h,s}=1$
Program Python¶
Masalah optimisasi di atas akan dituliskan kedalam program python.
Perlu diketahui bahwa index pada python bermula dari 0.
Sehingga dalam python perawat ke-0 adalah Anisa, ke-1 Balqis, ke-2 Cantika
Sehingga dalam python hari ke-0 adalah Senin, ke-1 Selasa, ke-2 Rabu
Sehingga dalam python shift ke-0 adalah Pagi, ke-1 Siang, ke-2 Malam
!pip install mip #Apabila library mip sudah terinstall, berikan comment (tanda #) sebelum !pip
import mip
import pandas as pd
Perawat=["Annisa","Balqis","Cantika"] #Daftar Perawat
Hari=["Senin","Selasa","Rabu"] #Daftar Hari
Shift=["Pagi","Siang","Malam"] #Daftar Shift
Tugas=[3,2,4] #Penugasan masing-masing perawat
np=len(Perawat);nh=len(Hari);ns=len(Shift)
m = mip.Model("Contoh Jadwal Perawat")
cost = [[[1 for p in range(np)] for h in range(nh)] for s in range(ns)]
x = [[[m.add_var(var_type=mip.BINARY) for p in range(np)] for h in range(nh)] for s in range(ns)]
m.objective = mip.minimize(mip.xsum(cost[p][h][s]*x[p][h][s] for p in range(np) for h in range(nh) for s in range(ns)))
#model.objective = minimize(xsum(c[i][j]*x[i][j] for i in V for j in V))
#kendala 0 : Banyaknya shift jaga yang harus diisi adalah 3 hari kali 3 shift = 9 shift
m += mip.xsum(x[p][h][s] for p in range(np) for h in range(nh) for s in range(ns)) == nh*ns
#kendala 1 : Untuk setiap shift, hanya ada 1 perawat yang berjaga
for h in range (nh):
for s in range (ns):
m += mip.xsum(x[p][h][s] for p in range(np)) == 1
#kendala 2 : Setiap Perawat tidak diperbolehkan jaga 2 kali secara berurutan
for p in range (np):
for h in range (nh):
for s in range (ns-1):
m += x[p][h][s]+x[p][h][s+1] <= 1
for h in range (nh-1):
m += x[p][h][ns-1]+x[p][h+1][0] <= 1
#kendala 3,4,5 : Annisa, Balqis dan Cantika jaga sesuai penugasan
for p in range(np):
m += mip.xsum(x[p][h][s] for h in range(nh) for s in range(ns)) == Tugas[p]
#kendala 6 : Balqis (p=2) hanya boleh jaga pada shift pagi.
p=2
m += mip.xsum( x[p-1][h][0] for h in range(nh) ) == 2
#kendala 7 : Annisa (p=1) hanya boleh berjaga 1 kali dalam sehari
p=1
for h in range(nh):
m += mip.xsum(x[p-1][h][s] for s in range(ns)) <= 1
m.optimize()
print("Jadwal Terpilih :")
jadwal1=[[1 for h in range(nh)] for s in range(ns)] #membuat list untuk menyimpan jadwal
for p in range (np):
for h in range (nh):
for s in range (ns):
if(x[p][h][s].x>0.5): print("x[",p+1,",",h+1,",",s+1,"]=",Perawat[p],"-",Hari[h],"-",Shift[s]);jadwal1[s][h]=Perawat[p]
#Mengeluarkan Jadwal dalam bentuk tabel
print("\nKeluaran jadwal dalam bentuk tabel :")
tabel1 = pd.DataFrame(jadwal1, columns=Hari, index=Shift)
print(tabel1)
Variabel keputusan dan kendala dasar dapat ditambahkan sesuai dengan banyaknya Perawat, Hari dan Shift.
Tambahan Kendala khusus (1)¶
Andaikan terdapat kendala khusus sebagai berikut
Cantika diusahakan tidak jaga pada Senin Pagi ($x_{3,1,1}$)
Cantika diusahakan jaga pada Selasa Pagi ($x_{3,2,1}$)
Kita bisa memberikan konstanta pengali pada variabel keputusa yang berperan sebagai "biaya".
Pada dasarnya konstanta "biaya" bernilai 1. Bisanya konstanta ini dinamakan cost, dengan variabel $c$.
Bila diinginkan suatu variabel keputusan diusahakan terpilih, maka berikan "biaya" yang "lebih murah", bernilai $c < 1$. Contohnya $c=0.5$
Bila diinginkan suatu variabel keputusan diusahakan TIDAK terpilih, maka berikan "biaya" yang "lebih mahal", bernilai $c> 1$. Contohnya $c=2$
Fungsi objektif yang dimiliki adalah meminimumkan, sehingga konstanta yang bernilai lebih kecil akan lebih dipilih.
Fungsi Objektif (modifikasi)¶
Minimumkan : $c_{1,1,1}x_{1,1,1}+c_{1,1,2}x_{1,1,2}+c_{1,1,3}x_{1,1,3}+c_{1,2,1}x_{1,2,1}+c_{1,2,2}+\cdots+c_{3,3,2}x_{3,3,2}+c_{3,3,3}x_{3,3,3}$
Atau disingkat menjadi :
Minimumkan :
$$\displaystyle f(\mathbb{x})=\sum_{p=1}^{np} \sum_{h=1}^{nh} \sum_{s=1}^{ns} c_{p,h,s}\times x_{p,h,s}$$
dengan
- "Biaya" standar : $\forall p\in P, \forall h \in H, \forall s\in S, c_{p,h,s}=1$
- "Biaya" agar variabel keputusan $x_{3,1,1}$ sulit terpilih : $c_{3,1,1}=2$
- "Biaya" agar variabel keputusan $x_{3,2,1}$ mudah terpilih : $c_{3,2,1}=0.5$
#Modifikasi Tambahan Kendala Khusus (1)
np=len(Perawat);nh=len(Hari);ns=len(Shift)
m = mip.Model("Contoh Jadwal Perawat")
cost = [[[1 for p in range(np)] for h in range(nh)] for s in range(ns)]
#Modifikasi Tambahan Kendala Khusus (1) :
cost[2][0][0]=2 #Cantika diusahakan tidak jaga pada Senin Pagi y_{18}=x_{3,1,1}
cost[2][1][0]=0.5 # Cantika diusahakan jaga pada Selasa Pagi y_{21}=x_{3,2,1}
x = [[[m.add_var(var_type=mip.BINARY) for p in range(np)] for h in range(nh)] for s in range(ns)]
m.objective = mip.minimize(mip.xsum(cost[p][h][s]*x[p][h][s] for p in range(np) for h in range(nh) for s in range(ns)))
#model.objective = minimize(xsum(c[i][j]*x[i][j] for i in V for j in V))
#kendala 0 : Banyaknya shift jaga yang harus diisi adalah 3 hari kali 3 shift = 9 shift
m += mip.xsum(x[p][h][s] for p in range(np) for h in range(nh) for s in range(ns)) == nh*ns
#kendala 1 : Untuk setiap shift, hanya ada 1 perawat yang berjaga
for h in range (nh):
for s in range (ns):
m += mip.xsum(x[p][h][s] for p in range(np)) == 1
#kendala 2 : Setiap Perawat tidak diperbolehkan jaga 2 kali secara berurutan
for p in range (np):
for h in range (nh):
for s in range (ns-1):
m += x[p][h][s]+x[p][h][s+1] <= 1
for h in range (nh-1):
m += x[p][h][ns-1]+x[p][h+1][0] <= 1
#kendala 3,4,5 : Annisa, Balqis dan Cantika jaga sesuai penugasan
tugas=[3,2,4]
for p in range(np):
m += mip.xsum(x[p][h][s] for h in range(nh) for s in range(ns)) == tugas[p]
#kendala 6 : Balqis (p=2) hanya boleh jaga pada shift pagi.
p=2
m += mip.xsum( x[p-1][h][0] for h in range(nh) ) == 2
#kendala 7 : Annisa (p=1) hanya boleh berjaga 1 kali dalam sehari
p=1
for h in range(nh):
m += mip.xsum(x[p-1][h][s] for s in range(ns)) <= 1
m.optimize()
print("Jadwal Terpilih :")
jadwal2=[[1 for h in range(nh)] for s in range(ns)] #membuat list untuk menyimpan jadwal
for p in range (np):
for h in range (nh):
for s in range (ns):
if(x[p][h][s].x>0.5): print("x[",p+1,",",h+1,",",s+1,"]=",Perawat[p],"-",Hari[h],"-",Shift[s]);jadwal2[s][h]=Perawat[p]
#Mengeluarkan Jadwal dalam bentuk tabel
print("\nKeluaran jadwal dalam bentuk tabel :")
tabel2 = pd.DataFrame(jadwal2, columns=Hari, index=Shift)
print(tabel2)
print("Bandingkan :")
print("\nJadwal Pertama :")
print(tabel1)
print("\nJadwal Kedua dengan tambahan kendala khusus (1) :")
print(tabel2)
Latihan : Tambahan Kendala Khusus (2)¶
Apabila diinginkan skenario sebagai berikut :
Annisa jaga Senin Siang ($x_{1,1,2}$) jika dan hanya jika Balqis jaga Selasa Siang ($x_{2,2,2}$)
Bagaimana kita perlu memodifikasi fungsi objektif/kendalanya?
Modifikasi programnya dan cek hasilnya!
Apabila ada masukkan silahkan sampaikan
Terima kasih
Comments
Post a Comment