1 Pendahuluan

Simulasi Monte Carlo adalah metode komputasi yang memanfaatkan angka random untuk memodelkan sistem yang bersifat probabilistik. Pada studi kasus ini, kita akan memprediksi permintaan harian es teh di sebuah warung pinggir jalan berdasarkan data historis 100 hari.

1.1 Studi Kasus

Sebuah warung es teh di pinggir jalan melakukan pengamatan dan mencatat frekuensi permintaan harian es teh selama 100 hari terakhir. Data pengamatannya adalah sebagai berikut:

Permintaan (gelas) Frekuensi Observasi
50 10
60 20
70 40
80 20
90 10

Pertanyaan:

  1. Prediksikan permintaan es teh selama 5 hari ke depan.
  2. Prediksikan permintaan es teh selama 20 hari ke depan.

2 Langkah Penyelesaian

2.1 Input Data Observasi

data_observasi <- data.frame(
  permintaan = c(50, 60, 70, 80, 90),
  frekuensi  = c(10, 20, 40, 20, 10)
)

data_observasi

2.2 Membangun Tabel Distribusi Probabilitas

Untuk simulasi Monte Carlo, kita perlu menghitung:

  1. Probabilitas masing-masing nilai permintaan: \(P(X) = \frac{f_i}{\sum f_i}\)
  2. Probabilitas kumulatif: \(F(X) = \sum_{i \leq x} P(X_i)\)
  3. Interval angka random (00–99) berdasarkan probabilitas kumulatif.
buat_tabel_distribusi <- function(data) {
  total_freq <- sum(data$frekuensi)
  
  data$probabilitas   <- data$frekuensi / total_freq
  data$prob_kumulatif <- cumsum(data$probabilitas)
  
  # Interval angka random (00 - 99)
  batas_atas  <- round(data$prob_kumulatif * 100) - 1
  batas_bawah <- c(0, head(batas_atas, -1) + 1)
  
  data$batas_bawah <- batas_bawah
  data$batas_atas  <- batas_atas
  data$interval_RN <- paste0(
    sprintf("%02d", batas_bawah), " - ", sprintf("%02d", batas_atas)
  )
  
  return(data)
}

tabel <- buat_tabel_distribusi(data_observasi)

2.2.1 Hasil Tabel Distribusi

knitr::kable(
  tabel[, c("permintaan", "frekuensi", "probabilitas",
            "prob_kumulatif", "interval_RN")],
  col.names = c("Permintaan (gelas)", "Frekuensi", "Probabilitas",
                "Prob. Kumulatif", "Interval Angka Random"),
  caption   = "Tabel Distribusi Probabilitas Permintaan Es Teh",
  align     = "ccccc"
)
Tabel Distribusi Probabilitas Permintaan Es Teh
Permintaan (gelas) Frekuensi Probabilitas Prob. Kumulatif Interval Angka Random
50 10 0.1 0.1 00 - 09
60 20 0.2 0.3 10 - 29
70 40 0.4 0.7 30 - 69
80 20 0.2 0.9 70 - 89
90 10 0.1 1.0 90 - 99

Interpretasi: Jika kita membangkitkan angka random antara 30–69, maka prediksi permintaannya adalah 70 gelas (karena interval inilah yang merepresentasikan probabilitas 0.40 untuk permintaan 70 gelas).

2.3 Fungsi Simulasi Monte Carlo

simulasi_monte_carlo <- function(tabel, n_hari, seed = 123) {
  set.seed(seed)
  random_numbers <- sample(0:99, size = n_hari, replace = TRUE)
  
  prediksi <- sapply(random_numbers, function(rn) {
    idx <- which(rn >= tabel$batas_bawah & rn <= tabel$batas_atas)
    tabel$permintaan[idx]
  })
  
  data.frame(
    Hari                = seq_len(n_hari),
    Random_Number       = sprintf("%02d", random_numbers),
    Prediksi_Permintaan = prediksi
  )
}

3 Jawaban (a) — Prediksi 5 Hari ke Depan

hasil_5 <- simulasi_monte_carlo(tabel, n_hari = 5, seed = 123)

knitr::kable(
  hasil_5,
  col.names = c("Hari ke-", "Angka Random", "Prediksi Permintaan (gelas)"),
  caption   = "Hasil Simulasi Permintaan 5 Hari ke Depan",
  align     = "ccc"
)
Hasil Simulasi Permintaan 5 Hari ke Depan
Hari ke- Angka Random Prediksi Permintaan (gelas)
1 30 70
2 78 80
3 50 70
4 13 60
5 66 70

Ringkasan:

cat("Total permintaan 5 hari :", sum(hasil_5$Prediksi_Permintaan), "gelas\n")
## Total permintaan 5 hari : 350 gelas
cat("Rata-rata per hari      :", round(mean(hasil_5$Prediksi_Permintaan), 2), "gelas\n")
## Rata-rata per hari      : 70 gelas
cat("Permintaan minimum      :", min(hasil_5$Prediksi_Permintaan), "gelas\n")
## Permintaan minimum      : 60 gelas
cat("Permintaan maksimum     :", max(hasil_5$Prediksi_Permintaan), "gelas\n")
## Permintaan maksimum     : 80 gelas

4 Jawaban (b) — Prediksi 20 Hari ke Depan

hasil_20 <- simulasi_monte_carlo(tabel, n_hari = 20, seed = 456)

knitr::kable(
  hasil_20,
  col.names = c("Hari ke-", "Angka Random", "Prediksi Permintaan (gelas)"),
  caption   = "Hasil Simulasi Permintaan 20 Hari ke Depan",
  align     = "ccc"
)
Hasil Simulasi Permintaan 20 Hari ke Depan
Hari ke- Angka Random Prediksi Permintaan (gelas)
1 34 70
2 37 70
3 84 80
4 26 60
5 24 60
6 77 80
7 30 70
8 72 80
9 78 80
10 89 80
11 82 80
12 42 70
13 86 80
14 07 50
15 13 60
16 12 60
17 68 70
18 51 70
19 29 60
20 46 70

Ringkasan:

cat("Total permintaan 20 hari :", sum(hasil_20$Prediksi_Permintaan), "gelas\n")
## Total permintaan 20 hari : 1400 gelas
cat("Rata-rata per hari       :", round(mean(hasil_20$Prediksi_Permintaan), 2), "gelas\n")
## Rata-rata per hari       : 70 gelas
cat("Permintaan minimum       :", min(hasil_20$Prediksi_Permintaan), "gelas\n")
## Permintaan minimum       : 50 gelas
cat("Permintaan maksimum      :", max(hasil_20$Prediksi_Permintaan), "gelas\n")
## Permintaan maksimum      : 80 gelas

5 Visualisasi Hasil Simulasi

par(mfrow = c(1, 2), mar = c(4, 4, 3, 1))

# Plot 1: Prediksi 5 hari
barplot(hasil_5$Prediksi_Permintaan,
        names.arg = hasil_5$Hari,
        main      = "Prediksi 5 Hari ke Depan",
        xlab      = "Hari ke-",
        ylab      = "Permintaan (gelas)",
        col       = "steelblue",
        border    = "white",
        ylim      = c(0, 100))
abline(h = mean(hasil_5$Prediksi_Permintaan), lty = 2, col = "red", lwd = 2)
legend("topright", legend = "Rata-rata", lty = 2, col = "red", bty = "n", cex = 0.8)

# Plot 2: Prediksi 20 hari
barplot(hasil_20$Prediksi_Permintaan,
        names.arg = hasil_20$Hari,
        main      = "Prediksi 20 Hari ke Depan",
        xlab      = "Hari ke-",
        ylab      = "Permintaan (gelas)",
        col       = "tomato",
        border    = "white",
        ylim      = c(0, 100),
        cex.names = 0.7)
abline(h = mean(hasil_20$Prediksi_Permintaan), lty = 2, col = "blue", lwd = 2)
legend("topright", legend = "Rata-rata", lty = 2, col = "blue", bty = "n", cex = 0.8)

par(mfrow = c(1, 1))

5.1 Distribusi Frekuensi Hasil Simulasi 20 Hari

freq_simulasi <- table(hasil_20$Prediksi_Permintaan)

barplot(freq_simulasi,
        main   = "Distribusi Frekuensi Permintaan (Simulasi 20 Hari)",
        xlab   = "Permintaan (gelas)",
        ylab   = "Frekuensi",
        col    = "darkgreen",
        border = "white")


6 Ringkasan & Kesimpulan

ringkasan <- data.frame(
  Periode          = c("5 hari", "20 hari"),
  Total_Gelas      = c(sum(hasil_5$Prediksi_Permintaan),
                       sum(hasil_20$Prediksi_Permintaan)),
  Rata_rata_Harian = c(round(mean(hasil_5$Prediksi_Permintaan), 2),
                       round(mean(hasil_20$Prediksi_Permintaan), 2)),
  Minimum          = c(min(hasil_5$Prediksi_Permintaan),
                       min(hasil_20$Prediksi_Permintaan)),
  Maksimum         = c(max(hasil_5$Prediksi_Permintaan),
                       max(hasil_20$Prediksi_Permintaan))
)

knitr::kable(
  ringkasan,
  col.names = c("Periode", "Total (gelas)", "Rata-rata/hari",
                "Min", "Max"),
  caption   = "Ringkasan Hasil Simulasi Monte Carlo",
  align     = "ccccc"
)
Ringkasan Hasil Simulasi Monte Carlo
Periode Total (gelas) Rata-rata/hari Min Max
5 hari 350 70 60 80
20 hari 1400 70 50 80

6.1 Validasi terhadap Nilai Ekspektasi Teoretis

Nilai ekspektasi (rata-rata teoretis) dari distribusi permintaan adalah:

\[ E(X) = \sum_{i=1}^{n} x_i \cdot P(x_i) \]

E_X <- sum(tabel$permintaan * tabel$probabilitas)
cat("Nilai Ekspektasi E(X) =", E_X, "gelas/hari\n")
## Nilai Ekspektasi E(X) = 70 gelas/hari

\[ E(X) = 50(0.10) + 60(0.20) + 70(0.40) + 80(0.20) + 90(0.10) = 70 \text{ gelas/hari} \]

Kesimpulan:

  • Hasil simulasi menunjukkan bahwa rata-rata permintaan harian mendekati nilai ekspektasi teoretis sebesar 70 gelas/hari.
  • Semakin banyak hari yang disimulasikan, rata-rata hasilnya akan semakin konvergen ke nilai ekspektasi (sesuai Hukum Bilangan Besar).
  • Simulasi 20 hari memberikan hasil yang lebih stabil dan representatif dibandingkan simulasi 5 hari.
  • Pemilik warung dapat menggunakan informasi ini untuk perencanaan stok bahan baku dan perkiraan pendapatan harian.

7 Informasi Sesi

sessionInfo()
## R version 4.5.2 (2025-10-31 ucrt)
## Platform: x86_64-w64-mingw32/x64
## Running under: Windows 10 x64 (build 19045)
## 
## Matrix products: default
##   LAPACK version 3.12.1
## 
## locale:
## [1] LC_COLLATE=English_Indonesia.utf8  LC_CTYPE=English_Indonesia.utf8   
## [3] LC_MONETARY=English_Indonesia.utf8 LC_NUMERIC=C                      
## [5] LC_TIME=English_Indonesia.utf8    
## 
## time zone: Asia/Jakarta
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## loaded via a namespace (and not attached):
##  [1] digest_0.6.38     R6_2.6.1          fastmap_1.2.0     xfun_0.54        
##  [5] cachem_1.1.0      knitr_1.51        htmltools_0.5.8.1 rmarkdown_2.30   
##  [9] lifecycle_1.0.5   cli_3.6.5         vctrs_0.7.3       sass_0.4.10      
## [13] jquerylib_0.1.4   compiler_4.5.2    rstudioapi_0.18.0 tools_4.5.2      
## [17] evaluate_1.0.5    bslib_0.9.0       yaml_2.3.10       otel_0.2.0       
## [21] jsonlite_2.0.0    rlang_1.2.0