data_historis <- data.frame(
Permintaan = c(50, 60, 70, 80, 90),
Frekuensi = c(10, 20, 40, 20, 10)
)
data_historis
## Permintaan Frekuensi
## 1 50 10
## 2 60 20
## 3 70 40
## 4 80 20
## 5 90 10
Tahap ini adalah fondasi dari simulasi Monte Carlo. Kita mengambil data masa lalu (frekuensi observasi) untuk menentukan seberapa besar peluang setiap kejadian muncul di masa depan. Dengan menjumlahkan seluruh frekuensi, kita mendapatkan total observasi (dalam kasus ini 100 hari). Probabilitas individu kemudian dihitung dengan membagi frekuensi setiap kelompok (misal: permintaan 50 gelas yang muncul 10 kali) dengan total observasi, sehingga menghasilkan bobot peluang (0.1 atau \(10\)%). Secara logis, tabel ini memberi tahu sistem kita “apa yang mungkin terjadi” dan “seberapa sering hal itu terjadi” berdasarkan fakta lapangan.
data_historis$Probabilitas <- data_historis$Frekuensi / sum(data_historis$Frekuensi)
data_historis$Kumulatif_100 <- cumsum(data_historis$Probabilitas) * 100
data_historis$Probabilitas
## [1] 0.1 0.2 0.4 0.2 0.1
data_historis$Kumulatif_100
## [1] 10 30 70 90 100
Setelah probabilitas diketahui, kita menghitung probabilitas kumulatif dengan menjumlahkan probabilitas secara berurutan. Mengalikan nilai kumulatif ini dengan 100 bertujuan untuk menciptakan “Interval Angka Acak” yang mudah dipahami (1-100). Fungsi dari interval ini adalah sebagai “batas wilayah”. Misalnya, jika permintaan 50 gelas memiliki kumulatif 10, maka ia menguasai wilayah angka acak 1 sampai 10. Jika permintaan 60 gelas memiliki kumulatif 30, maka ia memiliki wilayah dari angka 11 sampai 30. Hal ini secara logis memastikan bahwa saat angka acak ditarik, probabilitas munculnya suatu nilai permintaan akan tetap sesuai dengan proporsi data historisnya. Tanpa pembatasan interval kumulatif ini, angka acak yang kita bangkitkan tidak akan memiliki arti atau rujukan untuk dikonversi menjadi prediksi permintaan.
prediksi_permintaan <- function(n_hari) {
set.seed(123)
# 1. Bangkitkan Angka Acak Bulat 1-100
df_hasil <- data.frame(
Hari = 1:n_hari,
Angka_Acak = sample(1:100, n_hari, replace = TRUE)
)
# 2. Tentukan Prediksi Permintaan berdasarkan Interval
df_hasil$Prediksi <- sapply(df_hasil$Angka_Acak, function(r) {
idx <- which(data_historis$Kumulatif_100 >= r)[1]
return(data_historis$Permintaan[idx])
})
return(df_hasil)
}
## Latihan 1
# A. Prediksi 5 Hari
cat("--- LATIHAN 1: Prediksi 5 Hari ---\n")
## --- LATIHAN 1: Prediksi 5 Hari ---
sim_5 <- prediksi_permintaan(5)
print(sim_5)
## Hari Angka_Acak Prediksi
## 1 1 31 70
## 2 2 79 80
## 3 3 51 70
## 4 4 14 60
## 5 5 67 70
cat("Rata-rata Permintaan (5 hari):", mean(sim_5$Prediksi), "gelas/hari\n\n")
## Rata-rata Permintaan (5 hari): 70 gelas/hari
# B. Prediksi 20 Hari
cat("--- LATIHAN 1: Prediksi 20 Hari ---\n")
## --- LATIHAN 1: Prediksi 20 Hari ---
sim_20 <- prediksi_permintaan(20)
print(sim_20)
## Hari Angka_Acak Prediksi
## 1 1 31 70
## 2 2 79 80
## 3 3 51 70
## 4 4 14 60
## 5 5 67 70
## 6 6 42 70
## 7 7 50 70
## 8 8 43 70
## 9 9 14 60
## 10 10 25 60
## 11 11 90 80
## 12 12 91 90
## 13 13 69 70
## 14 14 91 90
## 15 15 57 70
## 16 16 92 90
## 17 17 9 50
## 18 18 93 90
## 19 19 99 90
## 20 20 72 80
cat("Rata-rata Permintaan (20 hari):", mean(sim_20$Prediksi), "gelas/hari\n\n")
## Rata-rata Permintaan (20 hari): 74 gelas/hari
Inti dari simulasi ini terletak pada penggunaan fungsi sample(1:100). Angka bulat yang terpilih secara acak dianggap mewakili ketidakpastian permintaan harian di masa depan. Melalui logika pencocokan interval (angka acak dibandingkan dengan probabilitas kumulatif), kita dapat mengubah nilai acak yang tidak bermakna menjadi nilai prediksi permintaan yang realistis. Secara logis, permintaan dengan frekuensi tertinggi dalam data historis akan memiliki rentang angka acak yang lebih lebar, sehingga lebih sering muncul sebagai hasil prediksi.
simulasi2 <- function(n_hari) {
set.seed(123)
data_sim <- data.frame(Hari = 1:n_hari)
permintaan_acak <- rexp(n_hari, rate = 1/70)
data_sim$Prediksi <- round(permintaan_acak)
return(data_sim)
}
# Eksekusi Latihan 2 (5, 20, 100, 1000 hari)
cat("--- HASIL LATIHAN 2 ---\n")
## --- HASIL LATIHAN 2 ---
target_hari <- c(5, 20, 100, 1000)
for(n in target_hari) {
hasil2 <- simulasi2(n)
cat(sprintf("Simulasi %4d hari | Rata-rata: %.2f gelas\n", n, mean(hasil2$Prediksi)))
}
## Simulasi 5 hari | Rata-rata: 39.60 gelas
## Simulasi 20 hari | Rata-rata: 56.70 gelas
## Simulasi 100 hari | Rata-rata: 73.18 gelas
## Simulasi 1000 hari | Rata-rata: 72.09 gelas
Pada bagian kedua, simulasi dilakukan menggunakan pendekatan distribusi teoretis (Eksponensial). Eksperimen ini menunjukkan prinsip statistik bahwa simulasi dalam jangka pendek (5-20 hari) cenderung menghasilkan rata-rata yang fluktuatif atau belum stabil. Namun, secara logis, saat jumlah simulasi ditingkatkan menjadi 100 hingga 1000 hari, nilai rata-ratanya akan semakin stabil dan mendekati nilai ekspektasi (rata-rata target). Ini membuktikan bahwa simulasi Monte Carlo sangat efektif untuk memprediksi risiko dan tren jangka panjang dalam kondisi yang penuh ketidakpastian.