Pendahuluan

Dalam analisis probabilitas dan statistika, nilai ekspektasi (expected value) merupakan ukuran penting yang merepresentasikan rata-rata jangka panjang dari suatu variabel acak. Secara teoritis, nilai ekspektasi dapat dihitung langsung menggunakan distribusi probabilitas yang diketahui. Namun, dalam banyak kasus nyata, distribusi tersebut tidak selalu tersedia secara eksplisit, sehingga pendekatan simulasi menjadi alternatif yang sangat berguna.

Salah satu metode yang sering digunakan adalah Simulasi Monte Carlo, yaitu teknik yang memanfaatkan pengambilan sampel acak berulang untuk mendekati nilai parameter tertentu. Melalui simulasi ini, kita dapat membandingkan hasil perhitungan teoritis (manual) dengan pendekatan empiris berbasis data untuk membuktikan Hukum Bilangan Besar (Law of Large Numbers).

1. Persiapan Data dan Probabilitas

Langkah pertama adalah mendefinisikan data historis permintaan beserta frekuensinya, kemudian menghitung probabilitas dan probabilitas kumulatif untuk membuat interval bilangan acak.

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

tabel_permintaan
##   permintaan frekuensi
## 1         50        10
## 2         60        20
## 3         70        40
## 4         80        20
## 5         90        10
# total frekuensi
total_frekuensi <- sum(tabel_permintaan$frekuensi)

# peluang
total_frekuensi <- sum(tabel_permintaan$frekuensi)
tabel_permintaan$probabilitas <- tabel_permintaan$frekuensi / total_frekuensi

tabel_permintaan
##   permintaan frekuensi probabilitas
## 1         50        10          0.1
## 2         60        20          0.2
## 3         70        40          0.4
## 4         80        20          0.2
## 5         90        10          0.1
# Probabilitas kumulatif
tabel_permintaan$probabilitas_kumulatif <- cumsum(tabel_permintaan$probabilitas)

tabel_permintaan
##   permintaan frekuensi probabilitas probabilitas_kumulatif
## 1         50        10          0.1                    0.1
## 2         60        20          0.2                    0.3
## 3         70        40          0.4                    0.7
## 4         80        20          0.2                    0.9
## 5         90        10          0.1                    1.0
# interval dengan +1 untuk lower bound
tabel_permintaan$batas_bawah<- c(1, head(tabel_permintaan$probabilitas_kumulatif, -1) * 100 + 1)
tabel_permintaan$batas_atas <- tabel_permintaan$probabilitas_kumulatif * 100

tabel_permintaan
##   permintaan frekuensi probabilitas probabilitas_kumulatif batas_bawah
## 1         50        10          0.1                    0.1           1
## 2         60        20          0.2                    0.3          11
## 3         70        40          0.4                    0.7          31
## 4         80        20          0.2                    0.9          71
## 5         90        10          0.1                    1.0          91
##   batas_atas
## 1         10
## 2         30
## 3         70
## 4         90
## 5        100

Penjelasan

Tabel di atas menampilkan distribusi frekuensi awal yang telah diubah menjadi probabilitas. Kolom peluang_kumulatif akan digunakan sebagai batas atas interval penarikan bilangan acak pada proses simulasi selanjutnya.

# ekspektasi Berdasarkan distribusi peluang yang sudah dihitung sebelumnya
nilai_ekspektasi <- sum(tabel_permintaan$permintaan * tabel_permintaan$probabilitas)

cat("Ekspektasi permintaan:", nilai_ekspektasi, "\n")
## Ekspektasi permintaan: 70

Penjelasan

Berdasarkan perkalian antara nilai permintaan dan probabilitas masing-masing, didapatkan nilai ekspektasi teoritis (manual) sebesar 70. Nilai ini akan menjadi acuan (parameter absolut) untuk menguji akurasi hasil simulasi kita.

Prediksi (Fungsi Simulasi Monte Carlo)

Berikut adalah fungsi permintaan_simulasi yang akan digunakan untuk membangkitkan bilangan acak dan mencocokkannya dengan tabel distribusi probabilitas kumulatif.

permintaan_simulasi <- function(n, tabel_permintaan) {
  # Bilangan acak dari 1 sampai 100 (diskrit sesuai interval)
  bilangan_acak <- sample(1:100, n, replace = TRUE)
  
  # Fungsi bantu untuk menentukan demand berdasarkan interval
  get_demand <- function(x) {
    index <- which(x >= tabel_permintaan$batas_bawah & x <= tabel_permintaan$batas_atas)
    if (length(index) == 0) {
      return(NA)  # atau fallback ke 70 jika mau pakai nilai tengah
    } else {
      return(tabel_permintaan$permintaan[index])
    }
  }
  
  prediksi_permintaan <- sapply(bilangan_acak, get_demand)
  
  # Hapus NA jika ada
  result <- data.frame(
    bilangan_acak = bilangan_acak,
    prediksi_permintaan = prediksi_permintaan
  )
  result <- na.omit(result)
  
  return(result)
}

a. Simulasi 1.000 hari

set.seed(1000)
# a. 1000 hari
sim_1000 <- permintaan_simulasi(1000, tabel_permintaan)
print(head(sim_1000, 10))
##    bilangan_acak prediksi_permintaan
## 1             68                  70
## 2             43                  70
## 3             86                  80
## 4             51                  70
## 5             88                  80
## 6             29                  60
## 7             99                  90
## 8             61                  70
## 9             18                  60
## 10            22                  60
cat("Rata-rata permintaan:", mean(sim_1000$prediksi_permintaan), "\n")
## Rata-rata permintaan: 70.12097

Penjelasan

Pada skala 1.000 kali iterasi simulasi, nilai rata-rata permintaan empiris yang dihasilkan sudah berada di sekitar angka ekspektasi teoritisnya. Namun, karena ukuran 1.000 sampel acak masih memiliki ruang untuk varians (simpangan/fluktuasi acak), angka rata-rata yang dihasilkan masih memiliki kemungkinan bergeser sedikit di atas angka pastinya (70).

b. Simulasi 5.000 hari

set.seed(5000)
# a. 5000 hari
sim_5000 <- permintaan_simulasi(5000, tabel_permintaan)
print(head(sim_5000, 10))
##    bilangan_acak prediksi_permintaan
## 1             63                  70
## 2             40                  70
## 3              5                  50
## 4             53                  70
## 5             50                  70
## 6             35                  70
## 7             97                  90
## 8            100                  90
## 9             52                  70
## 10            53                  70
cat("Rata-rata permintaan:", mean(sim_5000$prediksi_permintaan), "\n")
## Rata-rata permintaan: 70.08871

Penjelasan

Ketika jumlah hari (iterasi) dinaikkan menjadi 5.000 kali penarikan sampel, kita dapat melihat bahwa tingkat akurasi meningkat. Peningkatan jumlah percobaan ini secara efektif meredam noise atau fluktuasi acak dari sebaran data, membuat nilai rata-rata yang dihasilkan menjadi lebih konvergen (mendekat) ke angka 70 dibandingkan simulasi tahap pertama.

c. Simulasi 20.000 hari

set.seed(20000)
# a. 200000 hari
sim_20000 <- permintaan_simulasi(20000, tabel_permintaan)
print(head(sim_20000, 10))
##    bilangan_acak prediksi_permintaan
## 1             87                  80
## 2             27                  60
## 3             28                  60
## 4             76                  80
## 5             23                  60
## 6             36                  70
## 7             11                  60
## 8             12                  60
## 9             63                  70
## 10            78                  80
cat("Rata-rata permintaan:", mean(sim_20000$prediksi_permintaan), "\n")
## Rata-rata permintaan: 69.89096

Penjelasan

Pada tingkat simulasi yang sangat masif, yaitu 20.000 iterasi, kurva penarikan acak telah menjadi sangat halus dan stabil. Hasil dari eksekusi pada level ini umumnya akan sangat identik dengan nilai teoritis manualnya (tepat atau sangat mendekati 70.00). Ini membuktikan bahwa semakin banyak simulasi dilakukan, proporsi sampel akan sangat menyesuaikan dengan probabilitas aslinya tanpa gangguan keacakan yang signifikan.

Tabel Perbandingan

perbandingan <- data.frame(
  Metode = c("Ekspektasi Teoritis", "Simulasi 1000 hari", "Simulasi 5000 hari", "Simulasi 20000 hari"),
  Permintaan_Rata_Rata = c(
    round(nilai_ekspektasi, 2),
    round(mean(sim_1000$prediksi_permintaan), 2),
    round(mean(sim_5000$prediksi_permintaan), 2),
    round(mean(sim_20000$prediksi_permintaan), 2)
  )
)

# Tampilkan tabel
print(perbandingan)
##                Metode Permintaan_Rata_Rata
## 1 Ekspektasi Teoritis                70.00
## 2  Simulasi 1000 hari                70.12
## 3  Simulasi 5000 hari                70.09
## 4 Simulasi 20000 hari                69.89

Penjelasan

Secara teoritis, akurasi akan meningkat seiring bertambahnya jumlah hari simulasi. Namun, dalam data ini terlihat sedikit variasi di mana simulasi 5.000 hari memiliki deviasi terkecil sebesar 0.09, sementara simulasi 20.000 hari tetap menunjukkan kedekatan yang stabil terhadap ekspektasi teoritis.

Kesimpulan

Berdasarkan tabel perbandingan dan serangkaian simulasi di atas, dapat ditarik kesimpulan bahwa Simulasi Monte Carlo berhasil membuktikan berlakunya Hukum Bilangan Besar (Law of Large Numbers).

Peningkatan jumlah simulasi menghasilkan estimasi yang lebih stabil dan akurat karena seiring membesarnya ukuran sampel (dari 1.000 ke 20.000), efek anomali atau varians acak akan saling meniadakan. Hasil akhir rata-rata empiris akan terdorong (konvergen) secara pasti menuju satu titik kestabilan, yaitu nilai harapan (ekspektasi) matematis yang sebenarnya (70). Oleh karena itu, dalam konteks bisnis dan data sains, melakukan simulasi berskala puluhan atau ratusan ribu iterasi sangat krusial agar prediksi yang dihasilkan tidak lagi mengandung bias acak.