Soal 1: Simulasi E[X^2] untuk X ~ U(0, 1)

set.seed(1)
n <- 10000
x <- runif(n, 0, 1)
E_X2 <- mean(x^2)
E_X2
## [1] 0.3348666

Soal 2: Histogram dan statistik deskriptif untuk data normal

set.seed(2)
n1 <- 100
n2 <- 1000
n3 <- 10000

sim_norm <- function(n) {
  data <- rnorm(n, mean = 100, sd = sqrt(15^2))
  hist(data, main = paste("Histogram n =", n), xlab = "Nilai", col = "yellow")
  mean_val <- mean(data)
  sd_val <- sd(data)
  return(c(mean = mean_val, sd = sd_val))
}

sim_norm(n1)

##     mean       sd 
## 99.53953 17.40284
sim_norm(n2)

##      mean        sd 
## 101.05351  14.89456
sim_norm(n3)

##      mean        sd 
## 100.07452  15.02745

Soal 3: Simulasi distribusi Binomial

set.seed(3)
binom_data <- rbinom(5000, size = 30, prob = 0.25)
P_X_15plus <- mean(binom_data >= 15)
P_X_15plus
## [1] 0.0016

Soal 4: Buat function s dan gunakan untuk data normal

set.seed(4)
rumus_s <- function(x) {
  n <- length(x)
  s <- sqrt((sum(x^2) - (sum(x)^2)/n) / (n - 1))
  return(s)
}

data_normal <- rnorm(1000, mean = 89, sd = 10)
rumus_s(data_normal)
## [1] 9.693035

Soal 5: Simulasi Antrian Bank

(a) Simulasi antrian selama 20 hari kerja

knitr::opts_chunk$set(echo = TRUE)
set.seed(5)
lambda <- 5/60   
mu <- 1/8         
jam_kerja <- 360
n_hari <- 20


sim_bank <- function(n_teller) {
  total_tunggu <- 0
  total_nasabah <- 0
  total_sibuk <- 0
  antrian_harian <- matrix(0, n_hari, 6)
  
  for(hari in 1:n_hari) {
    
    n <- rpois(1, lambda * jam_kerja)
    kedatangan <- sort(runif(n, 0, jam_kerja))
    pelayanan <- rexp(n, mu)
    
   
    teller_selesai <- rep(0, n_teller)
    tunggu <- numeric(n)
    
    for(i in 1:n) {
      teller_idx <- which.min(teller_selesai)
      mulai <- max(kedatangan[i], teller_selesai[teller_idx])
      tunggu[i] <- mulai - kedatangan[i]
      teller_selesai[teller_idx] <- mulai + pelayanan[i]
    }
    
    
    total_tunggu <- total_tunggu + sum(tunggu)
    total_nasabah <- total_nasabah + n
    total_sibuk <- total_sibuk + sum(pmin(teller_selesai, jam_kerja))
 
    
    for(jam in 1:6) {
      start_t <- (jam-1) * 60
      end_t <- jam * 60
      dalam_jam <- kedatangan >= start_t & kedatangan < end_t
      if(sum(dalam_jam) > 0) {
        antrian_harian[hari, jam] <- mean(tunggu[dalam_jam] > 0)
      }
    }
  }
  
  list(
    rata_tunggu = total_tunggu / total_nasabah,
    utilisasi = total_sibuk / (n_teller * jam_kerja * n_hari),
    antrian_jam = colMeans(antrian_harian)
  )
}
hasil_2 <- sim_bank(2)
cat("Simulasi 20 hari dengan 2 teller selesai\n")
## Simulasi 20 hari dengan 2 teller selesai
cat("Total nasabah dilayani rata-rata:", round(rpois(1, lambda * jam_kerja)), "orang/hari\n")
## Total nasabah dilayani rata-rata: 40 orang/hari

(b) Hitung rata-rata lama nasabah menunggu

set.seed(5)
cat("Rata-rata waktu tunggu:", round(hasil_2$rata_tunggu, 2), "menit\n")
## Rata-rata waktu tunggu: 1.45 menit

(c) Hitung persen waktu teller sibuk bekerja

set.seed(178)
cat("Utilisasi teller:", round(hasil_2$utilisasi * 100, 1), "%\n")
## Utilisasi teller: 97.2 %

(d) Bandingkan dengan menambah 1 teller (total 3 teller)

set.seed(7)
hasil_3 <- sim_bank(3)

perbandingan <- data.frame(
  Metrik = c("Waktu tunggu (menit)", "Utilisasi (%)", "Efisiensi"),
  Teller_2 = c(round(hasil_2$rata_tunggu, 2), 
               round(hasil_2$utilisasi * 100, 1),
               round(hasil_2$rata_tunggu / hasil_2$utilisasi, 2)),
  Teller_3 = c(round(hasil_3$rata_tunggu, 2),
               round(hasil_3$utilisasi * 100, 1), 
               round(hasil_3$rata_tunggu / hasil_3$utilisasi, 2))
)

print(perbandingan)
##                 Metrik Teller_2 Teller_3
## 1 Waktu tunggu (menit)     1.45     0.11
## 2        Utilisasi (%)    97.20    95.60
## 3            Efisiensi     1.49     0.11
penurunan <- (hasil_2$rata_tunggu - hasil_3$rata_tunggu) / hasil_2$rata_tunggu * 100
cat("\nPenurunan waktu tunggu:", round(penurunan, 1), "%\n")
## 
## Penurunan waktu tunggu: 92.5 %
cat("Kesimpulan:", ifelse(penurunan > 25, "EFISIEN - tambah teller", "KURANG EFISIEN"))
## Kesimpulan: EFISIEN - tambah teller

(e) Grafik panjang antrian sepanjang hari

library(simmer)
library(simmer.plot)
## Loading required package: ggplot2
## 
## Attaching package: 'simmer.plot'
## The following objects are masked from 'package:simmer':
## 
##     get_mon_arrivals, get_mon_attributes, get_mon_resources
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:simmer':
## 
##     select
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)

# Buat simulasi bank2 dulu
teller_sim <- function(n_teller = 2, days = 20, hours_per_day = 6) {
  bank <- simmer("Bank")
  
  customer <- trajectory("Nasabah") %>%
    seize("teller", 1) %>%
    timeout(function() rexp(1, 1/8)) %>%
    release("teller", 1)

  bank %>%
    add_resource("teller", n_teller) %>%
    add_generator("nasabah", customer, function() rexp(1, 1/5))

  bank %>% run(days * hours_per_day * 60)
  return(bank)
}

# Jalankan simulasi dan simpan hasilnya ke bank2
bank2 <- teller_sim(n_teller = 2)
set.seed(8)
queue_plot <- get_mon_resources(bank2) %>%
  filter(resource == "teller") %>%
  ggplot(aes(x = time, y = queue)) +
  geom_line(color = "steelblue") +
  labs(title = "Panjang Antrian Sepanjang Hari (20 Hari)", x = "Waktu (menit)", y = "Jumlah Antrian") +
  theme_minimal()

queue_plot

Soal 6: Simulasi Toko Kelontong

(a) Simulasikan stok beras selama 60 hari (pesan 50 karung tiap 5 hari)

set.seed(11)

simulasi_stok <- function(hari = 60, stok_awal = 100, pesan_setiap = 5, jumlah_pesan = 50) {
  penjualan <- round(runif(hari, 8, 15))  # 8–15 karung/hari
  stok <- numeric(hari)
  stok[1] <- stok_awal - penjualan[1]
  habis <- 0
  rugi <- 0
  
  for (i in 2:hari) {
    if (i %% pesan_setiap == 0) {
      stok[i] <- stok[i-1] + jumlah_pesan - penjualan[i]
    } else {
      stok[i] <- stok[i-1] - penjualan[i]
    }
    
    if (stok[i] < 0) {
      rugi <- rugi + abs(stok[i]) * 50000  # rugi Rp50.000/karung
      habis <- habis + 1
      stok[i] <- 0
    }
  }
  
  return(list(stok = stok, habis = habis, rugi = rugi))
}

hasil_a <- simulasi_stok()
hasil_a <- simulasi_stok()

# Tampilkan output 
cat("Total kerugian        : Rp", format(hasil_a$rugi, big.mark = ","), "\n")
## Total kerugian        : Rp 6e+05
cat("Sisa stok akhir       :", tail(hasil_a$stok, 1), "karung\n")
## Sisa stok akhir       : 40 karung

(b) Hitung berapa kali toko kehabisan stok

cat("Hari stok habis       :", hasil_a$habis, "hari\n")
## Hari stok habis       : 2 hari

(c) Coba strategi: pesan 40, 50, dan 60 karung → Mana yang terbaik?

set.seed(12)
pesan_40 <- simulasi_stok(jumlah_pesan = 40)
pesan_50 <- simulasi_stok(jumlah_pesan = 50)
pesan_60 <- simulasi_stok(jumlah_pesan = 60)

data.frame(
  Jumlah_Pesan = c(40, 50, 60),
  Hari_Stok_Habis = c(pesan_40$habis, pesan_50$habis, pesan_60$habis),
  Total_Rugi = c(pesan_40$rugi, pesan_50$rugi, pesan_60$rugi)
)
##   Jumlah_Pesan Hari_Stok_Habis Total_Rugi
## 1           40              14    6550000
## 2           50               4    1350000
## 3           60               0          0

(d) Ubah frekuensi pesan: setiap 3, 5, dan 7 hari → Mana yang optimal?

set.seed(13)
freq_3 <- simulasi_stok(pesan_setiap = 3)
freq_5 <- simulasi_stok(pesan_setiap = 5)
freq_7 <- simulasi_stok(pesan_setiap = 7)

data.frame(
  Frekuensi_Pesan = c(3, 5, 7),
  Hari_Stok_Habis = c(freq_3$habis, freq_5$habis, freq_7$habis),
  Total_Rugi = c(freq_3$rugi, freq_5$rugi, freq_7$rugi)
)
##   Frekuensi_Pesan Hari_Stok_Habis Total_Rugi
## 1               3               0          0
## 2               5               4    1400000
## 3               7              20    9650000

(e) Grafik pergerakan stok & rekomendasi strategi

# Grafik
plot(1:60, hasil_a$stok, type = "o", col = "pink", xlab = "Hari", ylab = "Sisa Stok",
     main = "Pergerakan Stok Beras Bu Sari (Pesan 50 tiap 5 hari)")
abline(h = 0, col = "purple", lty = 2)

# Rekomendasi verbal
cat("\n REKOMENDASI UNTUK BU SARI \n")
## 
##  REKOMENDASI UNTUK BU SARI
cat("Berdasarkan hasil simulasi berbagai strategi:\n")
## Berdasarkan hasil simulasi berbagai strategi:
cat("- Strategi pemesanan 60 karung tiap 5 hari menghasilkan kerugian paling kecil.\n")
## - Strategi pemesanan 60 karung tiap 5 hari menghasilkan kerugian paling kecil.
cat("- Bu Sari disarankan menggunakan strategi tersebut untuk meminimalkan kehilangan untung.\n")
## - Bu Sari disarankan menggunakan strategi tersebut untuk meminimalkan kehilangan untung.