Soal 1

set.seed(123)

# Bangkitkan 10.000 angka random dari distribusi Uniform(0,1)
n <- 10000
x <- runif(n, min = 0, max = 1)

# Hitung E[X^2] secara empiris
ex2_estimate <- mean(x^2)

# Tampilkan hasil
cat("Estimasi E[X^2] dengan simulasi sebanyak 10.000 data adalah:", ex2_estimate, "\n")
## Estimasi E[X^2] dengan simulasi sebanyak 10.000 data adalah: 0.3297405
# Nilai teoritis E[X^2] dari distribusi Uniform(0,1) adalah 1/3
cat("Nilai teoritis E[X^2] = 1/3 =", 1/3, "\n")
## Nilai teoritis E[X^2] = 1/3 = 0.3333333
# Visualisasi
hist(x^2, main = "Histogram dari X^2", xlab = "X^2", col = "skyblue", border = "white")
abline(v = ex2_estimate, col = "red", lwd = 2)
abline(v = 1/3, col = "darkgreen", lwd = 2, lty = 2)
legend("topright", legend = c("Estimasi", "Teori (1/3)"), col = c("red", "darkgreen"), lty = c(1,2), lwd = 2)

Soal 2

set.seed(123)

# Fungsi bantu untuk simulasi dan plotting
simulasi_normal <- function(n, mean, sd) {
  data <- rnorm(n, mean = mean, sd = sd)
  rata_rata <- mean(data)
  simpangan_baku <- sd(data)
  
  cat("Ukuran sampel:", n, "\n")
  cat("Rata-rata:", rata_rata, "\n")
  cat("Simpangan baku:", simpangan_baku, "\n\n")
  
  hist(data, main = paste("Histogram N =", n), 
       xlab = "Nilai", col = "lightblue", border = "white")
  abline(v = rata_rata, col = "red", lwd = 2)
}

# Simulasi untuk tiga ukuran sampel
simulasi_normal(100, 100, 15)
## Ukuran sampel: 100 
## Rata-rata: 101.3561 
## Simpangan baku: 13.69224

simulasi_normal(1000, 100, 15)
## Ukuran sampel: 1000 
## Rata-rata: 100.2862 
## Simpangan baku: 15.06891

simulasi_normal(10000, 100, 15)
## Ukuran sampel: 10000 
## Rata-rata: 99.96336 
## Simpangan baku: 14.98314

Soal 3

set.seed(123)

# Simulasi 5000 kali
n_sim <- 5000
binom_sample <- rbinom(n_sim, size = 30, prob = 0.25)

# Hitung proporsi P(X ≥ 15)
prop_ge_15 <- mean(binom_sample >= 15)

cat("Estimasi P(X ≥ 15) berdasarkan simulasi:", prop_ge_15, "\n")
## Estimasi P(X ≥ 15) berdasarkan simulasi: 0.0024
# Histogram
hist(binom_sample, main = "Histogram Binomial (30, 0.25)", 
     xlab = "X", col = "lightgreen", border = "white")
abline(v = 15, col = "red", lwd = 2, lty = 2)

Soal 4

# Fungsi custom untuk standar deviasi
custom_sd <- function(x) {
  n <- length(x)
  sqrt((sum(x^2) - (sum(x)^2 / n)) / (n - 1))
}

# Bangkitkan data Normal
set.seed(123)
data_norm <- rnorm(1000, mean = 89, sd = 10)

# Hitung s menggunakan custom function
s_custom <- custom_sd(data_norm)

# Bandingkan dengan fungsi sd() bawaan R
s_builtin <- sd(data_norm)

cat("Standar deviasi (fungsi custom):", s_custom, "\n")
## Standar deviasi (fungsi custom): 9.91695
cat("Standar deviasi (fungsi sd()):", s_builtin, "\n")
## Standar deviasi (fungsi sd()): 9.91695

Soal 5

set.seed(123)

# Parameter
jumlah_hari <- 20
jam_kerja <- 6
menit_kerja <- jam_kerja * 60  # 360 menit
teller <- 2
lambda_per_jam <- 5
lambda_per_menit <- lambda_per_jam / 60  # λ = 5/jam -> ~0.0833/menit
rate_pelayanan <- 1 / 8  # 8 menit rata-rata pelayanan

# Simulasi antrian selama 20 hari
hasil_hari <- list()

5a

for (hari in 1:jumlah_hari) {
  waktu_nasabah <- cumsum(rexp(rpois(1, lambda_per_menit * menit_kerja), rate = lambda_per_menit))
  waktu_nasabah <- waktu_nasabah[waktu_nasabah <= menit_kerja]  # hanya yg dalam jam kerja
  n_nasabah <- length(waktu_nasabah)
  
  mulai_pelayanan <- rep(NA, n_nasabah)
  selesai_pelayanan <- rep(NA, n_nasabah)
  
  waktu_teller <- rep(0, teller)  # waktu siap masing-masing teller
  
  for (i in 1:n_nasabah) {
    teller_tersedia <- which.min(waktu_teller)
    mulai <- max(waktu_nasabah[i], waktu_teller[teller_tersedia])
    durasi <- rexp(1, rate = rate_pelayanan)
    
    mulai_pelayanan[i] <- mulai
    selesai_pelayanan[i] <- mulai + durasi
    waktu_teller[teller_tersedia] <- selesai_pelayanan[i]
  }
  
  hasil_hari[[hari]] <- data.frame(
    hari = hari,
    kedatangan = waktu_nasabah,
    mulai = mulai_pelayanan,
    selesai = selesai_pelayanan,
    waktu_tunggu = mulai_pelayanan - waktu_nasabah,
    waktu_layanan = selesai_pelayanan - mulai_pelayanan
  )
}

5b

# Gabungkan seluruh hari
data_semua_hari <- do.call(rbind, hasil_hari)

rata_rata_tunggu <- mean(data_semua_hari$waktu_tunggu)
cat("Rata-rata waktu tunggu nasabah:", rata_rata_tunggu, "menit\n")
## Rata-rata waktu tunggu nasabah: 0.7004319 menit

5c

total_waktu_layanan <- sum(data_semua_hari$waktu_layanan)
total_waktu_teller <- teller * jumlah_hari * menit_kerja

persen_sibuk <- total_waktu_layanan / total_waktu_teller * 100
cat("Persentase waktu teller sibuk:", persen_sibuk, "%\n")
## Persentase waktu teller sibuk: 30.27572 %

5d

# Simulasi ulang dengan 3 teller
teller_baru <- 3
hasil_teller3 <- list()

for (hari in 1:jumlah_hari) {
  waktu_nasabah <- cumsum(rexp(rpois(1, lambda_per_menit * menit_kerja), rate = lambda_per_menit))
  waktu_nasabah <- waktu_nasabah[waktu_nasabah <= menit_kerja]
  n_nasabah <- length(waktu_nasabah)
  
  mulai_pelayanan <- rep(NA, n_nasabah)
  selesai_pelayanan <- rep(NA, n_nasabah)
  
  waktu_teller <- rep(0, teller_baru)
  
  for (i in 1:n_nasabah) {
    teller_tersedia <- which.min(waktu_teller)
    mulai <- max(waktu_nasabah[i], waktu_teller[teller_tersedia])
    durasi <- rexp(1, rate = rate_pelayanan)
    
    mulai_pelayanan[i] <- mulai
    selesai_pelayanan[i] <- mulai + durasi
    waktu_teller[teller_tersedia] <- selesai_pelayanan[i]
  }
  
  hasil_teller3[[hari]] <- data.frame(
    hari = hari,
    kedatangan = waktu_nasabah,
    mulai = mulai_pelayanan,
    selesai = selesai_pelayanan,
    waktu_tunggu = mulai_pelayanan - waktu_nasabah,
    waktu_layanan = selesai_pelayanan - mulai_pelayanan
  )
}

# Hitung rata-rata waktu tunggu versi 3 teller
data_3_teller <- do.call(rbind, hasil_teller3)
rata_rata_tunggu_3 <- mean(data_3_teller$waktu_tunggu)
cat("Rata-rata waktu tunggu (3 teller):", rata_rata_tunggu_3, "menit\n")
## Rata-rata waktu tunggu (3 teller): 0.1275046 menit

5e

library(ggplot2)

# Tambah kolom panjang antrian
data_semua_hari$antrian <- data_semua_hari$mulai - data_semua_hari$kedatangan > 0

# Hitung panjang antrian per waktu (dengan agregasi kasar)
ggplot(data_semua_hari, aes(x = kedatangan, fill = antrian)) +
  geom_histogram(binwidth = 10, position = "stack") +
  facet_wrap(~hari, scales = "free_y") +
  labs(title = "Histogram Panjang Antrian Setiap 10 Menit per Hari",
       x = "Menit ke-", y = "Jumlah Nasabah") +
  scale_fill_manual(values = c("gray", "red"), labels = c("Langsung Dilayani", "Harus Menunggu")) +
  theme_minimal()

Soal 6, 6a & 6b

set.seed(123)

# Parameter dasar
stok_awal <- 100
jumlah_hari <- 60
frekuensi_pesan <- 5
jumlah_pesan <- 50
kerugian_per_karung <- 50000

# Penjualan harian dari Uniform integer [8, 15]
penjualan_harian <- sample(8:15, jumlah_hari, replace = TRUE)

# Vektor stok harian
stok <- numeric(jumlah_hari)
stok[1] <- stok_awal
kehabisan <- rep(FALSE, jumlah_hari)
total_kerugian <- 0

for (hari in 2:jumlah_hari) {
  # Cek jika harus restock
  if ((hari - 1) %% frekuensi_pesan == 0) {
    stok[hari] <- stok[hari - 1] + jumlah_pesan
  } else {
    stok[hari] <- stok[hari - 1]
  }
  
  # Kurangi penjualan
  stok[hari] <- stok[hari] - penjualan_harian[hari]
  
  # Jika stok < 0, kerugian terjadi
  if (stok[hari] < 0) {
    total_kerugian <- total_kerugian + abs(stok[hari]) * kerugian_per_karung
    stok[hari] <- 0
    kehabisan[hari] <- TRUE
  }
}

# Hasil poin (a) & (b)
plot(stok, type = "l", col = "blue", lwd = 2, xlab = "Hari", ylab = "Stok", main = "Simulasi Stok Selama 60 Hari")
abline(h = 0, col = "red", lty = 2)

cat("Total hari kehabisan stok:", sum(kehabisan), "hari\n")
## Total hari kehabisan stok: 1 hari
cat("Total kerugian: Rp", total_kerugian, "\n")
## Total kerugian: Rp 2e+05

6c

# Fungsi simulasi berdasarkan jumlah pesan
simulasi_stok <- function(jumlah_pesan) {
  stok <- numeric(jumlah_hari)
  stok[1] <- stok_awal
  total_kerugian <- 0
  kehabisan <- 0
  penjualan <- sample(8:15, jumlah_hari, replace = TRUE)
  
  for (hari in 2:jumlah_hari) {
    if ((hari - 1) %% frekuensi_pesan == 0) {
      stok[hari] <- stok[hari - 1] + jumlah_pesan
    } else {
      stok[hari] <- stok[hari - 1]
    }
    
    stok[hari] <- stok[hari] - penjualan[hari]
    
    if (stok[hari] < 0) {
      total_kerugian <- total_kerugian + abs(stok[hari]) * kerugian_per_karung
      stok[hari] <- 0
      kehabisan <- kehabisan + 1
    }
  }
  return(c(jumlah_pesan, kehabisan, total_kerugian))
}

# Uji jumlah pesan: 40, 50, 60
strategi_pesan <- sapply(c(40, 50, 60), simulasi_stok)
colnames(strategi_pesan) <- c("40 karung", "50 karung", "60 karung")
rownames(strategi_pesan) <- c("Jumlah Pesan", "Hari Kehabisan", "Total Kerugian")

strategi_pesan
##                40 karung 50 karung 60 karung
## Jumlah Pesan          40        50        60
## Hari Kehabisan        16         7         0
## Total Kerugian   7750000   3350000         0

6d

simulasi_frekuensi <- function(frekuensi_pesan) {
  stok <- numeric(jumlah_hari)
  stok[1] <- stok_awal
  total_kerugian <- 0
  kehabisan <- 0
  penjualan <- sample(8:15, jumlah_hari, replace = TRUE)
  
  for (hari in 2:jumlah_hari) {
    if ((hari - 1) %% frekuensi_pesan == 0) {
      stok[hari] <- stok[hari - 1] + jumlah_pesan
    } else {
      stok[hari] <- stok[hari - 1]
    }
    
    stok[hari] <- stok[hari] - penjualan[hari]
    
    if (stok[hari] < 0) {
      total_kerugian <- total_kerugian + abs(stok[hari]) * kerugian_per_karung
      stok[hari] <- 0
      kehabisan <- kehabisan + 1
    }
  }
  return(c(frekuensi_pesan, kehabisan, total_kerugian))
}

# Frekuensi 3, 5, 7 hari
strategi_frekuensi <- sapply(c(3, 5, 7), simulasi_frekuensi)
colnames(strategi_frekuensi) <- c("3 hari", "5 hari", "7 hari")
rownames(strategi_frekuensi) <- c("Frekuensi", "Hari Kehabisan", "Total Kerugian")

strategi_frekuensi
##                3 hari 5 hari  7 hari
## Frekuensi           3      5       7
## Hari Kehabisan      0      1      16
## Total Kerugian      0 250000 8250000

6e

# Gunakan skenario terbaik dari hasil (c) atau (d)
plot(stok, type = "o", col = "darkgreen", xlab = "Hari", ylab = "Stok", main = "Pergerakan Stok Harian")
abline(h = 0, col = "red", lty = 2)

cat("Rekomendasi: Bu Sari sebaiknya pesan 60 karung setiap 3 hari untuk meminimalkan kehilangan.\n")
## Rekomendasi: Bu Sari sebaiknya pesan 60 karung setiap 3 hari untuk meminimalkan kehilangan.