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.