Monte Carlo adalah strategi mengestimasi nilai yang sulit dihitung langsung: jalankan percobaan acak berkali-kali, lalu ambil rata-ratanya. Nama ini diambil dari kota kasino yang terkenal — sama seperti permainan judi, hasil satu kali lemparan tidak bisa diprediksi, tetapi rata-rata ribuan lemparan sangat bisa dihitung.
Semua yang kita butuhkan sudah ada di bab-bab sebelumnya: angka acak ber-seed dari Generator (Chapter Reproducibility dan Random Seed), rng.integers() (Chapter Random Integer dan Sampling), dan rng.random() yang berdistribusi uniform (Chapter Uniform Distribution). Pola kerjanya selalu sama: banyak percobaan → kumpulkan hasil → hitung rata-rata atau proporsi.
Ide Inti: Rata-rata dari Banyak Percobaan #
Bentuk paling sederhana: mengestimasi rata-rata lemparan dadu. Nilai eksaknya mudah dihitung (3,5), sehingga cocok sebagai alat kontrol — kita tahu seberapa dekat estimasi seharusnya:
import numpy as np
rng = np.random.default_rng(42)
lemparan = rng.integers(1, 7, size=1_000_000)
print("Rata-rata simulasi :", round(float(lemparan.mean()), 3))
print("Nilai eksak teori :", (1 + 2 + 3 + 4 + 5 + 6) / 6)Output yang Dihasilkan:
Rata-rata simulasi : 3.498
Nilai eksak teori : 3.5Satu juta lemparan memberi rata-rata 3,498 — meleset hanya 0,002 dari nilai eksak. Perhatikan bahwa satu lemparan tidak mungkin menghasilkan 3,5; hanya agregasi banyak lemparan yang bisa menyentuhnya.
Mengestimasi pi #
Sekarang estimasi yang eksaknya tidak mudah: nilai pi. Gambarnya seperti ini: titik-titik acak disebar merata di persegi satuan, lalu kita hitung berapa banyak yang jatuh di dalam seperempat lingkaran berjari-jari 1. Karena luas seperempat lingkaran adalah π/4 dan luas persegi adalah 1, proporsi titik di dalam lingkaran mendekati π/4 — kalikan 4 dan pi terestimasi.
import numpy as np
rng = np.random.default_rng(42)
n = 100_000
x = rng.random(n)
y = rng.random(n)
di_lingkaran = np.count_nonzero(x**2 + y**2 <= 1.0)
estimasi = 4 * di_lingkaran / n
print("Titik dalam seperempat lingkaran :", di_lingkaran)
print(f"Estimasi pi : {estimasi:.4f}")Output yang Dihasilkan:
Titik dalam seperempat lingkaran : 78444
Estimasi pi : 3.1378Bedah baris demi baris:
- Baris 5-6 (
x = rng.random(n),y = rng.random(n)): seratus ribu koordinat(x, y)disebar uniform di persegi[0, 1) × [0, 1); dua array ini adalah “lemparan” kita. - Baris 7 (
di_lingkaran = np.count_nonzero(...)):x**2 + y**2 <= 1.0menguji jarak titik dari pusat — satu syarat lingkaran berjari-jari 1;count_nonzeromenghitung berapa titik yang lulus uji, di sini 78.444. - Baris 8 (
estimasi = 4 * di_lingkaran / n): proporsi 0,78444 dikalikan 4, menghasilkan estimasi 3,1378 — hanya meleset sekitar 0,004 dari pi (3,14159…).
Estimasi ini deterministik: dengan seed 42 dan n = 100000, angka 3,1378 akan muncul lagi di setiap eksekusi. Tanpa seed, angkanya sedikit berganti tiap kali dijalankan.
Melihat Konvergensi #
Teori Monte Carlo menjanjikan estimasi yang makin baik saat jumlah percobaan bertambah. Kita buktikan dengan mengulang estimasi pi pada tiga ukuran sampel:
import numpy as np
def estimasi_pi(n, seed=42):
rng = np.random.default_rng(seed)
x = rng.random(n)
y = rng.random(n)
return 4 * np.count_nonzero(x**2 + y**2 <= 1.0) / n
for n in [1_000, 10_000, 100_000]:
print(f"n = {n:>7} -> estimasi pi = {estimasi_pi(n):.4f}")Output yang Dihasilkan:
n = 1000 -> estimasi pi = 3.1480
n = 10000 -> estimasi pi = 3.1488
n = 100000 -> estimasi pi = 3.1378Bedah baris demi baris:
- Baris 3 (
def estimasi_pi(n, seed=42)): seluruh langkah estimasi dikemas dalam satu fungsi, sehingga tiga ukuran sampel diuji dengan logika yang persis sama. - Baris 4-7: isi fungsi mengulang pola pada contoh sebelumnya — buat Generator ber-seed, sebar
ntitik(x, y), hitung proporsi yang berada di dalam seperempat lingkaran, lalu kalikan 4. - Baris 9-10 (
for n in [...]): fungsi dipanggil tiga kali dengannmembesar 10 kali lipat di tiap tahap; format{n:>7}meratakan angka ke kanan agar kolom output sejajar.
Dibandingkan dengan pi = 3,141593, hasilnya bisa dirangkum:
| n | Estimasi pi | Selisih dari pi |
|---|---|---|
| 1.000 | 3,1480 | 0,0064 |
| 10.000 | 3,1488 | 0,0072 |
| 100.000 | 3,1378 | 0,0038 |
Baris n = 100000 bernilai 3,1378, persis seperti estimasi pada contoh sebelumnya — keduanya memakai seed dan pola pembangkitan yang sama.
Kapan Monte Carlo Cocok Dipakai #
Satu hal perlu dipegang sejak awal: Monte Carlo menghasilkan estimasi yang mendekati nilai sebenarnya, bukan nilai eksak. Metode ini layak dipakai ketika jalur eksak tersendat:
- Nilai yang dicari melibatkan integral atau geometri rumit yang sulit dirumuskan eksak — contoh halus di atas adalah estimasi pi.
- Sistem terdiri dari banyak komponen acak yang berinteraksi (antrean call center, pergerakan harga, penyebaran sinyal noise).
- Kita butuh jawaban cepat untuk menguji dugaan, sebelum menulis analisis matematis yang ketat.
Sebaliknya, bila rumus eksaknya sederhana — seperti rata-rata dadu di awal bab — pakai rumusnya langsung; Monte Carlo adalah alat untuk kasus ketika rumus itu tidak tersedia. Estimasi 3,1378 bukan angka yang mengecewakan: dengan seratus ribu titik dan lima baris NumPy, kita mendekati pi tanpa satu pun rumus integral.