Membuat Algoritma untuk Simulasi Automatic Replenishment
Beberapa bulan silam, saya sempat menuliskan tentang bagaimana konsep automatic replenishment di suatu gudang distributor barang tertentu. Kali ini saya hendak menuliskan algoritma yang bisa digunakan untuk melakukan simulasi automatic replenishment di suatu depot pengisian galon air isi ulang. Seperti biasa, saya menggunakan R untuk menulis algoritma dan kemudian melakukan simulasi.
Suatu ketika, di salah satu depot pengisian galon air isi ulang, proses bisnis yang terjadi adalah sebagai berikut:
- Depot tersebut menjual air isi ulang untuk galon-galon kosong dari konsumen.
- Pengiriman bahan baku (air murni) dilakukan menggunakan satu truk tangki yang harus terisi dengan penuh dalam sekali pengiriman (misal: kapasitas tanki = 700 liter. Kelak nilai ini akan disebut dengan economic order quantity - EOQ). Lead time pengiriman bervariasi selama 1-2 hari dari hari pemesanan. Pemesanan dan pengiriman bisa dilakukan hari apa saja.
- Pemesanan baru dilakukan jika stok air di tangki depot sudah kurang dari reorder point (ROP) yang ditetapkan perusahaan. Cara perusahaan menghitung reorder point adalah: . Dimana adalah standar deviasi dari demand selama 30 hari ke depan.
- Demand selama 30 hari ke depan disimulasikan menggunakan data historikal pada bulan-bulan sebelumnya.
- Untuk melakukan pengiriman, biaya yang keluar adalah tetap sebesar
Rp500.000
. - Kapasitas tangki penampungan air di depot tersebut sangat besar sehingga kita bisa abaikan faktor ini.
- Kualitas air yang tertampung dalam tangki depot akan menurun
seiringnya waktu. Diperkirakan biaya yang timbul akibat penurunan
kualitas air ini adalah
Rp1.500
per liter air. (Kelak kita akan sebut biaya ini sebagai carrying cost). - Jika ada pelanggan datang untuk membeli air namun persediaan air
habis. Maka akan dihitung sebagai loss sales. Besarannya adalah
sebesar
Rp5.000
per liter air. (Kelak besaran ini akan dihitung sebagai biaya yang dinamakan shortage cost). - Saldo air di tangki depot pada hari
1
adalah sebesar 20 liter air. - Jika demand pada hari tersebut lebih besar dari stok air di depot, maka depot hanya bisa memenuhi demand sebagian saja (tergantung stok air). Sisa demand yang tidak terpenuhi akan menjadi loss sales.
Sekarang kita akan membuat algoritmanya.
Pendefinisian beberapa parameter
leadtime_min = 1
leadtime_max = 2
carrying_cost_per_unit = 1500
ordering_cost = 500000
stock_out_cost = 5000
Generate random number untuk demand
Untuk kasus ini saya gunakan random number berdistribusi normal. Pada real condition kita bisa dengan mudah melakukan generate number berdasarkan data historikal yang ada.
D = runif(30,0,5) * 10
D = round(D,0)
Menghitung safety stock
sigmaL = sd(D)
ss = 2 * sigmaL
Simulasi pada hari 1
Pada hari pertama ini, saya akan coba hitung:
- Berapa banyak order yang bisa dipenuhi (fullfilled).
- Stok di akhir hari (ending stock).
- Apakah ada loss sales? (stock outage).
- Apakah perlu melakukan pemesanan air dari supplier? (place order).
- Jika iya, kapan pesanan tersebut sampai? (order arrive at days …)
# initial condition
days = 1:30
begin_stok = c(20)
order_recv = c(0)
avail_stock = c(0)
demand = D
full_filled = rep(NA,30)
ending_stock = rep(NA,30)
stock_outage = rep(NA,30)
place_order = rep(NA,30)
lead_time = rep(NA,30)
order_arrive_at = rep(NA,30)
i = 1
# ===========================
# perhitungan
# hitung saldo sekarang
avail_stock[i] = begin_stok[i] + order_recv[i]
# perhitungan demand berapa yang bisa dipenuhi
# asumsi bisa dipenuhi sebagian
full_filled[i] = ifelse(avail_stock[i] < demand[i],
avail_stock[i],
demand[i])
# perhitungan ending stok
ending_stock[i] = avail_stock[i] - full_filled[i]
# outage atau tidak
stock_outage[i] = demand[i] - full_filled[i]
# perlu pesan lagi atau tidak?
place_order[i] = ifelse(ending_stock[i] <= ss,
1,
0)
# lead time pengiriman
lead_time[i] = sample(leadtime_min:leadtime_max,1)
# order akan datang kapan
order_arrive_at[i] = ifelse(place_order[i] == 1,
i + lead_time[i],
0)
Simulasi pada hari 2
Pada hari kedua ini, algoritma yang dilakukan sama dengan algoritma pada
hari pertama. Perbedaannya ada pada variabel order
. Jika dijadwalkan
air datang hari ini, maka akan masuk sejumlah air masuk ke dalam depot.
i = 2
# stok hari i adalah stok hari i-1
begin_stok[i] = ending_stock[i-1]
# jika order arrive, maka order sama dengan eoq
if(i == order_arrive_at[i-1]){order_recv[i] = eoq}
if(i != order_arrive_at[i-1]){order_recv[i] = 0}
Simulasi pada hari 3 hingga 30
Modifikasi hanya dilakukan pada variabel order
. Jika pada hari 1
didapatkan kondisi leadtime pengiriman 2
hari (maka air akan datang
pada hari ke 3
), maka pada hari ke 2
kita tidak boleh meminta
pengiriman lagi (harus bersabar hingga esok air datang).
for i in 3 to 30
# stok hari i adalah stok hari i-1
begin_stok[i] = ending_stock[i-1]
# jika order arrive, maka order sama dengan eoq
if(i == order_arrive_at[i-1] | i == order_arrive_at[i-2]){order_recv[i] = eoq}
else{order_recv[i] = 0}
Hasil Simulasi
Jika algoritma simulasi di atas di-run sekali, maka hasilnya adalah sebagai berikut:
days | begin_stok | order_recv | avail_stock | demand | full_filled | ending_stock | stock_outage | place_order | lead_time | order_arrive_at | carrying_cost | ordering_cost | stock_outage_cost | total_cost |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 20 | 0 | 20 | 21 | 20 | 0 | 1 | 1 | 2 | 3 | 0 | 500000 | 5000 | 505000 |
2 | 0 | 0 | 0 | 49 | 0 | 0 | 49 | 1 | 2 | 0 | 0 | 0 | 245000 | 245000 |
3 | 0 | 700 | 700 | 42 | 42 | 658 | 0 | 0 | 1 | 0 | 987000 | 0 | 0 | 987000 |
4 | 658 | 0 | 658 | 34 | 34 | 624 | 0 | 0 | 2 | 0 | 936000 | 0 | 0 | 936000 |
5 | 624 | 0 | 624 | 8 | 8 | 616 | 0 | 0 | 2 | 0 | 924000 | 0 | 0 | 924000 |
6 | 616 | 0 | 616 | 2 | 2 | 614 | 0 | 0 | 1 | 0 | 921000 | 0 | 0 | 921000 |
7 | 614 | 0 | 614 | 15 | 15 | 599 | 0 | 0 | 1 | 0 | 898500 | 0 | 0 | 898500 |
8 | 599 | 0 | 599 | 17 | 17 | 582 | 0 | 0 | 1 | 0 | 873000 | 0 | 0 | 873000 |
9 | 582 | 0 | 582 | 16 | 16 | 566 | 0 | 0 | 2 | 0 | 849000 | 0 | 0 | 849000 |
10 | 566 | 0 | 566 | 11 | 11 | 555 | 0 | 0 | 1 | 0 | 832500 | 0 | 0 | 832500 |
11 | 555 | 0 | 555 | 31 | 31 | 524 | 0 | 0 | 2 | 0 | 786000 | 0 | 0 | 786000 |
12 | 524 | 0 | 524 | 41 | 41 | 483 | 0 | 0 | 2 | 0 | 724500 | 0 | 0 | 724500 |
13 | 483 | 0 | 483 | 41 | 41 | 442 | 0 | 0 | 1 | 0 | 663000 | 0 | 0 | 663000 |
14 | 442 | 0 | 442 | 14 | 14 | 428 | 0 | 0 | 1 | 0 | 642000 | 0 | 0 | 642000 |
15 | 428 | 0 | 428 | 33 | 33 | 395 | 0 | 0 | 2 | 0 | 592500 | 0 | 0 | 592500 |
16 | 395 | 0 | 395 | 24 | 24 | 371 | 0 | 0 | 1 | 0 | 556500 | 0 | 0 | 556500 |
17 | 371 | 0 | 371 | 42 | 42 | 329 | 0 | 0 | 1 | 0 | 493500 | 0 | 0 | 493500 |
18 | 329 | 0 | 329 | 31 | 31 | 298 | 0 | 0 | 2 | 0 | 447000 | 0 | 0 | 447000 |
19 | 298 | 0 | 298 | 12 | 12 | 286 | 0 | 0 | 1 | 0 | 429000 | 0 | 0 | 429000 |
20 | 286 | 0 | 286 | 15 | 15 | 271 | 0 | 0 | 2 | 0 | 406500 | 0 | 0 | 406500 |
21 | 271 | 0 | 271 | 11 | 11 | 260 | 0 | 0 | 1 | 0 | 390000 | 0 | 0 | 390000 |
22 | 260 | 0 | 260 | 16 | 16 | 244 | 0 | 0 | 2 | 0 | 366000 | 0 | 0 | 366000 |
23 | 244 | 0 | 244 | 32 | 32 | 212 | 0 | 0 | 2 | 0 | 318000 | 0 | 0 | 318000 |
24 | 212 | 0 | 212 | 22 | 22 | 190 | 0 | 0 | 1 | 0 | 285000 | 0 | 0 | 285000 |
25 | 190 | 0 | 190 | 30 | 30 | 160 | 0 | 0 | 1 | 0 | 240000 | 0 | 0 | 240000 |
26 | 160 | 0 | 160 | 1 | 1 | 159 | 0 | 0 | 1 | 0 | 238500 | 0 | 0 | 238500 |
27 | 159 | 0 | 159 | 13 | 13 | 146 | 0 | 0 | 1 | 0 | 219000 | 0 | 0 | 219000 |
28 | 146 | 0 | 146 | 28 | 28 | 118 | 0 | 0 | 2 | 0 | 177000 | 0 | 0 | 177000 |
29 | 118 | 0 | 118 | 15 | 15 | 103 | 0 | 0 | 1 | 0 | 154500 | 0 | 0 | 154500 |
30 | 103 | 0 | 103 | 31 | 31 | 72 | 0 | 0 | 1 | 0 | 108000 | 0 | 0 | 108000 |
## Total cost yang dikeluarkan saat EOQ = 700 adalah: Rp16.208 juta
## Reorder Point hasil perhitungan = 25
Jika kita run sekali lagi, maka hasilnya adalah sebagai berikut:
days | begin_stok | order_recv | avail_stock | demand | full_filled | ending_stock | stock_outage | place_order | lead_time | order_arrive_at | carrying_cost | ordering_cost | stock_outage_cost | total_cost |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 20 | 0 | 20 | 15 | 15 | 5 | 0 | 1 | 2 | 3 | 7500 | 500000 | 0 | 507500 |
2 | 5 | 0 | 5 | 47 | 5 | 0 | 42 | 1 | 1 | 0 | 0 | 0 | 210000 | 210000 |
3 | 0 | 700 | 700 | 1 | 1 | 699 | 0 | 0 | 1 | 0 | 1048500 | 0 | 0 | 1048500 |
4 | 699 | 0 | 699 | 50 | 50 | 649 | 0 | 0 | 1 | 0 | 973500 | 0 | 0 | 973500 |
5 | 649 | 0 | 649 | 36 | 36 | 613 | 0 | 0 | 2 | 0 | 919500 | 0 | 0 | 919500 |
6 | 613 | 0 | 613 | 25 | 25 | 588 | 0 | 0 | 1 | 0 | 882000 | 0 | 0 | 882000 |
7 | 588 | 0 | 588 | 41 | 41 | 547 | 0 | 0 | 1 | 0 | 820500 | 0 | 0 | 820500 |
8 | 547 | 0 | 547 | 14 | 14 | 533 | 0 | 0 | 1 | 0 | 799500 | 0 | 0 | 799500 |
9 | 533 | 0 | 533 | 47 | 47 | 486 | 0 | 0 | 2 | 0 | 729000 | 0 | 0 | 729000 |
10 | 486 | 0 | 486 | 12 | 12 | 474 | 0 | 0 | 1 | 0 | 711000 | 0 | 0 | 711000 |
11 | 474 | 0 | 474 | 23 | 23 | 451 | 0 | 0 | 1 | 0 | 676500 | 0 | 0 | 676500 |
12 | 451 | 0 | 451 | 14 | 14 | 437 | 0 | 0 | 1 | 0 | 655500 | 0 | 0 | 655500 |
13 | 437 | 0 | 437 | 31 | 31 | 406 | 0 | 0 | 1 | 0 | 609000 | 0 | 0 | 609000 |
14 | 406 | 0 | 406 | 7 | 7 | 399 | 0 | 0 | 2 | 0 | 598500 | 0 | 0 | 598500 |
15 | 399 | 0 | 399 | 4 | 4 | 395 | 0 | 0 | 2 | 0 | 592500 | 0 | 0 | 592500 |
16 | 395 | 0 | 395 | 14 | 14 | 381 | 0 | 0 | 1 | 0 | 571500 | 0 | 0 | 571500 |
17 | 381 | 0 | 381 | 17 | 17 | 364 | 0 | 0 | 1 | 0 | 546000 | 0 | 0 | 546000 |
18 | 364 | 0 | 364 | 42 | 42 | 322 | 0 | 0 | 1 | 0 | 483000 | 0 | 0 | 483000 |
19 | 322 | 0 | 322 | 38 | 38 | 284 | 0 | 0 | 1 | 0 | 426000 | 0 | 0 | 426000 |
20 | 284 | 0 | 284 | 33 | 33 | 251 | 0 | 0 | 2 | 0 | 376500 | 0 | 0 | 376500 |
21 | 251 | 0 | 251 | 7 | 7 | 244 | 0 | 0 | 2 | 0 | 366000 | 0 | 0 | 366000 |
22 | 244 | 0 | 244 | 26 | 26 | 218 | 0 | 0 | 1 | 0 | 327000 | 0 | 0 | 327000 |
23 | 218 | 0 | 218 | 32 | 32 | 186 | 0 | 0 | 1 | 0 | 279000 | 0 | 0 | 279000 |
24 | 186 | 0 | 186 | 49 | 49 | 137 | 0 | 0 | 1 | 0 | 205500 | 0 | 0 | 205500 |
25 | 137 | 0 | 137 | 31 | 31 | 106 | 0 | 0 | 1 | 0 | 159000 | 0 | 0 | 159000 |
26 | 106 | 0 | 106 | 33 | 33 | 73 | 0 | 0 | 1 | 0 | 109500 | 0 | 0 | 109500 |
27 | 73 | 0 | 73 | 19 | 19 | 54 | 0 | 0 | 1 | 0 | 81000 | 0 | 0 | 81000 |
28 | 54 | 0 | 54 | 39 | 39 | 15 | 0 | 1 | 1 | 29 | 22500 | 500000 | 0 | 522500 |
29 | 15 | 700 | 715 | 36 | 36 | 679 | 0 | 0 | 1 | 0 | 1018500 | 0 | 0 | 1018500 |
30 | 679 | 0 | 679 | 34 | 34 | 645 | 0 | 0 | 1 | 0 | 967500 | 0 | 0 | 967500 |
## Total cost yang dikeluarkan saat EOQ = 700 adalah: Rp17.172 juta
## Reorder Point hasil perhitungan = 29
Jika kita run sekali lagi, maka hasilnya adalah sebagai berikut:
days | begin_stok | order_recv | avail_stock | demand | full_filled | ending_stock | stock_outage | place_order | lead_time | order_arrive_at | carrying_cost | ordering_cost | stock_outage_cost | total_cost |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 20 | 0 | 20 | 44 | 20 | 0 | 24 | 1 | 1 | 2 | 0 | 500000 | 120000 | 620000 |
2 | 0 | 700 | 700 | 1 | 1 | 699 | 0 | 0 | 2 | 0 | 1048500 | 0 | 0 | 1048500 |
3 | 699 | 0 | 699 | 17 | 17 | 682 | 0 | 0 | 1 | 0 | 1023000 | 0 | 0 | 1023000 |
4 | 682 | 0 | 682 | 30 | 30 | 652 | 0 | 0 | 1 | 0 | 978000 | 0 | 0 | 978000 |
5 | 652 | 0 | 652 | 43 | 43 | 609 | 0 | 0 | 2 | 0 | 913500 | 0 | 0 | 913500 |
6 | 609 | 0 | 609 | 39 | 39 | 570 | 0 | 0 | 2 | 0 | 855000 | 0 | 0 | 855000 |
7 | 570 | 0 | 570 | 40 | 40 | 530 | 0 | 0 | 1 | 0 | 795000 | 0 | 0 | 795000 |
8 | 530 | 0 | 530 | 6 | 6 | 524 | 0 | 0 | 2 | 0 | 786000 | 0 | 0 | 786000 |
9 | 524 | 0 | 524 | 25 | 25 | 499 | 0 | 0 | 2 | 0 | 748500 | 0 | 0 | 748500 |
10 | 499 | 0 | 499 | 49 | 49 | 450 | 0 | 0 | 2 | 0 | 675000 | 0 | 0 | 675000 |
11 | 450 | 0 | 450 | 40 | 40 | 410 | 0 | 0 | 2 | 0 | 615000 | 0 | 0 | 615000 |
12 | 410 | 0 | 410 | 11 | 11 | 399 | 0 | 0 | 1 | 0 | 598500 | 0 | 0 | 598500 |
13 | 399 | 0 | 399 | 17 | 17 | 382 | 0 | 0 | 2 | 0 | 573000 | 0 | 0 | 573000 |
14 | 382 | 0 | 382 | 48 | 48 | 334 | 0 | 0 | 1 | 0 | 501000 | 0 | 0 | 501000 |
15 | 334 | 0 | 334 | 24 | 24 | 310 | 0 | 0 | 2 | 0 | 465000 | 0 | 0 | 465000 |
16 | 310 | 0 | 310 | 20 | 20 | 290 | 0 | 0 | 1 | 0 | 435000 | 0 | 0 | 435000 |
17 | 290 | 0 | 290 | 36 | 36 | 254 | 0 | 0 | 1 | 0 | 381000 | 0 | 0 | 381000 |
18 | 254 | 0 | 254 | 11 | 11 | 243 | 0 | 0 | 2 | 0 | 364500 | 0 | 0 | 364500 |
19 | 243 | 0 | 243 | 40 | 40 | 203 | 0 | 0 | 2 | 0 | 304500 | 0 | 0 | 304500 |
20 | 203 | 0 | 203 | 27 | 27 | 176 | 0 | 0 | 2 | 0 | 264000 | 0 | 0 | 264000 |
21 | 176 | 0 | 176 | 47 | 47 | 129 | 0 | 0 | 2 | 0 | 193500 | 0 | 0 | 193500 |
22 | 129 | 0 | 129 | 15 | 15 | 114 | 0 | 0 | 1 | 0 | 171000 | 0 | 0 | 171000 |
23 | 114 | 0 | 114 | 34 | 34 | 80 | 0 | 0 | 2 | 0 | 120000 | 0 | 0 | 120000 |
24 | 80 | 0 | 80 | 27 | 27 | 53 | 0 | 0 | 1 | 0 | 79500 | 0 | 0 | 79500 |
25 | 53 | 0 | 53 | 34 | 34 | 19 | 0 | 1 | 1 | 26 | 28500 | 500000 | 0 | 528500 |
26 | 19 | 700 | 719 | 22 | 22 | 697 | 0 | 0 | 2 | 0 | 1045500 | 0 | 0 | 1045500 |
27 | 697 | 0 | 697 | 39 | 39 | 658 | 0 | 0 | 1 | 0 | 987000 | 0 | 0 | 987000 |
28 | 658 | 0 | 658 | 27 | 27 | 631 | 0 | 0 | 1 | 0 | 946500 | 0 | 0 | 946500 |
29 | 631 | 0 | 631 | 49 | 49 | 582 | 0 | 0 | 1 | 0 | 873000 | 0 | 0 | 873000 |
30 | 582 | 0 | 582 | 4 | 4 | 578 | 0 | 0 | 2 | 0 | 867000 | 0 | 0 | 867000 |
## Total cost yang dikeluarkan saat EOQ = 700 adalah: Rp18.756 juta
## Reorder Point hasil perhitungan = 28
Jika kita run berulang-ulang sebanyak-banyaknya (inilah salah satu kelebihan melakukan simulasi menggunakan coding seperti R atau Python), maka akan kita dapatkan expected total cost berada di kisaran Rp16 - Rp17 juta.
Perbandingan dengan Hitungan Teoritis
Dari berbagai jurnal terkait automatic replenishment, saya mendapatkan suatu istilah economic order quantity (EOQ), yakni suatu nilai pemesanan bahan baku yang bisa meminimalkan semua biaya yang timbul (ordering cost dan carrying cost). Secara teoritis, cara menghitung EOQ yang optimal adalah sebagai berikut:
Di mana:
- D : demand pada 30 hari.
- : ordering cost.
- : carrying cost.
Hal yang dimaksud dengan optimal di sini adalah EOQ yang bisa meminimalkan ordering cost dan carrying cost. Selain itu ROP juga ada formula tersendiri. Biasanya ROP dihitung dengan cara:
Di mana:
- : average demand during lead time.
- : safety stock; dihitung dengan mengasumsikan service level terpenuhi.
Service level adalah persentase di mana demand diharapkan terpenuhi. Formula untuk menghitung adalah:
Di mana:
- : cycle service level misalkan dipakai
95%
. - : standar deviasi demand pada lead time.
Jika saya melakukan simulasi kembali dengan nilai EOQ dan ROP sesuai dengan teoritis, maka kita dapatkan:
days | begin_stok | order_recv | avail_stock | demand | full_filled | ending_stock | stock_outage | place_order | lead_time | order_arrive_at | carrying_cost | ordering_cost | stock_outage_cost | total_cost |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 20 | 0 | 20 | 46 | 20 | 0 | 26 | 1 | 2 | 3 | 0 | 500000 | 130000 | 630000 |
2 | 0 | 0 | 0 | 36 | 0 | 0 | 36 | 1 | 2 | 0 | 0 | 0 | 180000 | 180000 |
3 | 0 | 644 | 644 | 1 | 1 | 643 | 0 | 0 | 1 | 0 | 964500 | 0 | 0 | 964500 |
4 | 643 | 0 | 643 | 36 | 36 | 607 | 0 | 0 | 1 | 0 | 910500 | 0 | 0 | 910500 |
5 | 607 | 0 | 607 | 41 | 41 | 566 | 0 | 0 | 1 | 0 | 849000 | 0 | 0 | 849000 |
6 | 566 | 0 | 566 | 7 | 7 | 559 | 0 | 0 | 1 | 0 | 838500 | 0 | 0 | 838500 |
7 | 559 | 0 | 559 | 34 | 34 | 525 | 0 | 0 | 2 | 0 | 787500 | 0 | 0 | 787500 |
8 | 525 | 0 | 525 | 10 | 10 | 515 | 0 | 0 | 1 | 0 | 772500 | 0 | 0 | 772500 |
9 | 515 | 0 | 515 | 12 | 12 | 503 | 0 | 0 | 2 | 0 | 754500 | 0 | 0 | 754500 |
10 | 503 | 0 | 503 | 44 | 44 | 459 | 0 | 0 | 1 | 0 | 688500 | 0 | 0 | 688500 |
11 | 459 | 0 | 459 | 43 | 43 | 416 | 0 | 0 | 2 | 0 | 624000 | 0 | 0 | 624000 |
12 | 416 | 0 | 416 | 22 | 22 | 394 | 0 | 0 | 1 | 0 | 591000 | 0 | 0 | 591000 |
13 | 394 | 0 | 394 | 3 | 3 | 391 | 0 | 0 | 2 | 0 | 586500 | 0 | 0 | 586500 |
14 | 391 | 0 | 391 | 1 | 1 | 390 | 0 | 0 | 2 | 0 | 585000 | 0 | 0 | 585000 |
15 | 390 | 0 | 390 | 44 | 44 | 346 | 0 | 0 | 1 | 0 | 519000 | 0 | 0 | 519000 |
16 | 346 | 0 | 346 | 1 | 1 | 345 | 0 | 0 | 2 | 0 | 517500 | 0 | 0 | 517500 |
17 | 345 | 0 | 345 | 37 | 37 | 308 | 0 | 0 | 1 | 0 | 462000 | 0 | 0 | 462000 |
18 | 308 | 0 | 308 | 6 | 6 | 302 | 0 | 0 | 2 | 0 | 453000 | 0 | 0 | 453000 |
19 | 302 | 0 | 302 | 13 | 13 | 289 | 0 | 0 | 1 | 0 | 433500 | 0 | 0 | 433500 |
20 | 289 | 0 | 289 | 5 | 5 | 284 | 0 | 0 | 2 | 0 | 426000 | 0 | 0 | 426000 |
21 | 284 | 0 | 284 | 7 | 7 | 277 | 0 | 0 | 1 | 0 | 415500 | 0 | 0 | 415500 |
22 | 277 | 0 | 277 | 33 | 33 | 244 | 0 | 0 | 2 | 0 | 366000 | 0 | 0 | 366000 |
23 | 244 | 0 | 244 | 27 | 27 | 217 | 0 | 0 | 2 | 0 | 325500 | 0 | 0 | 325500 |
24 | 217 | 0 | 217 | 16 | 16 | 201 | 0 | 0 | 2 | 0 | 301500 | 0 | 0 | 301500 |
25 | 201 | 0 | 201 | 18 | 18 | 183 | 0 | 0 | 1 | 0 | 274500 | 0 | 0 | 274500 |
26 | 183 | 0 | 183 | 20 | 20 | 163 | 0 | 0 | 1 | 0 | 244500 | 0 | 0 | 244500 |
27 | 163 | 0 | 163 | 5 | 5 | 158 | 0 | 0 | 1 | 0 | 237000 | 0 | 0 | 237000 |
28 | 158 | 0 | 158 | 20 | 20 | 138 | 0 | 0 | 2 | 0 | 207000 | 0 | 0 | 207000 |
29 | 138 | 0 | 138 | 5 | 5 | 133 | 0 | 0 | 1 | 0 | 199500 | 0 | 0 | 199500 |
30 | 133 | 0 | 133 | 29 | 29 | 104 | 0 | 0 | 1 | 0 | 156000 | 0 | 0 | 156000 |
## Total cost yang dikeluarkan saat EOQ = 644 adalah: Rp15.3 juta
## Reorder Point hasil perhitungan = 46
Dari sekali simulasi, kita dapatkan nilai EOQ yang lebih rendah tapi nilai ROP yang lebih tinggi. Jika simulasi ini dilakukan berulang-ulang kali sebanyak-banyaknya, kita dapatkan expected EOQ berada di kisaran 620 - 670 liter air dengan expected total cost berada di kisaran Rp15 - Rp16 juta.
Total cost yang dihasilkan relatif lebih rendah dibandingkan kondisi saat ini dimana EOQ diwajibkan sebesar 700 liter
Hasil Optimal dari Simulasi
Salah satu pertanyaan yang muncul di benak saya adalah, apakah EOQ yang dihasilkan di atas sudah optimal? Salah satu concern saya adalah jika EOQ yang digunakan bernilai besar, salah satu konsekuensinya adalah carrying cost-nya juga meledak.
Lantas, saya mencoba melakukan simulasi dengan mencoba nilai EOQ = 200 dan nilai ROP masih sama sesuai dengan formulasi perhitungan sebelumnya. Begini hasil simulasinya:
days | begin_stok | order_recv | avail_stock | demand | full_filled | ending_stock | stock_outage | place_order | lead_time | order_arrive_at | carrying_cost | ordering_cost | stock_outage_cost | total_cost |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1 | 20 | 0 | 20 | 49 | 20 | 0 | 29 | 1 | 1 | 2 | 0 | 500000 | 145000 | 645000 |
2 | 0 | 200 | 200 | 35 | 35 | 165 | 0 | 0 | 1 | 0 | 247500 | 0 | 0 | 247500 |
3 | 165 | 0 | 165 | 43 | 43 | 122 | 0 | 0 | 2 | 0 | 183000 | 0 | 0 | 183000 |
4 | 122 | 0 | 122 | 30 | 30 | 92 | 0 | 0 | 2 | 0 | 138000 | 0 | 0 | 138000 |
5 | 92 | 0 | 92 | 45 | 45 | 47 | 0 | 1 | 1 | 6 | 70500 | 500000 | 0 | 570500 |
6 | 47 | 200 | 247 | 43 | 43 | 204 | 0 | 0 | 2 | 0 | 306000 | 0 | 0 | 306000 |
7 | 204 | 0 | 204 | 23 | 23 | 181 | 0 | 0 | 2 | 0 | 271500 | 0 | 0 | 271500 |
8 | 181 | 0 | 181 | 14 | 14 | 167 | 0 | 0 | 1 | 0 | 250500 | 0 | 0 | 250500 |
9 | 167 | 0 | 167 | 30 | 30 | 137 | 0 | 0 | 2 | 0 | 205500 | 0 | 0 | 205500 |
10 | 137 | 0 | 137 | 40 | 40 | 97 | 0 | 0 | 2 | 0 | 145500 | 0 | 0 | 145500 |
11 | 97 | 0 | 97 | 39 | 39 | 58 | 0 | 0 | 1 | 0 | 87000 | 0 | 0 | 87000 |
12 | 58 | 0 | 58 | 47 | 47 | 11 | 0 | 1 | 2 | 14 | 16500 | 500000 | 0 | 516500 |
13 | 11 | 0 | 11 | 31 | 11 | 0 | 20 | 1 | 2 | 0 | 0 | 0 | 100000 | 100000 |
14 | 0 | 200 | 200 | 41 | 41 | 159 | 0 | 0 | 1 | 0 | 238500 | 0 | 0 | 238500 |
15 | 159 | 0 | 159 | 30 | 30 | 129 | 0 | 0 | 2 | 0 | 193500 | 0 | 0 | 193500 |
16 | 129 | 0 | 129 | 46 | 46 | 83 | 0 | 0 | 1 | 0 | 124500 | 0 | 0 | 124500 |
17 | 83 | 0 | 83 | 6 | 6 | 77 | 0 | 0 | 1 | 0 | 115500 | 0 | 0 | 115500 |
18 | 77 | 0 | 77 | 8 | 8 | 69 | 0 | 0 | 1 | 0 | 103500 | 0 | 0 | 103500 |
19 | 69 | 0 | 69 | 41 | 41 | 28 | 0 | 1 | 1 | 20 | 42000 | 500000 | 0 | 542000 |
20 | 28 | 200 | 228 | 37 | 37 | 191 | 0 | 0 | 1 | 0 | 286500 | 0 | 0 | 286500 |
21 | 191 | 0 | 191 | 38 | 38 | 153 | 0 | 0 | 1 | 0 | 229500 | 0 | 0 | 229500 |
22 | 153 | 0 | 153 | 2 | 2 | 151 | 0 | 0 | 2 | 0 | 226500 | 0 | 0 | 226500 |
23 | 151 | 0 | 151 | 26 | 26 | 125 | 0 | 0 | 1 | 0 | 187500 | 0 | 0 | 187500 |
24 | 125 | 0 | 125 | 11 | 11 | 114 | 0 | 0 | 1 | 0 | 171000 | 0 | 0 | 171000 |
25 | 114 | 0 | 114 | 46 | 46 | 68 | 0 | 0 | 1 | 0 | 102000 | 0 | 0 | 102000 |
26 | 68 | 0 | 68 | 4 | 4 | 64 | 0 | 0 | 2 | 0 | 96000 | 0 | 0 | 96000 |
27 | 64 | 0 | 64 | 34 | 34 | 30 | 0 | 1 | 1 | 28 | 45000 | 500000 | 0 | 545000 |
28 | 30 | 200 | 230 | 3 | 3 | 227 | 0 | 0 | 2 | 0 | 340500 | 0 | 0 | 340500 |
29 | 227 | 0 | 227 | 36 | 36 | 191 | 0 | 0 | 1 | 0 | 286500 | 0 | 0 | 286500 |
30 | 191 | 0 | 191 | 16 | 16 | 175 | 0 | 0 | 2 | 0 | 262500 | 0 | 0 | 262500 |
## Total cost yang dikeluarkan saat EOQ = 200 adalah: Rp7.718 juta
## Reorder Point hasil perhitungan = 54
Secara mengejutkan total cost yang dihasilkan jauh lebih menurun! Lalu kita bisa lihat, walaupun stock outage cost meningkat tapi nilainya tetap terjaga akibat ROP yang tinggi.
Jika saya melakukan simulasi ini berulang kali, saya dapatkan expected total cost sebesar Rp6 - Rp7 juta.
Kesimpulan
Nilai EOQ = 200 belum tentu merupakan solusi yang paling optimal karena saya hanya melakukan coba-coba saja. Jika mau menemukan solusi yang optimal berdasarkan algoritma simulasi ini, saya bisa memanfaatkan algoritma spiral.
Penentuan ROP bisa jadi menjadi titik kritis karena akan menentukan kapan bahan baku air harus dipesan sehingga bisa meminimalisir loss sales.
Saya menduga dengan mengecilkan EOQ dan membuat ROP tinggi (sesuai dengan formula yang ada) bisa meminimalisir total cost yang timbul.
if you find this article helpful, support this blog by clicking the
ads