Praktikum Simulasi Monte Carlo

Simulasi Monte Carlo merupakan metode numerik yang digunakan untuk memodelkan dan menganalisis sistem yang mengandung unsur ketidakpastian dengan memanfaatkan bilangan acak. Metode ini bekerja dengan cara melakukan simulasi berulang berdasarkan distribusi probabilitas tertentu untuk memperoleh gambaran kemungkinan hasil yang dapat terjadi. Dalam konteks analisis permintaan, simulasi Monte Carlo dapat digunakan untuk memprediksi nilai permintaan di masa mendatang berdasarkan pola data historis yang dibangkitkan mengikuti distribusi tertentu.

# Data awal
tabel_permintaan <- data.frame(
  permintaan = c(50,60,70,80,90),
  frekuensi = c(10,20,40,20,10)
)
print(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

print(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)
print(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

print(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
# ekspektasi Berdasarkan distribusi peluang
nilai_ekspektasi <- sum(tabel_permintaan$permintaan * tabel_permintaan$probabilitas)
cat("Ekspektasi permintaan:", nilai_ekspektasi, "\n")
## Ekspektasi permintaan: 70

Prediksi

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 follback 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)
}
set.seed(5)
# a. 5 hari
sim_5 <- permintaan_simulasi(5, tabel_permintaan)
print(head(sim_5, 10))
##   bilangan_acak prediksi_permintaan
## 1            66                  70
## 2            57                  70
## 3            79                  80
## 4            75                  80
## 5            41                  70
cat("Rata-rata permintaan:", mean(sim_5$prediksi_permintaan), "\n")
## Rata-rata permintaan: 74
set.seed(20)
# b. 20 hari
sim_20 <- permintaan_simulasi(20, tabel_permintaan)
print(head(sim_20, 10))
##    bilangan_acak prediksi_permintaan
## 1             38                  70
## 2             63                  70
## 3              2                  50
## 4             98                  90
## 5             29                  60
## 6             94                  90
## 7             62                  70
## 8             45                  70
## 9             41                  70
## 10            67                  70
cat("Rata-rata permintaan:", mean(sim_20$prediksi_permintaan), "\n")
## Rata-rata permintaan: 71
set.seed(100)
# c. 100 hari
sim_100 <- permintaan_simulasi(100, tabel_permintaan)
print(head(sim_100, 10))
##    bilangan_acak prediksi_permintaan
## 1             74                  80
## 2             89                  80
## 3             78                  80
## 4             23                  60
## 5             86                  80
## 6             70                  70
## 7              4                  50
## 8             55                  70
## 9             70                  70
## 10            98                  90
cat("Rata-rata permintaan:", mean(sim_100$prediksi_permintaan), "\n")
## Rata-rata permintaan: 69.19192
set.seed(1000)
# d. 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
perbandingan <- data.frame(
  Metode = c("Ekspektasi Teoritis", "Simulasi 5 hari", "simulasi 20 hari", "Simulasi 100 hari", "Simulasi 1000 hari"),
  permintaan_Rata_Rata = c(
    round(nilai_ekspektasi, 2), round(mean(sim_5$prediksi_permintaan), 2), round(mean(sim_20$prediksi_permintaan), 2), round(mean(sim_100$prediksi_permintaan), 2), round(mean(sim_1000$prediksi_permintaan), 2)
  )
)
print(perbandingan)
##                Metode permintaan_Rata_Rata
## 1 Ekspektasi Teoritis                70.00
## 2     Simulasi 5 hari                74.00
## 3    simulasi 20 hari                71.00
## 4   Simulasi 100 hari                69.19
## 5  Simulasi 1000 hari                70.12

Tugas

Tugas 1

Lakukan modifikasi pada salah satu kode program yang telah diberikan dengan mengubah jumlah simulasi menjadi 1.000, 5.000, dan 20.000. Jalankan simulasi untuk masing-masing kondisi tersebut, kemudian bandingkan nilai ekspektasi yang dihasilkan dengan nilai ekspektasi hasil perhitungan manual. Selanjutnya, analisis bagaimana perubahan jumlah simulasi memengaruhi kedekatan hasil simulasi terhadap nilai teoritis, serta jelaskan mengapa peningkatan jumlah simulasi dapat menghasilkan estimasi yang lebih stabil dan akurat.

# Data awal
Tabel_permintaan <- data.frame(
  permintaan = c(50,60,70,80,90),
  frekuensi = c(10,20,40,20,10)
)
print(Tabel_permintaan)
##   permintaan frekuensi
## 1         50        10
## 2         60        20
## 3         70        40
## 4         80        20
## 5         90        10
# Total frekuensi
totalfrekuensi <- sum(Tabel_permintaan$frekuensi)

# Peluang
totalfrekuensi <- sum(Tabel_permintaan$frekuensi)
Tabel_permintaan$probabilitas <- Tabel_permintaan$frekuensi / totalfrekuensi

print(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)
print(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

print(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
# 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

Prediksi

permintaan_simulasi <- function(n, tabel_permintaan) {
  # Bilangan acak dari 1 (sampai 100 (diskrit sesuai interval)
  bilangan_acak <- sample(1:100, n, replace = TRUE)
  
  #Funsgi 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 follback 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)
}
set.seed(20)
# a. 20 hari
sim_20 <- permintaan_simulasi(20, Tabel_permintaan)
print(head(sim_20, 10))
##    bilangan_acak prediksi_permintaan
## 1             38                  70
## 2             63                  70
## 3              2                  50
## 4             98                  90
## 5             29                  60
## 6             94                  90
## 7             62                  70
## 8             45                  70
## 9             41                  70
## 10            67                  70
cat("Rata-rata permintaan:", mean(sim_20$prediksi_permintaan), "\n")
## Rata-rata permintaan: 71
set.seed(100)
# b. 100 hari
sim_100 <- permintaan_simulasi(100, Tabel_permintaan)
print(head(sim_100, 10))
##    bilangan_acak prediksi_permintaan
## 1             74                  80
## 2             89                  80
## 3             78                  80
## 4             23                  60
## 5             86                  80
## 6             70                  70
## 7              4                  50
## 8             55                  70
## 9             70                  70
## 10            98                  90
cat("Rata-rata permintaan:", mean(sim_100$prediksi_permintaan), "\n")
## Rata-rata permintaan: 69.19192
set.seed(1000)
# c. 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
set.seed(5000)
# d. 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
set.seed(20000)
# e. 20000 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
perbandingan <- data.frame(
  Metode = c("Ekspektasi Teoritis", "Simulasi 20 hari", "Simulasi 100 hari", "Simulasi 1000 hari", "Simulasi 5000 hari", "Simulasi 20000 hari"),
  permintaan_Rata_Rata = c(
    round(Nilai_ekspektasi, 2),
    round(mean(sim_20$prediksi_permintaan), 2),
    round(mean(sim_100$prediksi_permintaan), 2),
    round(mean(sim_1000$prediksi_permintaan), 2), 
    round(mean(sim_5000$prediksi_permintaan), 2), 
    round(mean(sim_20000$prediksi_permintaan), 2)
  )
)
print(perbandingan)
##                Metode permintaan_Rata_Rata
## 1 Ekspektasi Teoritis                70.00
## 2    Simulasi 20 hari                71.00
## 3   Simulasi 100 hari                69.19
## 4  Simulasi 1000 hari                70.12
## 5  Simulasi 5000 hari                70.09
## 6 Simulasi 20000 hari                69.89

Kesimpulan: Berdasarkan hasil simulasi Monte Carlo dengan jumlah iterasi yang semakin besar yaitu 1.000, 5.000, dan 20.000, terlihat bahwa nilai rata-rata permintaan yang dihasilkan semakin mendekati nilai ekspektasi teoritis (sekitar 70) dan menjadi lebih stabil. Prebedaannya terlihat saat simulasi dengan jumlah lebih kecil berangsur mengecil ketika jumlah simulasi ditingkatkan, sehingga hasil pada 5.000 dan 20.000 iterasi hampir sama dengan nilai teoritis. Hal ini menunjukkan bahwa semakin banyak jumlah simulasi yang dilakukan, maka pengaruh variabilitas acak akan berkurang dan estimasi menjadi lebih akurat serta konsisten.

Tugas 2

Bangkitkanlah data dengan distribusi eksponensial untuk variabel permintaan sebanyak 10 permintaan, dan data dengan distribusi normal untuk variabel frekuensi a. prediksikan permintaan selam 5 hari ke depan b. prediksikan permintaan selam 20 hari ke depan c. prediksikan permintaan selam 100 hari ke depan d. prediksikan permintaan selam 1000 hari ke depan

rm(list = ls())
set.seed(111)

# Bangkitkan 10 data permintaan
permintaan <- round(
  rexp(10, rate = 1/70)
)
permintaan
##  [1]  13  32  82   2  84  96 317   5  53  13
# Bangkitkan 10 data frekuensi
frekuensi <- round(
  rnorm(10, mean = 10, sd = 3 )
)

frekuensi[frekuensi < 1] <- 1
frekuensi
##  [1]  6  7  7  9  9  9 16 11 12  5
# Menggabungkan data
data_simulasi <- data.frame(
  permintaan = permintaan,
  frekuensi = frekuensi
)
data_simulasi
##    permintaan frekuensi
## 1          13         6
## 2          32         7
## 3          82         7
## 4           2         9
## 5          84         9
## 6          96         9
## 7         317        16
## 8           5        11
## 9          53        12
## 10         13         5
# Menghitung probabilitas
data_simulasi$probabilitas <-
  data_simulasi$frekuensi / sum(data_simulasi$frekuensi)

data_simulasi
##    permintaan frekuensi probabilitas
## 1          13         6   0.06593407
## 2          32         7   0.07692308
## 3          82         7   0.07692308
## 4           2         9   0.09890110
## 5          84         9   0.09890110
## 6          96         9   0.09890110
## 7         317        16   0.17582418
## 8           5        11   0.12087912
## 9          53        12   0.13186813
## 10         13         5   0.05494505
# Probabilitas kumulatif
data_simulasi$prob_kumulatif <-
  cumsum(data_simulasi$probabilitas)

data_simulasi
##    permintaan frekuensi probabilitas prob_kumulatif
## 1          13         6   0.06593407     0.06593407
## 2          32         7   0.07692308     0.14285714
## 3          82         7   0.07692308     0.21978022
## 4           2         9   0.09890110     0.31868132
## 5          84         9   0.09890110     0.41758242
## 6          96         9   0.09890110     0.51648352
## 7         317        16   0.17582418     0.69230769
## 8           5        11   0.12087912     0.81318681
## 9          53        12   0.13186813     0.94505495
## 10         13         5   0.05494505     1.00000000
# Interval angka acak 1-100
bawah <- c(1, floor(data_simulasi$prob_kumulatif[-length(data_simulasi$prob_kumulatif)] * 100) + 1)
atas  <- floor(data_simulasi$prob_kumulatif * 100)

data_simulasi$batas_bawah <- bawah
data_simulasi$batas_atas  <- atas

data_simulasi
##    permintaan frekuensi probabilitas prob_kumulatif batas_bawah batas_atas
## 1          13         6   0.06593407     0.06593407           1          6
## 2          32         7   0.07692308     0.14285714           7         14
## 3          82         7   0.07692308     0.21978022          15         21
## 4           2         9   0.09890110     0.31868132          22         31
## 5          84         9   0.09890110     0.41758242          32         41
## 6          96         9   0.09890110     0.51648352          42         51
## 7         317        16   0.17582418     0.69230769          52         69
## 8           5        11   0.12087912     0.81318681          70         81
## 9          53        12   0.13186813     0.94505495          82         94
## 10         13         5   0.05494505     1.00000000          95        100
simulasi_mc <- function(n, data_simulasi){

  bilangan_acak <- sample(1:100, n, replace = TRUE)
  hasil <- numeric(n)

  for(i in 1:n){
    
    idx <- which(
      bilangan_acak[i] >= data_simulasi$batas_bawah &
      bilangan_acak[i] <= data_simulasi$batas_atas
    )
    
    hasil[i] <- data_simulasi$permintaan[idx]
  }

  output <- data.frame(
    hari = 1:n,
    bilangan_acak = bilangan_acak,
    permintaan = hasil
  )

  total <- sum(hasil)
  rata2 <- mean(hasil)

  return(list(
    detail = output,
    total_permintaan = total,
    rata_rata = rata2
  ))
}
# a. Prediksi 5 hari
set.seed(5)
sim_5 <- simulasi_mc(5, data_simulasi)
sim_5
## $detail
##   hari bilangan_acak permintaan
## 1    1            66        317
## 2    2            57        317
## 3    3            79          5
## 4    4            75          5
## 5    5            41         84
## 
## $total_permintaan
## [1] 728
## 
## $rata_rata
## [1] 145.6
# b. Prediksi 20 hari
set.seed(20)
sim_20 <- simulasi_mc(20, data_simulasi)
sim_20
## $detail
##    hari bilangan_acak permintaan
## 1     1            38         84
## 2     2            63        317
## 3     3             2         13
## 4     4            98         13
## 5     5            29          2
## 6     6            94         53
## 7     7            62        317
## 8     8            45         96
## 9     9            41         84
## 10   10            67        317
## 11   11            61        317
## 12   12            14         32
## 13   13            72          5
## 14   14            63        317
## 15   15            52        317
## 16   16            73          5
## 17   17            85         53
## 18   18            81          5
## 19   19            57        317
## 20   20             6         13
## 
## $total_permintaan
## [1] 2677
## 
## $rata_rata
## [1] 133.85
# c. Prediksi 100 hari
set.seed(100)
sim_100 <- simulasi_mc(100, data_simulasi)
sim_100
## $detail
##     hari bilangan_acak permintaan
## 1      1            74          5
## 2      2            89         53
## 3      3            78          5
## 4      4            23          2
## 5      5            86         53
## 6      6            70          5
## 7      7             4         13
## 8      8            55        317
## 9      9            70          5
## 10    10            98         13
## 11    11             7         32
## 12    12             7         32
## 13    13            55        317
## 14    14            43         96
## 15    15            82         53
## 16    16            61        317
## 17    17            12         32
## 18    18            99         13
## 19    19            51         96
## 20    20            72          5
## 21    21            18         82
## 22    22            25          2
## 23    23             2         13
## 24    24            51         96
## 25    25            68        317
## 26    26            68        317
## 27    27            52        317
## 28    28            48         96
## 29    29            32         84
## 30    30            85         53
## 31    31            91         53
## 32    32            39         84
## 33    33            16         82
## 34    34            75          5
## 35    35            66        317
## 36    36            70          5
## 37    37            93         53
## 38    38            45         96
## 39    39            30          2
## 40    40            30          2
## 41    41            93         53
## 42    42            87         53
## 43    43            95         13
## 44    44            97         13
## 45    45            95         13
## 46    46            29          2
## 47    47            92         53
## 48    48            31          2
## 49    49            54        317
## 50    50            41         84
## 51    51            41         84
## 52    52            24          2
## 53    53            43         96
## 54    54             7         32
## 55    55            63        317
## 56    56            65        317
## 57    57             9         32
## 58    58            20         82
## 59    59            14         32
## 60    60            78          5
## 61    61            88         53
## 62    62             3         13
## 63    63            36         84
## 64    64            27          2
## 65    65            46         96
## 66    66            59        317
## 67    67            46         96
## 68    68            69        317
## 69    69            47         96
## 70    70            55        317
## 71    71            47         96
## 72    72            68        317
## 73    73            12         32
## 74    74            51         96
## 75    75            16         82
## 76    76            56        317
## 77    77            22          2
## 78    78            82         53
## 79    79            53        317
## 80    80             3         13
## 81    81             5         13
## 82    82            44         96
## 83    83            85         53
## 84    84            28          2
## 85    85            52        317
## 86    86            25          2
## 87    87            42         96
## 88    88            15         82
## 89    89            57        317
## 90    90            42         96
## 91    91            76          5
## 92    92            37         84
## 93    93            26          2
## 94    94            24          2
## 95    95            12         32
## 96    96             9         32
## 97    97            55        317
## 98    98            75          5
## 99    99            63        317
## 100  100            35         84
## 
## $total_permintaan
## [1] 9812
## 
## $rata_rata
## [1] 98.12
# d. Prediksi 1000 hari
set.seed(1000)
sim_1000 <- simulasi_mc(1000, data_simulasi)
sim_1000$rata_rata
## [1] 88.969
# Ekspektasi teoritis
ekspektasi <- mean(data_simulasi$permintaan)

hasil_akhir <- data.frame(
  Metode = c("Ekspektasi Teoritis",
             "Simulasi 5 hari",
             "Simulasi 20 hari",
             "Simulasi 100 hari",
             "Simulasi 1000 hari"),
  
  Permintaan_Rata_Rata = c(
    round(ekspektasi, 5),
    round(sim_5$rata_rata, 5),
    round(sim_20$rata_rata, 5),
    round(sim_100$rata_rata, 5),
    round(sim_1000$rata_rata, 5)
  )
)

hasil_akhir
##                Metode Permintaan_Rata_Rata
## 1 Ekspektasi Teoritis               69.700
## 2     Simulasi 5 hari              145.600
## 3    Simulasi 20 hari              133.850
## 4   Simulasi 100 hari               98.120
## 5  Simulasi 1000 hari               88.969

Berdasarkan hasil simulasi Monte Carlo, prediksi permintaan pada periode pendek yaitu 5 dan 20 hari masih menunjukkan nilai yang fluktuatif dan jauh dari ekspektasi teoritis, sedangkan pada periode yang lebih panjang seperti pada 100 dan 1000 hari, hasilnya semakin stabil dan mendekati nilai ekspektasi. Hal ini menunjukkan bahwa semakin banyak jumlah simulasi yang dilakukan, maka estimasi permintaan menjadi lebih akurat, sehingga metode Monte Carlo lebih efektif digunakan untuk prediksi jangka panjang.